Skip to main content

mito2/sst/index/
column.rs

1// Copyright 2023 Greptime Team
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use api::v1::SemanticType;
16use datatypes::arrow::array::Array;
17use datatypes::arrow::record_batch::RecordBatch;
18use store_api::storage::consts::PRIMARY_KEY_COLUMN_NAME;
19
20use crate::sst::parquet::format::PrimaryKeyArray;
21
22/// Yields (first row, row count) for indexing a materialized column.
23/// Tags are constant within consecutive equal PK dictionary keys. Fields and
24/// timestamps must still be visited row by row. Distinct dictionary entries may
25/// contain equal PK bytes; keeping those runs separate is correct and avoids decoding.
26/// Inputs without a non-null PK dictionary fall back to visiting individual rows.
27pub(crate) fn column_index_rows(
28    batch: &RecordBatch,
29    semantic_type: SemanticType,
30) -> impl Iterator<Item = (usize, usize)> + '_ {
31    let keys = (semantic_type == SemanticType::Tag)
32        .then(|| batch.column_by_name(PRIMARY_KEY_COLUMN_NAME))
33        .flatten()
34        .and_then(|array| array.as_any().downcast_ref::<PrimaryKeyArray>())
35        .filter(|array| array.null_count() == 0 && array.values().null_count() == 0)
36        .map(|array| array.keys().values());
37    let mut row = 0;
38    std::iter::from_fn(move || {
39        if row == batch.num_rows() {
40            return None;
41        }
42        let start = row;
43        row += 1;
44        if let Some(keys) = keys {
45            while row < keys.len() && keys[row] == keys[start] {
46                row += 1;
47            }
48        }
49        Some((start, row - start))
50    })
51}