Skip to content

Commit 09b6665

Browse files
hongzhi-gaoycycse
authored andcommitted
fix(cpp): aligned VECTOR row-offset skip only when time/value counts match (apache#778)
Whole-chunk and whole-page skips by statistic count previously used only the value side for aligned series, which could desynchronize row_offset from decoded rows when ChunkMeta or page header counts differed. Require both time and value statistics to be present, positive, and equal before applying count-based skip; otherwise decode and rely on page/row handling. Made-with: Cursor
1 parent b63af49 commit 09b6665

3 files changed

Lines changed: 46 additions & 7 deletions

File tree

cpp/src/reader/aligned_chunk_reader.cc

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -740,15 +740,21 @@ bool AlignedChunkReader::should_skip_page_by_offset(int& row_offset) {
740740
if (row_offset <= 0) {
741741
return false;
742742
}
743-
// Use time page statistic for count.
744-
Statistic* stat = cur_time_page_header_.statistic_;
745-
if (stat == nullptr) {
746-
stat = cur_value_page_header_.statistic_;
743+
// Aligned TV pages: only skip a whole page by count when both page headers
744+
// expose the same positive row count. Using a single side (or min) when
745+
// the other is missing or unequal can desynchronize row_offset from
746+
// decoded row order vs. the paired time/value stream.
747+
Statistic* ts = cur_time_page_header_.statistic_;
748+
Statistic* vs = cur_value_page_header_.statistic_;
749+
if (ts == nullptr || vs == nullptr) {
750+
return false;
747751
}
748-
if (stat == nullptr || stat->count_ == 0) {
752+
int32_t tc = ts->count_;
753+
int32_t vc = vs->count_;
754+
if (tc <= 0 || vc <= 0 || tc != vc) {
749755
return false;
750756
}
751-
int32_t count = stat->count_;
757+
int32_t count = tc;
752758
if (row_offset >= count) {
753759
row_offset -= count;
754760
return true;

cpp/src/reader/tsfile_series_scan_iterator.cc

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,30 @@ bool TsFileSeriesScanIterator::should_skip_chunk_by_offset(ChunkMeta* cm) {
6060
return false;
6161
}
6262

63+
bool TsFileSeriesScanIterator::should_skip_aligned_chunk_by_offset(
64+
ChunkMeta* time_cm, ChunkMeta* value_cm) {
65+
if (row_offset_ <= 0) {
66+
return false;
67+
}
68+
if (time_cm->statistic_ == nullptr || value_cm->statistic_ == nullptr) {
69+
return false;
70+
}
71+
int32_t tc = time_cm->statistic_->count_;
72+
int32_t vc = value_cm->statistic_->count_;
73+
if (tc <= 0 || vc <= 0) {
74+
return false;
75+
}
76+
if (tc != vc) {
77+
return false;
78+
}
79+
int32_t count = tc;
80+
if (row_offset_ >= count) {
81+
row_offset_ -= count;
82+
return true;
83+
}
84+
return false;
85+
}
86+
6387
int TsFileSeriesScanIterator::get_next(TsBlock*& ret_tsblock, bool alloc,
6488
Filter* oneshoot_filter,
6589
int64_t min_time_hint) {
@@ -106,7 +130,8 @@ int TsFileSeriesScanIterator::get_next(TsBlock*& ret_tsblock, bool alloc,
106130
min_time_hint)) {
107131
continue;
108132
}
109-
if (should_skip_chunk_by_offset(value_cm)) {
133+
if (should_skip_aligned_chunk_by_offset(time_cm,
134+
value_cm)) {
110135
continue;
111136
}
112137
chunk_reader_->reset();

cpp/src/reader/tsfile_series_scan_iterator.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,14 @@ class TsFileSeriesScanIterator {
119119
}
120120
bool should_skip_chunk_by_time(ChunkMeta* cm, int64_t min_time_hint);
121121
bool should_skip_chunk_by_offset(ChunkMeta* cm);
122+
/**
123+
* Aligned (VECTOR): whole-chunk skip by row count is only safe when the
124+
* time ChunkMeta and value ChunkMeta agree on statistic count (>0). If
125+
* either side lacks count or counts differ, skip is disabled for this
126+
* chunk; pages are loaded and page/row-level offset handling applies.
127+
*/
128+
bool should_skip_aligned_chunk_by_offset(ChunkMeta* time_cm,
129+
ChunkMeta* value_cm);
122130
common::TsBlock* alloc_tsblock();
123131

124132
private:

0 commit comments

Comments
 (0)