This is an automated email from the ASF dual-hosted git repository.

colinlee pushed a commit to branch colin_fix_timestamp_check
in repository https://gitbox.apache.org/repos/asf/tsfile.git

commit c34969a65ca39fc774971258fa51e0b7f19c0498
Author: ColinLee <[email protected]>
AuthorDate: Mon May 12 00:17:04 2025 +0800

    add timestamp check.
---
 cpp/src/common/statistic.h                         |  5 +++
 cpp/src/writer/time_page_writer.h                  |  4 ++
 cpp/src/writer/tsfile_writer.cc                    |  4 +-
 .../writer/table_view/tsfile_writer_table_test.cc  | 47 ++++++++++++++++++++++
 4 files changed, 59 insertions(+), 1 deletion(-)

diff --git a/cpp/src/common/statistic.h b/cpp/src/common/statistic.h
index 8eb866e2..7590a6e0 100644
--- a/cpp/src/common/statistic.h
+++ b/cpp/src/common/statistic.h
@@ -164,6 +164,11 @@ class Statistic {
         ASSERT(false);
         return 0;
     }
+
+    int get_count() const { return count_; }
+
+    int64_t get_end_time() const { return end_time_; }
+
     virtual int deserialize_from(common::ByteStream &in) {
         int ret = common::E_OK;
         if (RET_FAIL(common::SerializationUtil::read_var_uint(
diff --git a/cpp/src/writer/time_page_writer.h 
b/cpp/src/writer/time_page_writer.h
index bc5b8212..bbf70165 100644
--- a/cpp/src/writer/time_page_writer.h
+++ b/cpp/src/writer/time_page_writer.h
@@ -73,6 +73,10 @@ class TimePageWriter {
 
     FORCE_INLINE int write(int64_t timestamp) {
         int ret = common::E_OK;
+        if (statistic_->count_ != 0 && is_inited_ &&
+            timestamp <= statistic_->end_time_) {
+            return common::E_OUT_OF_ORDER;
+        }
         if (RET_FAIL(time_encoder_->encode(timestamp, time_out_stream_))) {
         } else {
             statistic_->update(timestamp);
diff --git a/cpp/src/writer/tsfile_writer.cc b/cpp/src/writer/tsfile_writer.cc
index a570fc54..5b031189 100644
--- a/cpp/src/writer/tsfile_writer.cc
+++ b/cpp/src/writer/tsfile_writer.cc
@@ -730,7 +730,9 @@ int TsFileWriter::write_table(Tablet &tablet) {
                 return ret;
             }
             for (int i = start_idx; i < end_idx; i++) {
-                time_chunk_writer->write(tablet.timestamps_[i]);
+                if (RET_FAIL(time_chunk_writer->write(tablet.timestamps_[i]))) 
{
+                    return ret;
+                }
             }
             uint32_t field_col_count = 0;
             for (uint32_t i = 0; i < tablet.get_column_count(); ++i) {
diff --git a/cpp/test/writer/table_view/tsfile_writer_table_test.cc 
b/cpp/test/writer/table_view/tsfile_writer_table_test.cc
index ac2f4040..121e63a2 100644
--- a/cpp/test/writer/table_view/tsfile_writer_table_test.cc
+++ b/cpp/test/writer/table_view/tsfile_writer_table_test.cc
@@ -139,6 +139,53 @@ TEST_F(TsFileWriterTableTest, WriteTableTest) {
     delete table_schema;
 }
 
+TEST_F(TsFileWriterTableTest, WriteDisorderTest) {
+    auto table_schema = gen_table_schema(0);
+    auto tsfile_table_writer_ =
+        std::make_shared<TsFileTableWriter>(&write_file_, table_schema);
+
+    int device_num = 1;
+    int num_timestamp_per_device = 10;
+    int offset = 0;
+    storage::Tablet tablet(table_schema->get_measurement_names(),
+                       table_schema->get_data_types(),
+                       device_num * num_timestamp_per_device);
+
+    char* literal = new char[std::strlen("device_id") + 1];
+    std::strcpy(literal, "device_id");
+    String literal_str(literal, std::strlen("device_id"));
+    for (int i = 0; i < device_num; i++) {
+        for (int l = 0; l < num_timestamp_per_device; l++) {
+            int row_index = i * num_timestamp_per_device + l;
+            // disordered timestamp.
+            tablet.add_timestamp(row_index, l > num_timestamp_per_device / 2 ? 
l - num_timestamp_per_device : offset + l);
+            auto column_schemas = table_schema->get_measurement_schemas();
+            for (const auto& column_schema : column_schemas) {
+                switch (column_schema->data_type_) {
+                    case TSDataType::INT64:
+                        tablet.add_value(row_index,
+                                         column_schema->measurement_name_,
+                                         static_cast<int64_t>(i));
+                    break;
+                    case TSDataType::STRING:
+                        tablet.add_value(row_index,
+                                         column_schema->measurement_name_,
+                                         literal_str);
+                    break;
+                    default:
+                        break;
+                }
+            }
+        }
+    }
+    delete[] literal;
+
+    ASSERT_EQ(tsfile_table_writer_->write_table(tablet), 
common::E_OUT_OF_ORDER);
+    ASSERT_EQ(tsfile_table_writer_->flush(), common::E_OK);
+    ASSERT_EQ(tsfile_table_writer_->close(), common::E_OK);
+    delete table_schema;
+}
+
 TEST_F(TsFileWriterTableTest, WriteTableTestMultiFlush) {
     auto table_schema = gen_table_schema(0);
     auto tsfile_table_writer_ = std::make_shared<TsFileTableWriter>(

Reply via email to