be/src/storage/key/row_key_encoder.cpp
Line | Count | Source |
1 | | // Licensed to the Apache Software Foundation (ASF) under one |
2 | | // or more contributor license agreements. See the NOTICE file |
3 | | // distributed with this work for additional information |
4 | | // regarding copyright ownership. The ASF licenses this file |
5 | | // to you under the Apache License, Version 2.0 (the |
6 | | // "License"); you may not use this file except in compliance |
7 | | // with the License. You may obtain a copy of the License at |
8 | | // |
9 | | // http://www.apache.org/licenses/LICENSE-2.0 |
10 | | // |
11 | | // Unless required by applicable law or agreed to in writing, |
12 | | // software distributed under the License is distributed on an |
13 | | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
14 | | // KIND, either express or implied. See the License for the |
15 | | // specific language governing permissions and limitations |
16 | | // under the License. |
17 | | |
18 | | #include "storage/key/row_key_encoder.h" |
19 | | |
20 | | #include <cassert> |
21 | | |
22 | | #include "common/cast_set.h" |
23 | | #include "common/compiler_util.h" // IWYU pragma: keep |
24 | | #include "common/consts.h" |
25 | | #include "common/logging.h" |
26 | | #include "storage/iterator/olap_data_convertor.h" |
27 | | #include "storage/key_coder.h" |
28 | | #include "storage/tablet/tablet_schema.h" |
29 | | |
30 | | namespace doris { |
31 | | |
32 | | RowKeyEncoder::RowKeyEncoder(const TabletSchema& schema, bool mow) |
33 | 5.23k | : _num_short_key_columns(schema.num_short_key_columns()) { |
34 | 5.23k | if (mow) { |
35 | 196 | _init_mow(schema); |
36 | 5.03k | } else { |
37 | 5.03k | _init_non_mow(schema); |
38 | 5.03k | } |
39 | 5.23k | } |
40 | | |
41 | 196 | void RowKeyEncoder::_init_mow(const TabletSchema& schema) { |
42 | | // encode the sequence id into the primary key index |
43 | 196 | if (schema.has_sequence_col()) { |
44 | 84 | const auto& column = schema.column(schema.sequence_col_idx()); |
45 | 84 | _seq_coder = get_key_coder(column.type()); |
46 | 84 | _seq_col_length = column.length(); |
47 | 84 | } |
48 | | |
49 | 196 | if (schema.cluster_key_uids().empty()) { |
50 | 182 | _add_default_sort_key_columns(schema); |
51 | 182 | return; |
52 | 182 | } |
53 | | |
54 | 94 | for (size_t cid = 0; cid < schema.num_key_columns(); ++cid) { |
55 | 80 | _primary_key_coders.push_back(get_key_coder(schema.column(cid).type())); |
56 | 80 | } |
57 | 14 | _rowid_coder = get_key_coder(FieldType::OLAP_FIELD_TYPE_UNSIGNED_INT); |
58 | 86 | for (auto uid : schema.cluster_key_uids()) { |
59 | 86 | _add_sort_key_column(schema.column_by_uid(uid)); |
60 | 86 | } |
61 | 14 | } |
62 | | |
63 | 5.03k | void RowKeyEncoder::_init_non_mow(const TabletSchema& schema) { |
64 | 5.03k | _add_default_sort_key_columns(schema); |
65 | 5.03k | } |
66 | | |
67 | 5.21k | void RowKeyEncoder::_add_default_sort_key_columns(const TabletSchema& schema) { |
68 | 9.91k | for (size_t cid = 0; cid < schema.num_key_columns(); ++cid) { |
69 | 4.69k | _add_sort_key_column(schema.column(cid)); |
70 | 4.69k | } |
71 | 5.21k | } |
72 | | |
73 | 4.78k | void RowKeyEncoder::_add_sort_key_column(const TabletColumn& column) { |
74 | 4.78k | _sort_key_coders.push_back(get_key_coder(column.type())); |
75 | 4.78k | _sort_key_index_size.push_back(cast_set<uint16_t>(column.index_length())); |
76 | 4.78k | } |
77 | | |
78 | | std::string RowKeyEncoder::full_encode(const std::vector<IOlapColumnDataAccessor*>& key_columns, |
79 | 14.7k | size_t pos) const { |
80 | 14.7k | assert(_sort_key_index_size.size() == _sort_key_coders.size()); |
81 | 14.7k | assert(key_columns.size() == _sort_key_coders.size()); |
82 | 14.7k | return _full_encode(_sort_key_coders, key_columns, pos); |
83 | 14.7k | } |
84 | | |
85 | | std::string RowKeyEncoder::full_encode_primary_keys( |
86 | 236 | const std::vector<IOlapColumnDataAccessor*>& key_columns, size_t pos) const { |
87 | 236 | return _full_encode(_primary_key_coders, key_columns, pos); |
88 | 236 | } |
89 | | |
90 | | namespace { |
91 | | // Shared row-key encoding base: for each key column, write a null marker for |
92 | | // a null value, otherwise a normal marker followed by whatever `encode_field` |
93 | | // appends. `encode_field(cid, field, out)` is the only thing that differs between |
94 | | // the full key encode and the short-key prefix encode. |
95 | | template <typename EncodeField> |
96 | | std::string encode_key_columns(const std::vector<IOlapColumnDataAccessor*>& key_columns, size_t pos, |
97 | 42.1k | EncodeField&& encode_field) { |
98 | 42.1k | std::string encoded_keys; |
99 | 42.1k | size_t cid = 0; |
100 | 62.7k | for (const auto& column : key_columns) { |
101 | 62.7k | const auto* field = column->get_data_at(pos); |
102 | 62.7k | if (UNLIKELY(!field)) { |
103 | 584 | encoded_keys.push_back(KeyConsts::KEY_NULL_FIRST_MARKER); |
104 | 584 | ++cid; |
105 | 584 | continue; |
106 | 584 | } |
107 | 62.2k | encoded_keys.push_back(KeyConsts::KEY_NORMAL_MARKER); |
108 | 62.2k | encode_field(cid, field, &encoded_keys); |
109 | 62.2k | ++cid; |
110 | 62.2k | } |
111 | 42.1k | return encoded_keys; |
112 | 42.1k | } row_key_encoder.cpp:_ZN5doris12_GLOBAL__N_118encode_key_columnsIZNS_13RowKeyEncoder12_full_encodeB5cxx11ERKSt6vectorIPKNS_8KeyCoderESaIS6_EERKS3_IPNS_23IOlapColumnDataAccessorESaISC_EEmE3$_0EENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESG_mOT_ Line | Count | Source | 97 | 14.9k | EncodeField&& encode_field) { | 98 | 14.9k | std::string encoded_keys; | 99 | 14.9k | size_t cid = 0; | 100 | 29.8k | for (const auto& column : key_columns) { | 101 | 29.8k | const auto* field = column->get_data_at(pos); | 102 | 29.8k | if (UNLIKELY(!field)) { | 103 | 340 | encoded_keys.push_back(KeyConsts::KEY_NULL_FIRST_MARKER); | 104 | 340 | ++cid; | 105 | 340 | continue; | 106 | 340 | } | 107 | 29.5k | encoded_keys.push_back(KeyConsts::KEY_NORMAL_MARKER); | 108 | 29.5k | encode_field(cid, field, &encoded_keys); | 109 | 29.5k | ++cid; | 110 | 29.5k | } | 111 | 14.9k | return encoded_keys; | 112 | 14.9k | } |
row_key_encoder.cpp:_ZN5doris12_GLOBAL__N_118encode_key_columnsIZNKS_13RowKeyEncoder17encode_short_keysB5cxx11ERKSt6vectorIPNS_23IOlapColumnDataAccessorESaIS5_EEmE3$_0EENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_mOT_ Line | Count | Source | 97 | 27.1k | EncodeField&& encode_field) { | 98 | 27.1k | std::string encoded_keys; | 99 | 27.1k | size_t cid = 0; | 100 | 32.9k | for (const auto& column : key_columns) { | 101 | 32.9k | const auto* field = column->get_data_at(pos); | 102 | 32.9k | if (UNLIKELY(!field)) { | 103 | 244 | encoded_keys.push_back(KeyConsts::KEY_NULL_FIRST_MARKER); | 104 | 244 | ++cid; | 105 | 244 | continue; | 106 | 244 | } | 107 | 32.6k | encoded_keys.push_back(KeyConsts::KEY_NORMAL_MARKER); | 108 | 32.6k | encode_field(cid, field, &encoded_keys); | 109 | 32.6k | ++cid; | 110 | 32.6k | } | 111 | 27.1k | return encoded_keys; | 112 | 27.1k | } |
|
113 | | } // namespace |
114 | | |
115 | | std::string RowKeyEncoder::_full_encode(const std::vector<const KeyCoder*>& key_coders, |
116 | | const std::vector<IOlapColumnDataAccessor*>& key_columns, |
117 | 14.9k | size_t pos) { |
118 | 14.9k | assert(key_columns.size() == key_coders.size()); |
119 | 14.9k | return encode_key_columns(key_columns, pos, |
120 | 29.5k | [&](size_t cid, const void* field, std::string* out) { |
121 | 29.5k | DCHECK(key_coders[cid] != nullptr); |
122 | 29.5k | key_coders[cid]->full_encode_ascending(field, out); |
123 | 29.5k | }); |
124 | 14.9k | } |
125 | | |
126 | | std::string RowKeyEncoder::encode_short_keys( |
127 | 27.1k | const std::vector<IOlapColumnDataAccessor*>& key_columns, size_t pos) const { |
128 | 27.1k | assert(key_columns.size() == _num_short_key_columns); |
129 | 27.1k | assert(key_columns.size() <= _sort_key_coders.size()); |
130 | 27.1k | return encode_key_columns( |
131 | 32.6k | key_columns, pos, [&](size_t cid, const void* field, std::string* out) { |
132 | 32.6k | _sort_key_coders[cid]->encode_ascending(field, _sort_key_index_size[cid], out); |
133 | 32.6k | }); |
134 | 27.1k | } |
135 | | |
136 | | void RowKeyEncoder::append_seq_suffix(std::string* encoded_keys, |
137 | 282 | const IOlapColumnDataAccessor* seq_column, size_t pos) const { |
138 | 282 | const auto* field = seq_column->get_data_at(pos); |
139 | | // So the primary key index can still use it, encode a null seq column as |
140 | | // the smallest value of its length. |
141 | 282 | if (UNLIKELY(!field)) { |
142 | 24 | encoded_keys->push_back(KeyConsts::KEY_NULL_FIRST_MARKER); |
143 | 24 | encoded_keys->append(_seq_col_length, KeyConsts::KEY_MINIMAL_MARKER); |
144 | 24 | return; |
145 | 24 | } |
146 | 258 | encoded_keys->push_back(KeyConsts::KEY_NORMAL_MARKER); |
147 | 258 | _seq_coder->full_encode_ascending(field, encoded_keys); |
148 | 258 | } |
149 | | |
150 | 236 | void RowKeyEncoder::append_rowid_suffix(std::string* encoded_keys, uint32_t rowid) const { |
151 | 236 | encoded_keys->push_back(KeyConsts::KEY_NORMAL_MARKER); |
152 | 236 | _rowid_coder->full_encode_ascending(&rowid, encoded_keys); |
153 | 236 | } |
154 | | |
155 | | } // namespace doris |