diff --git a/.github/workflows/unit-test-cpp.yml b/.github/workflows/unit-test-cpp.yml
index 08c138018..d4172f8b4 100644
--- a/.github/workflows/unit-test-cpp.yml
+++ b/.github/workflows/unit-test-cpp.yml
@@ -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
diff --git a/.github/workflows/unit-test-python.yml b/.github/workflows/unit-test-python.yml
index c99935976..72be32363 100644
--- a/.github/workflows/unit-test-python.yml
+++ b/.github/workflows/unit-test-python.yml
@@ -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
diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt
index 60f5dc861..3128c9968 100755
--- a/cpp/CMakeLists.txt
+++ b/cpp/CMakeLists.txt
@@ -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 ()
diff --git a/cpp/README.md b/cpp/README.md
index 9e13cdd11..dced6c8c1 100644
--- a/cpp/README.md
+++ b/cpp/README.md
@@ -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
@@ -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`.
@@ -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`.
\ No newline at end of file
diff --git a/cpp/pom.xml b/cpp/pom.xml
index d2bd2ab6e..f2644a96e 100644
--- a/cpp/pom.xml
+++ b/cpp/pom.xml
@@ -171,30 +171,6 @@
Linux
-
-
-
- org.codehaus.mojo
- exec-maven-plugin
-
-
- install-uuid-dev
- validate
-
- exec
-
-
-
-
- bash
-
- -c
- sudo apt-get update && sudo apt-get install -y uuid-dev
-
-
-
-
-
diff --git a/cpp/test/cwrapper/c_release_test.cc b/cpp/test/cwrapper/c_release_test.cc
index 692f10435..85583d526 100644
--- a/cpp/test/cwrapper/c_release_test.cc
+++ b/cpp/test/cwrapper/c_release_test.cc
@@ -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(malloc(sizeof(ColumnSchema) * 2));
+ static_cast(malloc(sizeof(ColumnSchema) * 2));
table_schema.column_schemas[0] =
(ColumnSchema){.column_name = strdup("col1"),
.data_type = TS_DATATYPE_STRING,
@@ -121,7 +121,7 @@ TEST_F(CReleaseTest, TsFileWriterWriteDataAbnormalColumn) {
abnormal_schema.table_name = strdup("!@#$%^*()_+-=");
abnormal_schema.column_num = 3;
abnormal_schema.column_schemas =
- static_cast(malloc(sizeof(ColumnSchema) * 4));
+ static_cast(malloc(sizeof(ColumnSchema) * 4));
abnormal_schema.column_schemas[0] =
(ColumnSchema){.column_name = strdup("!@#$%^*()_+-="),
.data_type = TS_DATATYPE_STRING,
@@ -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(malloc(sizeof(char *) * 3));
+ char** column_list = static_cast(malloc(sizeof(char*) * 3));
column_list[0] = strdup("!@#$%^*()_+-=");
column_list[1] = strdup("TAG2");
column_list[2] = strdup("!@#$%^*()_+-=1");
- TSDataType *type_list =
- static_cast(malloc(sizeof(TSDataType) * 3));
+ TSDataType* type_list =
+ static_cast(malloc(sizeof(TSDataType) * 3));
type_list[0] = TS_DATATYPE_STRING;
type_list[1] = TS_DATATYPE_STRING;
type_list[2] = TS_DATATYPE_DOUBLE;
@@ -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);
@@ -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(malloc(sizeof(ColumnSchema) * 6));
+ static_cast(malloc(sizeof(ColumnSchema) * 6));
all_type_schema.column_schemas[0] =
(ColumnSchema){.column_name = strdup("TAG"),
.data_type = TS_DATATYPE_STRING,
@@ -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(malloc(sizeof(char *) * 6));
+ char** column_list = static_cast(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(malloc(sizeof(TSDataType) * 6));
+ TSDataType* type_list =
+ static_cast(malloc(sizeof(TSDataType) * 6));
type_list[0] = TS_DATATYPE_STRING;
type_list[1] = TS_DATATYPE_INT32;
type_list[2] = TS_DATATYPE_INT64;
@@ -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);
@@ -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(malloc(sizeof(char*) * 2));
+ column_list[0] = strdup("id");
+ column_list[1] = strdup("value");
+
+ TSDataType* type_list =
+ static_cast(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(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
\ No newline at end of file