Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/workflows/unit-test-cpp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,14 @@ jobs:
core.setOutput('platform_suffix', ``)
}

- name: Install clang-format
# Install dependencies
- name: Install dependencies
shell: bash
run: |
if [[ "$RUNNER_OS" == "Linux" ]]; then
sudo update-alternatives --install /usr/bin/clang-format clang-format /usr/bin/clang-format-17 100
sudo update-alternatives --set clang-format /usr/bin/clang-format-17
sudo apt-get install -y uuid-dev
elif [[ "$RUNNER_OS" == "Windows" ]]; then
choco install llvm --version 17.0.6 --force
else
Expand Down
16 changes: 16 additions & 0 deletions .github/workflows/unit-test-python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,22 @@ jobs:
core.setOutput('platform_suffix', ``)
}

# Install dependencies
- name: Install dependencies
shell: bash
run: |
if [[ "$RUNNER_OS" == "Linux" ]]; then
sudo update-alternatives --install /usr/bin/clang-format clang-format /usr/bin/clang-format-17 100
sudo update-alternatives --set clang-format /usr/bin/clang-format-17
sudo apt-get install -y uuid-dev
elif [[ "$RUNNER_OS" == "Windows" ]]; then
choco install llvm --version 17.0.6 --force
else
brew install llvm@17
ln -sf $(brew --prefix llvm@17)/bin/clang-format /opt/homebrew/bin/clang-format
fi


# Run the actual maven build including all tests.
- name: Build and test with Maven
shell: bash
Expand Down
8 changes: 8 additions & 0 deletions cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,17 @@ under the License.
cmake_minimum_required(VERSION 3.11)
project(TsFile_CPP)

if (DEFINED ToolChain)
include(${CMAKE_SOURCE_DIR}/cmake/ToolChain.cmake)
message(STATUS "Using ToolChain: ${CMAKE_TOOLCHAIN_FILE}")
else()
message(STATUS "Not using ToolChain")
endif ()

cmake_policy(SET CMP0079 NEW)
set(TsFile_CPP_VERSION 2.2.0.dev)
set(CMAKE_CXX_FLAGS "$ENV{CXXFLAGS} -Wall")

if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wunused -Wuninitialized -D__STDC_FORMAT_MACROS")
endif ()
Expand Down
34 changes: 16 additions & 18 deletions cpp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,23 +42,6 @@ The source code can be found in the `./src` directory. C/C++ examples are locate

We use `clang-format` to ensure that our C++ code adheres to a consistent set of rules defined in `./clang-format`. This is similar to the Google style.

**Feature List**:

- [ ] Add unit tests for the reader, writer, compression, etc.
- [ ] Add unit tests for the C wrapper.
- [ ] Support multiple data flushes.
- [ ] Support aligned timeseries.
- [ ] Support table description in tsfile.
- [ ] Retrieve all table schemas/names.
- [ ] Implement automatic flush.
- [ ] Support out-of-order data writing.
- [ ] Support TsFile V4. Note: TsFile CPP does not implement support for the table model, therefore there are differences in file output compared to the Java version.

**Bug List**:

- [ ] Flushing without writing after registering a timeseries will cause a core dump.
- [ ] Misalignment in memory may lead to a bus error.

We welcome any bug reports. You can open an issue with a title starting with [CPP] to describe the bug, like: https://github.com/apache/tsfile/issues/94

## Build
Expand All @@ -67,7 +50,7 @@ We welcome any bug reports. You can open an issue with a title starting with [CP

```bash
sudo apt-get update
sudo apt-get install -y cmake make g++ clang-format
sudo apt-get install -y cmake make g++ clang-format libuuid-dev
```

To build tsfile, you can run: `bash build.sh`. If you have Maven tools, you can run: `mvn package -P with-cpp clean verify`. Then, you can find the shared object at `./build`.
Expand All @@ -81,6 +64,21 @@ If you compile using MinGW on windows and encounter an error, you can try replac
* GCC 12.2.0 + LLVM/Clang/LLD/LLDB 16.0.0 + MinGW-w64 10.0.0 (MSVCRT) - release 5
* GCC 11.2.0 + MinGW-w64 10.0.0 (MSVCRT) - release 1

### configure the cross-compilation toolchain

Modify the Toolchain File `cmake/ToolChain.cmake`, define the following variables:

- `CMAKE_C_COMPILER`: Specify the path to the C compiler.
- `CMAKE_CXX_COMPILER`: Specify the path to the C++ compiler.
- `CMAKE_FIND_ROOT_PATH`: Set the root path for the cross-compilation environment (e.g., the directory of the cross-compilation toolchain).

In the `cpp/` directory, run the following commands to create the build directory and start the compilation:
```
mkdir build && cd build
cmake .. -DToolChian=ON
make
```

## Use TsFile

You can find examples on how to read and write data in `demo_read.cpp` and `demo_write.cpp` located under `./examples/cpp_examples`. There are also examples under `./examples/c_examples`on how to use a C-style API to read and write data in a C environment. You can run `bash build.sh` under `./examples` to generate an executable output under `./examples/build`.
24 changes: 0 additions & 24 deletions cpp/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -171,30 +171,6 @@
<name>Linux</name>
</os>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<id>install-uuid-dev</id>
<phase>validate</phase>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>bash</executable>
<arguments>
<argument>-c</argument>
<argument>sudo apt-get update &amp;&amp; sudo apt-get install -y uuid-dev</argument>
</arguments>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<!-- When running on jenkins, download the sonar build-wrapper, so we can do a code analysis -->
<profile>
Expand Down
87 changes: 76 additions & 11 deletions cpp/test/cwrapper/c_release_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ TEST_F(CReleaseTest, TsFileWriterNew) {
table_schema.table_name = strdup("test_table");
table_schema.column_num = 2;
table_schema.column_schemas =
static_cast<ColumnSchema *>(malloc(sizeof(ColumnSchema) * 2));
static_cast<ColumnSchema*>(malloc(sizeof(ColumnSchema) * 2));
table_schema.column_schemas[0] =
(ColumnSchema){.column_name = strdup("col1"),
.data_type = TS_DATATYPE_STRING,
Expand Down Expand Up @@ -121,7 +121,7 @@ TEST_F(CReleaseTest, TsFileWriterWriteDataAbnormalColumn) {
abnormal_schema.table_name = strdup("!@#$%^*()_+-=");
abnormal_schema.column_num = 3;
abnormal_schema.column_schemas =
static_cast<ColumnSchema *>(malloc(sizeof(ColumnSchema) * 4));
static_cast<ColumnSchema*>(malloc(sizeof(ColumnSchema) * 4));
abnormal_schema.column_schemas[0] =
(ColumnSchema){.column_name = strdup("!@#$%^*()_+-="),
.data_type = TS_DATATYPE_STRING,
Expand Down Expand Up @@ -163,12 +163,12 @@ TEST_F(CReleaseTest, TsFileWriterWriteDataAbnormalColumn) {
writer = tsfile_writer_new(file, &abnormal_schema, &error_code);
ASSERT_EQ(RET_OK, error_code);

char **column_list = static_cast<char **>(malloc(sizeof(char *) * 3));
char** column_list = static_cast<char**>(malloc(sizeof(char*) * 3));
column_list[0] = strdup("!@#$%^*()_+-=");
column_list[1] = strdup("TAG2");
column_list[2] = strdup("!@#$%^*()_+-=1");
TSDataType *type_list =
static_cast<TSDataType *>(malloc(sizeof(TSDataType) * 3));
TSDataType* type_list =
static_cast<TSDataType*>(malloc(sizeof(TSDataType) * 3));
type_list[0] = TS_DATATYPE_STRING;
type_list[1] = TS_DATATYPE_STRING;
type_list[2] = TS_DATATYPE_DOUBLE;
Expand Down Expand Up @@ -196,7 +196,7 @@ TEST_F(CReleaseTest, TsFileWriterWriteDataAbnormalColumn) {
tsfile_result_set_get_value_by_name_int64_t(result_set, "time");
ASSERT_EQ(timestamp * 100.0, tsfile_result_set_get_value_by_name_double(
result_set, "!@#$%^*()_+-=1"));
char *value_str =
char* value_str =
tsfile_result_set_get_value_by_index_string(result_set, 2);
ASSERT_EQ("device1", std::string(value_str));
free(value_str);
Expand Down Expand Up @@ -226,7 +226,7 @@ TEST_F(CReleaseTest, TsFileWriterMultiDataType) {
all_type_schema.table_name = strdup("All_Datatype");
all_type_schema.column_num = 6;
all_type_schema.column_schemas =
static_cast<ColumnSchema *>(malloc(sizeof(ColumnSchema) * 6));
static_cast<ColumnSchema*>(malloc(sizeof(ColumnSchema) * 6));
all_type_schema.column_schemas[0] =
(ColumnSchema){.column_name = strdup("TAG"),
.data_type = TS_DATATYPE_STRING,
Expand Down Expand Up @@ -257,15 +257,15 @@ TEST_F(CReleaseTest, TsFileWriterMultiDataType) {
ASSERT_EQ(RET_OK, error_code);

free_table_schema(all_type_schema);
char **column_list = static_cast<char **>(malloc(sizeof(char *) * 6));
char** column_list = static_cast<char**>(malloc(sizeof(char*) * 6));
column_list[0] = strdup("TAG");
column_list[1] = strdup("INT32");
column_list[2] = strdup("INT64");
column_list[3] = strdup("FLOAT");
column_list[4] = strdup("DOUBLE");
column_list[5] = strdup("BOOLEAN");
TSDataType *type_list =
static_cast<TSDataType *>(malloc(sizeof(TSDataType) * 6));
TSDataType* type_list =
static_cast<TSDataType*>(malloc(sizeof(TSDataType) * 6));
type_list[0] = TS_DATATYPE_STRING;
type_list[1] = TS_DATATYPE_INT32;
type_list[2] = TS_DATATYPE_INT64;
Expand Down Expand Up @@ -302,7 +302,7 @@ TEST_F(CReleaseTest, TsFileWriterMultiDataType) {
Timestamp timestamp =
tsfile_result_set_get_value_by_name_int64_t(result_set, "time");
int64_t value = timestamp + 10;
char *str_value =
char* str_value =
tsfile_result_set_get_value_by_name_string(result_set, "TAG");
ASSERT_EQ("device1", std::string(str_value));
free(str_value);
Expand Down Expand Up @@ -336,4 +336,69 @@ TEST_F(CReleaseTest, TsFileWriterMultiDataType) {
remove("TsFileWriterMultiDataType.tsfile");
}

TEST_F(CReleaseTest, TsFileWriterConfTest) {
ERRNO err_no = RET_OK;
WriteFile file = write_file_new("plain_file.tsfile", &err_no);
TableSchema plain_schema;
plain_schema.table_name = strdup("plain_table");
plain_schema.column_num = 2;

plain_schema.column_schemas =
(ColumnSchema*)malloc(sizeof(ColumnSchema) * 2);
plain_schema.column_schemas[0].column_name = strdup("id");
plain_schema.column_schemas[0].data_type = TS_DATATYPE_STRING;
plain_schema.column_schemas[0].column_category = ColumnCategory::TAG;
plain_schema.column_schemas[1].column_name = strdup("value");
plain_schema.column_schemas[1].data_type = TS_DATATYPE_INT64;
plain_schema.column_schemas[1].column_category = ColumnCategory::FIELD;

set_global_compression(TS_COMPRESSION_UNCOMPRESSED);
set_datatype_encoding(TS_DATATYPE_INT64, TS_ENCODING_PLAIN);
TsFileWriter writer = tsfile_writer_new(file, &plain_schema, &err_no);
free_table_schema(plain_schema);

char** column_list = static_cast<char**>(malloc(sizeof(char*) * 2));
column_list[0] = strdup("id");
column_list[1] = strdup("value");

TSDataType* type_list =
static_cast<TSDataType*>(malloc(sizeof(TSDataType) * 2));
type_list[0] = TS_DATATYPE_STRING;
type_list[1] = TS_DATATYPE_INT64;

Tablet tablet = tablet_new(column_list, type_list, 2, 10);
for (int i = 0; i < 10; i++) {
tablet_add_timestamp(tablet, i, static_cast<int64_t>(i));
tablet_add_value_by_name_string(tablet, i, "id", "device1");
tablet_add_value_by_name_int32_t(tablet, i, "value", i);
}

ASSERT_EQ(RET_OK, tsfile_writer_write(writer, tablet));
ASSERT_EQ(RET_OK, tsfile_writer_close(writer));
free_write_file(&file);
TsFileReader reader = tsfile_reader_new("plain_file.tsfile", &err_no);
ASSERT_EQ(RET_OK, err_no);
TableSchema schema = tsfile_reader_get_table_schema(reader, "plain_table");
ASSERT_EQ(schema.column_num, 2);
uint32_t size = 0;
DeviceSchema* device_schema =
tsfile_reader_get_all_timeseries_schemas(reader, &size);
ASSERT_EQ(1, size);
ASSERT_EQ(1, device_schema->timeseries_num);
ASSERT_EQ(device_schema->timeseries_schema[0].encoding, TS_ENCODING_PLAIN);
ASSERT_EQ(device_schema->timeseries_schema[0].compression,
TS_COMPRESSION_UNCOMPRESSED);
tsfile_reader_close(reader);
free_table_schema(schema);
free_device_schema(*device_schema);
free(device_schema);
free(column_list[0]);
free(column_list[1]);
free(column_list);
free(type_list);
free_tablet(&tablet);

remove("plain_file.tsfile");
}

} // namespace CReleaseTest
Loading