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/rowset/rowset_meta.h" |
19 | | |
20 | | #include <gen_cpp/olap_file.pb.h> |
21 | | #include <glog/logging.h> |
22 | | |
23 | | #include <algorithm> |
24 | | #include <iterator> |
25 | | #include <memory> |
26 | | #include <random> |
27 | | |
28 | | #include "cloud/cloud_storage_engine.h" |
29 | | #include "common/logging.h" |
30 | | #include "common/status.h" |
31 | | #include "cpp/sync_point.h" |
32 | | #include "exec/common/variant_util.h" |
33 | | #include "google/protobuf/util/message_differencer.h" |
34 | | #include "io/fs/encrypted_fs_factory.h" |
35 | | #include "io/fs/file_system.h" |
36 | | #include "io/fs/file_writer.h" |
37 | | #include "io/fs/local_file_system.h" |
38 | | #include "io/fs/packed_file_manager.h" |
39 | | #include "io/fs/packed_file_system.h" |
40 | | #include "json2pb/json_to_pb.h" |
41 | | #include "json2pb/pb_to_json.h" |
42 | | #include "runtime/exec_env.h" |
43 | | #include "storage/olap_common.h" |
44 | | #include "storage/storage_policy.h" |
45 | | #include "storage/tablet/base_tablet.h" |
46 | | #include "storage/tablet/tablet_fwd.h" |
47 | | #include "storage/tablet/tablet_schema.h" |
48 | | #include "storage/tablet/tablet_schema_cache.h" |
49 | | #include "util/lru_cache.h" |
50 | | |
51 | | namespace doris { |
52 | | |
53 | 17.3k | RowsetMeta::~RowsetMeta() { |
54 | 17.3k | if (_handle) { |
55 | 4.86k | TabletSchemaCache::instance()->release(_handle); |
56 | 4.86k | } |
57 | 17.3k | } |
58 | | |
59 | 13 | bool RowsetMeta::init(std::string_view pb_rowset_meta) { |
60 | 13 | bool ret = _deserialize_from_pb(pb_rowset_meta); |
61 | 13 | if (!ret) { |
62 | 1 | return false; |
63 | 1 | } |
64 | 12 | _init(); |
65 | 12 | return true; |
66 | 13 | } |
67 | | |
68 | 124 | bool RowsetMeta::init(const RowsetMeta* rowset_meta) { |
69 | 124 | RowsetMetaPB rowset_meta_pb; |
70 | 124 | rowset_meta->to_rowset_pb(&rowset_meta_pb); |
71 | 124 | return init_from_pb(rowset_meta_pb); |
72 | 124 | } |
73 | | |
74 | 9.03k | bool RowsetMeta::init_from_pb(const RowsetMetaPB& rowset_meta_pb) { |
75 | 9.03k | if (rowset_meta_pb.has_tablet_schema()) { |
76 | 389 | set_tablet_schema(rowset_meta_pb.tablet_schema()); |
77 | 389 | } |
78 | | // Release ownership of TabletSchemaPB from `rowset_meta_pb` and then set it back to `rowset_meta_pb`, |
79 | | // this won't break const semantics of `rowset_meta_pb`, because `rowset_meta_pb` is not changed |
80 | | // before and after call this method. |
81 | 9.03k | auto& mut_rowset_meta_pb = const_cast<RowsetMetaPB&>(rowset_meta_pb); |
82 | 9.03k | auto* schema = mut_rowset_meta_pb.release_tablet_schema(); |
83 | 9.03k | _rowset_meta_pb = mut_rowset_meta_pb; |
84 | 9.03k | mut_rowset_meta_pb.set_allocated_tablet_schema(schema); |
85 | 9.03k | _init(); |
86 | 9.03k | return true; |
87 | 9.03k | } |
88 | | |
89 | 78 | bool RowsetMeta::init_from_json(const std::string& json_rowset_meta) { |
90 | 78 | bool ret = json2pb::JsonToProtoMessage(json_rowset_meta, &_rowset_meta_pb); |
91 | 78 | if (!ret) { |
92 | 1 | return false; |
93 | 1 | } |
94 | 77 | _init(); |
95 | 77 | return true; |
96 | 78 | } |
97 | | |
98 | 0 | bool RowsetMeta::json_rowset_meta(std::string* json_rowset_meta) { |
99 | 0 | json2pb::Pb2JsonOptions json_options; |
100 | 0 | json_options.pretty_json = true; |
101 | 0 | bool ret = json2pb::ProtoMessageToJson(_rowset_meta_pb, json_rowset_meta, json_options); |
102 | 0 | return ret; |
103 | 0 | } |
104 | | |
105 | 6.14k | io::FileSystemSPtr RowsetMeta::physical_fs() { |
106 | 6.14k | if (is_local()) { |
107 | 6.13k | return io::global_local_filesystem(); |
108 | 6.13k | } |
109 | | |
110 | 7 | auto storage_resource = remote_storage_resource(); |
111 | 7 | if (storage_resource) { |
112 | 4 | return storage_resource.value()->fs; |
113 | 4 | } else { |
114 | 3 | LOG(WARNING) << storage_resource.error(); |
115 | 3 | return nullptr; |
116 | 3 | } |
117 | 7 | } |
118 | | |
119 | 6.14k | io::FileSystemSPtr RowsetMeta::fs() { |
120 | 6.14k | auto fs = physical_fs(); |
121 | | |
122 | | #ifndef BE_TEST |
123 | | auto algorithm = _determine_encryption_once.call([this]() -> Result<EncryptionAlgorithmPB> { |
124 | | auto maybe_tablet = ExecEnv::get_tablet(tablet_id()); |
125 | | if (!maybe_tablet) { |
126 | | LOG(WARNING) << "get tablet failed: " << maybe_tablet.error(); |
127 | | return ResultError(maybe_tablet.error()); |
128 | | } |
129 | | auto tablet = maybe_tablet.value(); |
130 | | return tablet->tablet_meta()->encryption_algorithm(); |
131 | | }); |
132 | | if (!algorithm.has_value()) { |
133 | | // TODO: return a Result<FileSystemSPtr> in this method? |
134 | | return nullptr; |
135 | | } |
136 | | |
137 | | // Apply packed file system first if enabled and index_map is not empty |
138 | | io::FileSystemSPtr wrapped = fs; |
139 | | if (_rowset_meta_pb.packed_slice_locations_size() > 0) { |
140 | | std::unordered_map<std::string, io::PackedSliceLocation> index_map; |
141 | | for (const auto& [path, index_pb] : _rowset_meta_pb.packed_slice_locations()) { |
142 | | io::PackedSliceLocation index; |
143 | | index.packed_file_path = index_pb.packed_file_path(); |
144 | | index.offset = index_pb.offset(); |
145 | | index.size = index_pb.size(); |
146 | | index.packed_file_size = |
147 | | index_pb.has_packed_file_size() ? index_pb.packed_file_size() : -1; |
148 | | index.tablet_id = tablet_id(); |
149 | | index.rowset_id = _rowset_id.to_string(); |
150 | | index.resource_id = wrapped->id(); |
151 | | index_map[path] = index; |
152 | | } |
153 | | if (!index_map.empty()) { |
154 | | io::PackedAppendContext append_info; |
155 | | append_info.tablet_id = tablet_id(); |
156 | | append_info.rowset_id = _rowset_id.to_string(); |
157 | | append_info.txn_id = txn_id(); |
158 | | wrapped = std::make_shared<io::PackedFileSystem>(wrapped, index_map, append_info); |
159 | | } |
160 | | } |
161 | | |
162 | | // Then apply encryption on top |
163 | | wrapped = io::make_file_system(wrapped, algorithm.value()); |
164 | | return wrapped; |
165 | | #else |
166 | 6.14k | return fs; |
167 | 6.14k | #endif |
168 | 6.14k | } |
169 | | |
170 | 13 | Result<const StorageResource*> RowsetMeta::remote_storage_resource() { |
171 | 13 | if (is_local()) { |
172 | 0 | return ResultError(Status::InternalError<false>( |
173 | 0 | "local rowset has no storage resource. tablet_id={} rowset_id={}", tablet_id(), |
174 | 0 | _rowset_id.to_string())); |
175 | 0 | } |
176 | | |
177 | 13 | if (!_storage_resource.fs) { |
178 | 3 | if (auto storage_resource = get_storage_resource(resource_id())) { |
179 | 0 | _storage_resource = std::move(storage_resource->first); |
180 | 3 | } else { |
181 | 3 | if (config::is_cloud_mode()) { |
182 | | // When creating a new cluster or creating a storage resource, BE may not sync storage resource, |
183 | | // at the moment a query is coming, the BetaRowsetReader call loadSegment and use this method |
184 | | // to get the storage resource, so we need to sync storage resource here. |
185 | 0 | ExecEnv::GetInstance()->storage_engine().to_cloud().sync_storage_vault(); |
186 | 0 | if (auto retry_resource = get_storage_resource(resource_id())) { |
187 | 0 | _storage_resource = std::move(retry_resource->first); |
188 | 0 | return &_storage_resource; |
189 | 0 | } |
190 | 0 | } |
191 | 3 | return ResultError(Status::InternalError<false>( |
192 | 3 | "cannot find storage resource. resource_id={}", resource_id())); |
193 | 3 | } |
194 | 3 | } |
195 | 10 | return &_storage_resource; |
196 | 13 | } |
197 | | |
198 | 16 | void RowsetMeta::set_remote_storage_resource(StorageResource resource) { |
199 | 16 | _storage_resource = std::move(resource); |
200 | 16 | _rowset_meta_pb.set_resource_id(_storage_resource.fs->id()); |
201 | 16 | } |
202 | | |
203 | 11.0k | bool RowsetMeta::has_variant_type_in_schema() const { |
204 | 11.0k | return _schema && _schema->num_variant_columns() > 0; |
205 | 11.0k | } |
206 | | |
207 | 11.0k | void RowsetMeta::to_rowset_pb(RowsetMetaPB* rs_meta_pb, bool skip_schema) const { |
208 | 11.0k | *rs_meta_pb = _rowset_meta_pb; |
209 | 11.0k | if (_schema) [[likely]] { |
210 | 832 | rs_meta_pb->set_schema_version(_schema->schema_version()); |
211 | 832 | if (!skip_schema) { |
212 | | // For cloud, separate tablet schema from rowset meta to reduce persistent size. |
213 | 832 | _schema->to_schema_pb(rs_meta_pb->mutable_tablet_schema()); |
214 | 832 | } |
215 | 832 | } |
216 | 11.0k | rs_meta_pb->set_has_variant_type_in_schema(has_variant_type_in_schema()); |
217 | 11.0k | } |
218 | | |
219 | 182 | RowsetMetaPB RowsetMeta::get_rowset_pb(bool skip_schema) const { |
220 | 182 | RowsetMetaPB rowset_meta_pb; |
221 | 182 | to_rowset_pb(&rowset_meta_pb, skip_schema); |
222 | 182 | return rowset_meta_pb; |
223 | 182 | } |
224 | | |
225 | 5.53k | void RowsetMeta::set_tablet_schema(const TabletSchemaSPtr& tablet_schema) { |
226 | 5.53k | if (_handle) { |
227 | 1.05k | TabletSchemaCache::instance()->release(_handle); |
228 | 1.05k | } |
229 | 5.53k | auto pair = TabletSchemaCache::instance()->insert(tablet_schema->to_key()); |
230 | 5.53k | _handle = pair.first; |
231 | 5.53k | _schema = pair.second; |
232 | 5.53k | } |
233 | | |
234 | 392 | void RowsetMeta::set_tablet_schema(const TabletSchemaPB& tablet_schema) { |
235 | 392 | if (_handle) { |
236 | 0 | TabletSchemaCache::instance()->release(_handle); |
237 | 0 | } |
238 | 392 | auto pair = TabletSchemaCache::instance()->insert( |
239 | 392 | TabletSchema::deterministic_string_serialize(tablet_schema)); |
240 | 392 | _handle = pair.first; |
241 | 392 | _schema = pair.second; |
242 | 392 | } |
243 | | |
244 | 13 | bool RowsetMeta::_deserialize_from_pb(std::string_view value) { |
245 | 13 | if (!_rowset_meta_pb.ParseFromArray(value.data(), cast_set<int32_t>(value.size()))) { |
246 | 1 | _rowset_meta_pb.Clear(); |
247 | 1 | return false; |
248 | 1 | } |
249 | 12 | if (_rowset_meta_pb.has_tablet_schema()) { |
250 | 0 | set_tablet_schema(_rowset_meta_pb.tablet_schema()); |
251 | 0 | _rowset_meta_pb.set_allocated_tablet_schema(nullptr); |
252 | 0 | } |
253 | 12 | return true; |
254 | 13 | } |
255 | | |
256 | 6 | bool RowsetMeta::_serialize_to_pb(std::string* value) { |
257 | 6 | if (value == nullptr) { |
258 | 0 | return false; |
259 | 0 | } |
260 | 6 | RowsetMetaPB rowset_meta_pb = _rowset_meta_pb; |
261 | 6 | if (_schema) { |
262 | 0 | _schema->to_schema_pb(rowset_meta_pb.mutable_tablet_schema()); |
263 | 0 | } |
264 | 6 | return rowset_meta_pb.SerializeToString(value); |
265 | 6 | } |
266 | | |
267 | 9.12k | void RowsetMeta::_init() { |
268 | 9.12k | if (_rowset_meta_pb.rowset_id() > 0) { |
269 | 3.66k | _rowset_id.init(_rowset_meta_pb.rowset_id()); |
270 | 5.46k | } else { |
271 | 5.46k | _rowset_id.init(_rowset_meta_pb.rowset_id_v2()); |
272 | 5.46k | } |
273 | 9.12k | _validate_segment_ids(); |
274 | 9.12k | update_metadata_size(); |
275 | 9.12k | } |
276 | | |
277 | 9.20k | void RowsetMeta::_validate_segment_ids() const { |
278 | 9.20k | if (!has_segment_ids()) { |
279 | 9.12k | return; |
280 | 9.12k | } |
281 | 72 | DORIS_CHECK_EQ(_rowset_meta_pb.segment_ids_size(), _rowset_meta_pb.num_segments()); |
282 | 72 | int64_t prev_segment_id = -1; |
283 | 365 | for (const auto segment_id : _rowset_meta_pb.segment_ids()) { |
284 | 365 | DORIS_CHECK_GE(segment_id, 0); |
285 | 365 | DORIS_CHECK_GT(segment_id, prev_segment_id); |
286 | 365 | prev_segment_id = segment_id; |
287 | 365 | } |
288 | 72 | } |
289 | | |
290 | 72 | void RowsetMeta::set_segment_ids(const std::vector<int64_t>& segment_ids) { |
291 | 72 | _rowset_meta_pb.mutable_segment_ids()->Assign(segment_ids.begin(), segment_ids.end()); |
292 | 72 | set_num_segments(cast_set<int64_t>(segment_ids.size())); |
293 | 72 | _validate_segment_ids(); |
294 | 72 | } |
295 | | |
296 | 224 | size_t RowsetMeta::position_of(int64_t seg_id) const { |
297 | 224 | DORIS_CHECK_GE(seg_id, 0); |
298 | 224 | if (!has_segment_ids()) { |
299 | 156 | DORIS_CHECK_LT(seg_id, num_segments()); |
300 | 156 | return cast_set<size_t>(seg_id); |
301 | 156 | } |
302 | 68 | const auto& segment_ids = _rowset_meta_pb.segment_ids(); |
303 | 68 | auto it = std::lower_bound(segment_ids.begin(), segment_ids.end(), seg_id); |
304 | 68 | DORIS_CHECK(it != segment_ids.end()); |
305 | 68 | DORIS_CHECK_EQ(*it, seg_id); |
306 | 68 | return cast_set<size_t>(std::distance(segment_ids.begin(), it)); |
307 | 224 | } |
308 | | |
309 | 1 | void RowsetMeta::add_segments_file_size(const std::vector<size_t>& seg_file_size) { |
310 | 1 | _rowset_meta_pb.set_enable_segments_file_size(true); |
311 | 3 | for (auto fsize : seg_file_size) { |
312 | 3 | _rowset_meta_pb.add_segments_file_size(fsize); |
313 | 3 | } |
314 | 1 | } |
315 | | |
316 | 3.70k | int64_t RowsetMeta::segment_file_size_by_pos(size_t pos) const { |
317 | 3.70k | DCHECK(_rowset_meta_pb.segments_file_size().empty() || |
318 | 0 | _rowset_meta_pb.segments_file_size_size() > cast_set<int>(pos)) |
319 | 0 | << _rowset_meta_pb.segments_file_size_size() << ' ' << pos; |
320 | 3.70k | return _rowset_meta_pb.enable_segments_file_size() |
321 | 3.70k | ? (_rowset_meta_pb.segments_file_size_size() > cast_set<int>(pos) |
322 | 1 | ? _rowset_meta_pb.segments_file_size(cast_set<int>(pos)) |
323 | 1 | : -1) |
324 | 3.70k | : -1; |
325 | 3.70k | } |
326 | | |
327 | | void RowsetMeta::set_segments_key_bounds(const std::vector<KeyBoundsPB>& segments_key_bounds, |
328 | 1.13k | bool aggregate_into_single) { |
329 | 1.13k | _rowset_meta_pb.clear_segments_key_bounds(); |
330 | 1.13k | bool did_aggregate = aggregate_into_single && !segments_key_bounds.empty(); |
331 | 1.13k | if (did_aggregate) { |
332 | 744 | const std::string* overall_min = &segments_key_bounds.front().min_key(); |
333 | 744 | const std::string* overall_max = &segments_key_bounds.front().max_key(); |
334 | 2.74k | for (const KeyBoundsPB& key_bounds : segments_key_bounds) { |
335 | 2.74k | if (key_bounds.min_key() < *overall_min) { |
336 | 4 | overall_min = &key_bounds.min_key(); |
337 | 4 | } |
338 | 2.74k | if (key_bounds.max_key() > *overall_max) { |
339 | 1.25k | overall_max = &key_bounds.max_key(); |
340 | 1.25k | } |
341 | 2.74k | } |
342 | 744 | KeyBoundsPB* aggregated = _rowset_meta_pb.add_segments_key_bounds(); |
343 | 744 | aggregated->set_min_key(*overall_min); |
344 | 744 | aggregated->set_max_key(*overall_max); |
345 | 744 | } else { |
346 | 390 | for (const KeyBoundsPB& key_bounds : segments_key_bounds) { |
347 | 202 | KeyBoundsPB* new_key_bounds = _rowset_meta_pb.add_segments_key_bounds(); |
348 | 202 | *new_key_bounds = key_bounds; |
349 | 202 | } |
350 | 390 | } |
351 | 1.13k | set_segments_key_bounds_aggregated(did_aggregate); |
352 | | |
353 | 1.13k | int32_t truncation_threshold = config::segments_key_bounds_truncation_threshold; |
354 | 1.13k | if (config::random_segments_key_bounds_truncation) { |
355 | 0 | std::mt19937 generator(std::random_device {}()); |
356 | 0 | std::uniform_int_distribution<int> distribution(-10, 40); |
357 | 0 | truncation_threshold = distribution(generator); |
358 | 0 | } |
359 | 1.13k | bool really_do_truncation {false}; |
360 | 1.13k | if (truncation_threshold > 0) { |
361 | 810 | for (auto& segment_key_bounds : *_rowset_meta_pb.mutable_segments_key_bounds()) { |
362 | 632 | if (segment_key_bounds.min_key().size() > truncation_threshold) { |
363 | 66 | really_do_truncation = true; |
364 | 66 | segment_key_bounds.mutable_min_key()->resize(truncation_threshold); |
365 | 66 | } |
366 | 632 | if (segment_key_bounds.max_key().size() > truncation_threshold) { |
367 | 66 | really_do_truncation = true; |
368 | 66 | segment_key_bounds.mutable_max_key()->resize(truncation_threshold); |
369 | 66 | } |
370 | 632 | } |
371 | 810 | } |
372 | 1.13k | set_segments_key_bounds_truncated(really_do_truncation || is_segments_key_bounds_truncated()); |
373 | 1.13k | } |
374 | | |
375 | 3 | void RowsetMeta::merge_rowset_meta(const RowsetMeta& other) { |
376 | 3 | set_num_segments(num_segments() + other.num_segments()); |
377 | 3 | set_num_rows(num_rows() + other.num_rows()); |
378 | 3 | set_data_disk_size(data_disk_size() + other.data_disk_size()); |
379 | 3 | set_total_disk_size(total_disk_size() + other.total_disk_size()); |
380 | 3 | set_index_disk_size(index_disk_size() + other.index_disk_size()); |
381 | 3 | set_total_disk_size(data_disk_size() + index_disk_size()); |
382 | 3 | set_segments_key_bounds_truncated(is_segments_key_bounds_truncated() || |
383 | 3 | other.is_segments_key_bounds_truncated()); |
384 | | // merge_rowset_meta is used in the MOW partial-update publish path, which relies |
385 | | // on per-segment bounds. Aggregation should never be enabled for MOW rowsets, |
386 | | // so we do not expect either side to be aggregated here. |
387 | 3 | DCHECK(!is_segments_key_bounds_aggregated() && !other.is_segments_key_bounds_aggregated()) |
388 | 0 | << "merge_rowset_meta encountered aggregated key bounds"; |
389 | 3 | if (_rowset_meta_pb.num_segment_rows_size() > 0) { |
390 | 2 | if (other.num_segments() > 0) { |
391 | 2 | if (other._rowset_meta_pb.num_segment_rows_size() > 0) { |
392 | 3 | for (auto row_count : other._rowset_meta_pb.num_segment_rows()) { |
393 | 3 | _rowset_meta_pb.add_num_segment_rows(row_count); |
394 | 3 | } |
395 | 1 | } else { |
396 | | // This may happen when a partial update load commits in high version doirs_be |
397 | | // and publishes with new segments in low version doris_be. In this case, just clear |
398 | | // all num_segment_rows. |
399 | 1 | _rowset_meta_pb.clear_num_segment_rows(); |
400 | 1 | } |
401 | 2 | } |
402 | 2 | } |
403 | 3 | for (auto&& key_bound : other.get_segments_key_bounds()) { |
404 | 0 | add_segment_key_bounds(key_bound); |
405 | 0 | } |
406 | 3 | if (_rowset_meta_pb.enable_segments_file_size() && |
407 | 3 | other._rowset_meta_pb.enable_segments_file_size()) { |
408 | 0 | for (auto fsize : other.segments_file_size()) { |
409 | 0 | _rowset_meta_pb.add_segments_file_size(fsize); |
410 | 0 | } |
411 | 0 | } |
412 | 3 | if (_rowset_meta_pb.enable_inverted_index_file_info() && |
413 | 3 | other._rowset_meta_pb.enable_inverted_index_file_info()) { |
414 | 0 | for (auto finfo : other.inverted_index_file_info()) { |
415 | 0 | InvertedIndexFileInfo* new_file_info = _rowset_meta_pb.add_inverted_index_file_info(); |
416 | 0 | *new_file_info = finfo; |
417 | 0 | } |
418 | 0 | } |
419 | | // In partial update the rowset schema maybe updated when table contains variant type, so we need the newest schema to be updated |
420 | | // Otherwise the schema is stale and lead to wrong data read |
421 | 3 | TEST_SYNC_POINT_RETURN_WITH_VOID("RowsetMeta::merge_rowset_meta:skip_schema_merge"); |
422 | 0 | if (tablet_schema()->num_variant_columns() > 0) { |
423 | | // merge extracted columns |
424 | 0 | TabletSchemaSPtr merged_schema; |
425 | 0 | static_cast<void>(variant_util::get_least_common_schema( |
426 | 0 | {tablet_schema(), other.tablet_schema()}, nullptr, merged_schema)); |
427 | 0 | if (*_schema != *merged_schema) { |
428 | 0 | set_tablet_schema(merged_schema); |
429 | 0 | } |
430 | 0 | } |
431 | 0 | if (rowset_state() == RowsetStatePB::BEGIN_PARTIAL_UPDATE) { |
432 | 0 | set_rowset_state(RowsetStatePB::COMMITTED); |
433 | 0 | } |
434 | |
|
435 | 0 | update_metadata_size(); |
436 | 0 | } |
437 | | |
438 | 9.12k | int64_t RowsetMeta::get_metadata_size() const { |
439 | 9.12k | return sizeof(RowsetMeta) + _rowset_meta_pb.ByteSizeLong(); |
440 | 9.12k | } |
441 | | |
442 | 5.27k | InvertedIndexFileInfo RowsetMeta::inverted_index_file_info_by_pos(size_t pos) const { |
443 | 5.27k | return _rowset_meta_pb.enable_inverted_index_file_info() |
444 | 5.27k | ? (_rowset_meta_pb.inverted_index_file_info_size() > cast_set<int>(pos) |
445 | 2.40k | ? _rowset_meta_pb.inverted_index_file_info(cast_set<int>(pos)) |
446 | 2.40k | : InvertedIndexFileInfo()) |
447 | 5.27k | : InvertedIndexFileInfo(); |
448 | 5.27k | } |
449 | | |
450 | | void RowsetMeta::add_inverted_index_files_info( |
451 | 160 | const std::vector<const InvertedIndexFileInfo*>& idx_file_info) { |
452 | 160 | _rowset_meta_pb.set_enable_inverted_index_file_info(true); |
453 | 270 | for (auto finfo : idx_file_info) { |
454 | 270 | auto* new_file_info = _rowset_meta_pb.add_inverted_index_file_info(); |
455 | 270 | *new_file_info = *finfo; |
456 | 270 | } |
457 | 160 | } |
458 | | |
459 | 0 | bool operator==(const RowsetMeta& a, const RowsetMeta& b) { |
460 | 0 | if (a._rowset_id != b._rowset_id) return false; |
461 | 0 | if (a._is_removed_from_rowset_meta != b._is_removed_from_rowset_meta) return false; |
462 | 0 | if (!google::protobuf::util::MessageDifferencer::Equals(a._rowset_meta_pb, b._rowset_meta_pb)) |
463 | 0 | return false; |
464 | 0 | return true; |
465 | 0 | } |
466 | | |
467 | | } // namespace doris |