Coverage Report

Created: 2026-10-29 14:40

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/storage/tablet/tablet_meta.h
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
#pragma once
19
20
#include <gen_cpp/AgentService_types.h>
21
#include <gen_cpp/FrontendService_types.h>
22
#include <gen_cpp/olap_file.pb.h>
23
#include <stdint.h>
24
25
#include <atomic>
26
#include <cstddef>
27
#include <limits>
28
#include <map>
29
#include <memory>
30
#include <mutex>
31
#include <optional>
32
#include <ostream>
33
#include <roaring/roaring.hh>
34
#include <shared_mutex>
35
#include <string>
36
#include <tuple>
37
#include <unordered_map>
38
#include <utility>
39
#include <vector>
40
41
#include "common/logging.h"
42
#include "common/status.h"
43
#include "io/fs/file_system.h"
44
#include "runtime/memory/lru_cache_policy.h"
45
#include "storage/binlog_config.h"
46
#include "storage/metadata_adder.h"
47
#include "storage/olap_common.h"
48
#include "storage/rowset/rowset_meta.h"
49
#include "storage/tablet/tablet_schema.h"
50
#include "util/lru_cache.h"
51
#include "util/uid_util.h"
52
53
namespace json2pb {
54
struct Pb2JsonOptions;
55
} // namespace json2pb
56
57
namespace doris {
58
class TColumn;
59
60
// Lifecycle states that a Tablet can be in. Legal state transitions for a
61
// Tablet object:
62
//
63
//   NOTREADY -> RUNNING -> TOMBSTONED -> STOPPED -> SHUTDOWN
64
//      |           |            |          ^^^
65
//      |           |            +----------++|
66
//      |           +------------------------+|
67
//      +-------------------------------------+
68
69
enum class TabletState {
70
    // Tablet is under alter table, rollup, clone
71
    TABLET_NOTREADY,
72
73
    TABLET_RUNNING,
74
75
    // Tablet integrity has been violated, such as missing versions.
76
    // In this state, tablet will not accept any incoming request.
77
    // Report this state to FE, scheduling BE to drop tablet.
78
    TABLET_TOMBSTONED,
79
80
    // Tablet is shutting down, files in disk still remained.
81
    TABLET_STOPPED,
82
83
    // Files have been removed, tablet has been shutdown completely.
84
    TABLET_SHUTDOWN
85
};
86
87
inline constexpr TabletState TABLET_NOTREADY = TabletState::TABLET_NOTREADY;
88
inline constexpr TabletState TABLET_RUNNING = TabletState::TABLET_RUNNING;
89
inline constexpr TabletState TABLET_TOMBSTONED = TabletState::TABLET_TOMBSTONED;
90
inline constexpr TabletState TABLET_STOPPED = TabletState::TABLET_STOPPED;
91
inline constexpr TabletState TABLET_SHUTDOWN = TabletState::TABLET_SHUTDOWN;
92
93
class DataDir;
94
class TabletMeta;
95
class DeleteBitmap;
96
class TBinlogConfig;
97
98
// Class encapsulates meta of tablet.
99
// The concurrency control is handled in Tablet Class, not in this class.
100
class TabletMeta : public MetadataAdder<TabletMeta> {
101
public:
102
    static TabletMetaSharedPtr create(
103
            const TCreateTabletReq& request, const TabletUid& tablet_uid, uint64_t shard_id,
104
            uint32_t next_unique_id,
105
            const std::unordered_map<uint32_t, uint32_t>& col_ordinal_to_unique_id);
106
107
    TabletMeta();
108
    ~TabletMeta() override;
109
    TabletMeta(int64_t table_id, int64_t partition_id, int64_t tablet_id, int64_t replica_id,
110
               int32_t schema_hash, int32_t shard_id, const TTabletSchema& tablet_schema,
111
               uint32_t next_unique_id,
112
               const std::unordered_map<uint32_t, uint32_t>& col_ordinal_to_unique_id,
113
               TabletUid tablet_uid, TTabletType::type tabletType,
114
               TCompressionType::type compression_type, int64_t storage_policy_id = 0,
115
               bool enable_unique_key_merge_on_write = false,
116
               std::optional<TBinlogConfig> binlog_config = {},
117
               std::string compaction_policy = "size_based",
118
               int64_t time_series_compaction_goal_size_mbytes = 1024,
119
               int64_t time_series_compaction_file_count_threshold = 1000,
120
               int64_t time_series_compaction_time_threshold_seconds = 3600,
121
               int64_t time_series_compaction_empty_rowsets_threshold = 5,
122
               int64_t time_series_compaction_level_threshold = 1,
123
               TInvertedIndexFileStorageFormat::type inverted_index_file_storage_format =
124
                       TInvertedIndexFileStorageFormat::V2,
125
               TEncryptionAlgorithm::type tde_algorithm = TEncryptionAlgorithm::PLAINTEXT,
126
               TStorageFormat::type storage_format = TStorageFormat::V2,
127
               int32_t vertical_compaction_num_columns_per_group = 5,
128
               TTabletRole::type tablet_role = TTabletRole::TABLET_ROLE_DATA);
129
    // If need add a filed in TableMeta, filed init copy in copy construct function
130
    TabletMeta(const TabletMeta& tablet_meta);
131
    TabletMeta(TabletMeta&& tablet_meta) = delete;
132
133
// UT
134
#ifdef BE_TEST
135
    TabletMeta(TabletSchemaSPtr tablet_schema) : _schema(tablet_schema) {
136
        _row_ttl_config.set_duration_us(tablet_schema->row_ttl_duration_us());
137
        _disable_auto_compaction.store(tablet_schema->disable_auto_compaction());
138
    }
139
#endif
140
141
    // Function create_from_file is used to be compatible with previous tablet_meta.
142
    // Previous tablet_meta is a physical file in tablet dir, which is not stored in rocksdb.
143
    Status create_from_file(const std::string& file_path);
144
    // Used to create tablet meta from memory buffer.
145
    Status create_from_buffer(const uint8_t* buffer, size_t buffer_size);
146
    static Status load_from_file(const std::string& file_path, TabletMetaPB* tablet_meta_pb);
147
    Status save(const std::string& file_path);
148
    Status save_as_json(const std::string& file_path);
149
    static Status save(const std::string& file_path, const TabletMetaPB& tablet_meta_pb);
150
    static std::string construct_header_file_path(const std::string& schema_hash_path,
151
                                                  int64_t tablet_id);
152
    Status save_meta(DataDir* data_dir);
153
154
    void serialize(std::string* meta_binary);
155
    Status deserialize(std::string_view meta_binary);
156
    void init_from_pb(const TabletMetaPB& tablet_meta_pb);
157
158
    void to_meta_pb(TabletMetaPB* tablet_meta_pb, bool cloud_get_rowset_meta);
159
    void to_json(std::string* json_string, json2pb::Pb2JsonOptions& options);
160
426k
    size_t tablet_columns_num() const { return _schema->num_columns(); }
161
162
0
    TabletTypePB tablet_type() const { return _tablet_type; }
163
    TabletUid tablet_uid() const;
164
105
    void set_tablet_uid(TabletUid uid) { _tablet_uid = uid; }
165
    int64_t table_id() const;
166
    int64_t index_id() const;
167
    int64_t partition_id() const;
168
    int64_t tablet_id() const;
169
    int64_t replica_id() const;
170
0
    void set_replica_id(int64_t replica_id) { _replica_id = replica_id; }
171
    int32_t schema_hash() const;
172
    int32_t shard_id() const;
173
    void set_shard_id(int32_t shard_id);
174
    int64_t creation_time() const;
175
    void set_creation_time(int64_t creation_time);
176
    int64_t cumulative_layer_point() const;
177
    void set_cumulative_layer_point(int64_t new_point);
178
179
    size_t num_rows() const;
180
    // Disk space occupied by tablet, contain local and remote.
181
    size_t tablet_footprint() const;
182
    // Local disk space occupied by tablet.
183
    size_t tablet_local_size() const;
184
    // Remote disk space occupied by tablet.
185
    size_t tablet_remote_size() const;
186
    size_t tablet_local_index_size() const;
187
    size_t tablet_local_segment_size() const;
188
    size_t tablet_remote_index_size() const;
189
    size_t tablet_remote_segment_size() const;
190
191
    size_t version_count() const;
192
    size_t stale_version_count() const;
193
    size_t version_count_cross_with_range(const Version& range) const;
194
    Version max_version() const;
195
196
    TabletState tablet_state() const;
197
    void set_tablet_state(TabletState state);
198
199
    bool in_restore_mode() const;
200
    void set_in_restore_mode(bool in_restore_mode);
201
202
    const TabletSchemaSPtr& tablet_schema() const;
203
204
    TabletSchema* mutable_tablet_schema();
205
206
    // This mutable tablet property must not modify the shared, cached schema.
207
1.84G
    bool disable_auto_compaction() const { return _disable_auto_compaction.load(); }
208
22
    void set_disable_auto_compaction(bool value) { _disable_auto_compaction.store(value); }
209
210
    const RowsetMetaMapContainer& all_rs_metas() const;
211
    RowsetMetaMapContainer& all_mutable_rs_metas();
212
    Status add_rs_meta(const RowsetMetaSharedPtr& rs_meta);
213
    void delete_rs_meta_by_version(const Version& version,
214
                                   std::vector<RowsetMetaSharedPtr>* deleted_rs_metas);
215
    // If same_version is true, the rowset in "to_delete" will not be added
216
    // to _stale_rs_meta, but to be deleted from rs_meta directly.
217
    void modify_rs_metas(const std::vector<RowsetMetaSharedPtr>& to_add,
218
                         const std::vector<RowsetMetaSharedPtr>& to_delete,
219
                         bool same_version = false);
220
    void revise_rs_metas(std::vector<RowsetMetaSharedPtr>&& rs_metas);
221
    void revise_delete_bitmap_unlocked(const DeleteBitmap& delete_bitmap);
222
223
    const RowsetMetaMapContainer& all_stale_rs_metas() const;
224
    RowsetMetaSharedPtr acquire_rs_meta_by_version(const Version& version) const;
225
    void delete_stale_rs_meta_by_version(const Version& version);
226
    RowsetMetaSharedPtr acquire_stale_rs_meta_by_version(const Version& version) const;
227
228
    Status set_partition_id(int64_t partition_id);
229
230
732
    RowsetTypePB preferred_rowset_type() const { return _preferred_rowset_type; }
231
232
126
    void set_preferred_rowset_type(RowsetTypePB preferred_rowset_type) {
233
126
        _preferred_rowset_type = preferred_rowset_type;
234
126
    }
235
236
    // used for after tablet cloned to clear stale rowset
237
    void clear_stale_rowset();
238
239
    // Clear stale rowset metadata without changing the delete bitmap cache.
240
    void clear_stale_rs_metas();
241
242
    void clear_rowsets();
243
244
    // MUST hold EXCLUSIVE `_meta_lock` in belonged Tablet
245
    // `to_add` MUST NOT have overlapped version with `_rs_metas` in tablet meta.
246
    void add_rowsets_unchecked(const std::vector<RowsetSharedPtr>& to_add);
247
248
    bool all_beta() const;
249
250
2.39M
    int64_t storage_policy_id() const { return _storage_policy_id; }
251
252
4
    void set_storage_policy_id(int64_t id) {
253
4
        VLOG_NOTICE << "set tablet_id : " << _table_id << " storage policy from "
254
4
                    << _storage_policy_id << " to " << id;
255
4
        _storage_policy_id = id;
256
4
    }
257
258
3.27M
    UniqueId cooldown_meta_id() const { return _cooldown_meta_id; }
259
5
    void set_cooldown_meta_id(UniqueId uid) { _cooldown_meta_id = uid; }
260
261
    static void init_column_from_tcolumn(uint32_t unique_id, const TColumn& tcolumn,
262
                                         ColumnPB* column);
263
264
    struct SchemaCreateOptions {
265
        const std::unordered_map<uint32_t, uint32_t>& col_ordinal_to_unique_id;
266
        TCompressionType::type compression_type;
267
        TInvertedIndexFileStorageFormat::type inverted_index_file_storage_format;
268
        uint32_t next_unique_id;
269
    };
270
271
    static void init_schema_from_thrift(const TTabletSchema& tablet_schema,
272
                                        const SchemaCreateOptions& schema_create_options,
273
                                        TabletSchemaPB* tablet_schema_pb);
274
275
2.76M
    DeleteBitmapPtr delete_bitmap_ptr() { return _delete_bitmap; }
276
477k
    DeleteBitmap& delete_bitmap() { return *_delete_bitmap; }
277
278
    void remove_rowset_delete_bitmap(const RowsetId& rowset_id, const Version& version);
279
280
7.52M
    bool enable_unique_key_merge_on_write() const { return _enable_unique_key_merge_on_write; }
281
#ifdef BE_TEST
282
    void set_enable_unique_key_merge_on_write(bool value) {
283
        _enable_unique_key_merge_on_write = value;
284
    }
285
#endif
286
    // Access under the tablet header lock, like binlog_config().
287
243k
    const RowTtlConfigPB& row_ttl_config() const { return _row_ttl_config; }
288
    Status update_row_ttl_config(const RowTtlConfigPB& config);
289
290
    // TODO(Drogon): thread safety
291
828k
    const BinlogConfig& binlog_config() const { return _binlog_config; }
292
15
    void set_binlog_config(BinlogConfig binlog_config) {
293
15
        _binlog_config = std::move(binlog_config);
294
15
    }
295
0
    TabletRolePB tablet_role() const { return _tablet_role; }
296
4.71G
    bool is_changelog_tablet() const { return _tablet_role == TabletRolePB::TABLET_ROLE_CHANGELOG; }
297
    void set_tablet_role(TabletRolePB tablet_role) { _tablet_role = tablet_role; }
298
4.02k
    int64_t changelog_tablet_id() const { return _changelog_tablet_id; }
299
4
    void set_changelog_tablet_id(int64_t changelog_tablet_id) {
300
4
        _changelog_tablet_id = changelog_tablet_id;
301
4
    }
302
303
46
    void set_compaction_policy(std::string compaction_policy) {
304
46
        _compaction_policy = compaction_policy;
305
46
    }
306
1.88G
    std::string compaction_policy() const { return _compaction_policy; }
307
14
    void set_time_series_compaction_goal_size_mbytes(int64_t goal_size_mbytes) {
308
14
        _time_series_compaction_goal_size_mbytes = goal_size_mbytes;
309
14
    }
310
491k
    int64_t time_series_compaction_goal_size_mbytes() const {
311
491k
        return _time_series_compaction_goal_size_mbytes;
312
491k
    }
313
14
    void set_time_series_compaction_file_count_threshold(int64_t file_count_threshold) {
314
14
        _time_series_compaction_file_count_threshold = file_count_threshold;
315
14
    }
316
491k
    int64_t time_series_compaction_file_count_threshold() const {
317
491k
        return _time_series_compaction_file_count_threshold;
318
491k
    }
319
15
    void set_time_series_compaction_time_threshold_seconds(int64_t time_threshold) {
320
15
        _time_series_compaction_time_threshold_seconds = time_threshold;
321
15
    }
322
491k
    int64_t time_series_compaction_time_threshold_seconds() const {
323
491k
        return _time_series_compaction_time_threshold_seconds;
324
491k
    }
325
2
    void set_time_series_compaction_empty_rowsets_threshold(int64_t empty_rowsets_threshold) {
326
2
        _time_series_compaction_empty_rowsets_threshold = empty_rowsets_threshold;
327
2
    }
328
491k
    int64_t time_series_compaction_empty_rowsets_threshold() const {
329
491k
        return _time_series_compaction_empty_rowsets_threshold;
330
491k
    }
331
4
    void set_time_series_compaction_level_threshold(int64_t level_threshold) {
332
4
        _time_series_compaction_level_threshold = level_threshold;
333
4
    }
334
491k
    int64_t time_series_compaction_level_threshold() const {
335
491k
        return _time_series_compaction_level_threshold;
336
491k
    }
337
338
2
    void set_vertical_compaction_num_columns_per_group(int32_t num) {
339
2
        _vertical_compaction_num_columns_per_group = num;
340
2
    }
341
501k
    int32_t vertical_compaction_num_columns_per_group() const {
342
501k
        return _vertical_compaction_num_columns_per_group;
343
501k
    }
344
345
2.04M
    int64_t ttl_seconds() const {
346
2.04M
        std::shared_lock rlock(_meta_lock);
347
2.04M
        return _ttl_seconds;
348
2.04M
    }
349
350
33
    void set_ttl_seconds(int64_t ttl_seconds) {
351
33
        std::lock_guard wlock(_meta_lock);
352
33
        _ttl_seconds = ttl_seconds;
353
33
    }
354
355
    // Absolute timestamp (seconds since epoch) at which this tablet's data stops being kept
356
    // in the file cache TTL queue, or 0 when the tablet has no TTL or the deadline has
357
    // already passed. The deadline is anchored at the tablet creation time, so every tablet
358
    // of a table shares one deadline regardless of when each rowset was written.
359
    //
360
    // This is the single definition of that deadline. The load, compaction, schema change,
361
    // query and warm up paths all stamp the cache blocks they create with this value, and
362
    // BlockFileCacheTtlMgr expires those blocks by the very same value, so a block's
363
    // recorded expiration time always agrees with the sweep that acts on it.
364
    int64_t file_cache_ttl_expiration_time() const;
365
366
178
    int64_t avg_rs_meta_serialize_size() const { return _avg_rs_meta_serialize_size; }
367
368
454k
    EncryptionAlgorithmPB encryption_algorithm() const { return _encryption_algorithm; }
369
370
208k
    bool has_inverted_index_storage_format() const {
371
208k
        return _inverted_index_storage_format.has_value();
372
208k
    }
373
374
209k
    InvertedIndexStorageFormatPB inverted_index_storage_format() const {
375
209k
        return _inverted_index_storage_format.value_or(
376
209k
                _schema->get_inverted_index_storage_format());
377
209k
    }
378
379
private:
380
    Status _save_meta(DataDir* data_dir);
381
    void _check_mow_rowset_cache_version_size(size_t rowset_cache_version_size);
382
383
    // _del_predicates is ignored to compare.
384
    friend bool operator==(const TabletMeta& a, const TabletMeta& b);
385
    friend bool operator!=(const TabletMeta& a, const TabletMeta& b);
386
387
private:
388
    int64_t _table_id = 0;
389
    int64_t _index_id = 0;
390
    int64_t _partition_id = 0;
391
    int64_t _tablet_id = 0;
392
    int64_t _replica_id = 0;
393
    int32_t _schema_hash = 0;
394
    int32_t _shard_id = 0;
395
    int64_t _creation_time = 0;
396
    int64_t _cumulative_layer_point = 0;
397
    TabletUid _tablet_uid;
398
    TabletTypePB _tablet_type = TabletTypePB::TABLET_TYPE_DISK;
399
400
    TabletState _tablet_state = TabletState::TABLET_NOTREADY;
401
    // the reference of _schema may use in tablet, so here need keep
402
    // the lifetime of tablemeta and _schema is same with tablet
403
    TabletSchemaSPtr _schema;
404
    Cache::Handle* _handle = nullptr;
405
    // Scheduling reads this without _meta_lock; persist it in the existing schema PB field.
406
    std::atomic<bool> _disable_auto_compaction {false};
407
408
    RowsetMetaMapContainer _rs_metas;
409
    // This variable _stale_rs_metas is used to record these rowsets‘ meta which are be compacted.
410
    // These stale rowsets meta are been removed when rowsets' pathVersion is expired,
411
    // this policy is judged and computed by TimestampedVersionTracker.
412
    RowsetMetaMapContainer _stale_rs_metas;
413
    bool _in_restore_mode = false;
414
    RowsetTypePB _preferred_rowset_type = BETA_ROWSET;
415
416
    // meta for cooldown
417
    int64_t _storage_policy_id = 0; // <= 0 means no storage policy
418
    UniqueId _cooldown_meta_id;
419
420
    // For unique key data model, the feature Merge-on-Write will leverage a primary
421
    // key index and a delete-bitmap to mark duplicate keys as deleted in load stage,
422
    // which can avoid the merging cost in read stage, and accelerate the aggregation
423
    // query performance significantly.
424
    bool _enable_unique_key_merge_on_write = false;
425
    std::shared_ptr<DeleteBitmap> _delete_bitmap;
426
427
    // binlog config
428
    BinlogConfig _binlog_config {};
429
    RowTtlConfigPB _row_ttl_config;
430
    TabletRolePB _tablet_role = TabletRolePB::TABLET_ROLE_DATA;
431
    int64_t _changelog_tablet_id = 0;
432
433
    // meta for compaction
434
    std::string _compaction_policy;
435
    int64_t _time_series_compaction_goal_size_mbytes = 0;
436
    int64_t _time_series_compaction_file_count_threshold = 0;
437
    int64_t _time_series_compaction_time_threshold_seconds = 0;
438
    int64_t _time_series_compaction_empty_rowsets_threshold = 0;
439
    int64_t _time_series_compaction_level_threshold = 0;
440
    int32_t _vertical_compaction_num_columns_per_group = 5;
441
442
    int64_t _avg_rs_meta_serialize_size = 0;
443
444
    // cloud
445
    int64_t _ttl_seconds = 0;
446
447
    EncryptionAlgorithmPB _encryption_algorithm = PLAINTEXT;
448
449
    // Persisted storage format for this tablet (e.g. V2, V3). Used to derive
450
    // schema-level defaults such as external ColumnMeta usage.
451
    TStorageFormat::type _storage_format = TStorageFormat::V2;
452
    // The schema KV is shared by (index_id, schema_version). Keep the tablet's
453
    // immutable file format outside that shared identity.
454
    std::optional<InvertedIndexStorageFormatPB> _inverted_index_storage_format;
455
456
    mutable std::shared_mutex _meta_lock;
457
};
458
459
class DeleteBitmapAggCache : public LRUCachePolicy {
460
public:
461
    DeleteBitmapAggCache(size_t capacity);
462
463
    static DeleteBitmapAggCache* instance();
464
465
    static DeleteBitmapAggCache* create_instance(size_t capacity);
466
467
    DeleteBitmap snapshot(int64_t tablet_id);
468
469
    class Value : public LRUCacheValueBase {
470
    public:
471
        roaring::Roaring bitmap;
472
    };
473
};
474
475
/**
476
 * Wraps multiple bitmaps for recording rows (row id) that are deleted or
477
 * overwritten. For now, it's only used when unique key merge-on-write property
478
 * enabled.
479
 *
480
 * RowsetId and SegmentId are for locating segment, Version here is a single
481
 * uint32_t means that at which "version" of the load causes the delete or
482
 * overwrite.
483
 *
484
 * The start and end version of a load is the same, it's ok and straightforward
485
 * to use a single uint32_t.
486
 *
487
 * e.g.
488
 * There is a key "key1" in rowset id 1, version [1,1], segment id 1, row id 1.
489
 * A new load also contains "key1", the rowset id 2, version [2,2], segment id 1
490
 * the delete bitmap will be `{1,1,2} -> 1`, which means the "row id 1" in
491
 * "rowset id 1, segment id 1" is deleted/overitten by some loads at "version 2"
492
 */
493
class DeleteBitmap {
494
public:
495
    mutable std::shared_mutex lock;
496
    using SegmentId = uint32_t;
497
    using Version = uint64_t;
498
    using BitmapKey = std::tuple<RowsetId, SegmentId, Version>;
499
    using RowsetIdWithSegmentIds = std::pair<RowsetId, std::vector<SegmentId>>;
500
    std::map<BitmapKey, roaring::Roaring> delete_bitmap; // Ordered map
501
    constexpr static inline uint32_t INVALID_SEGMENT_ID = std::numeric_limits<uint32_t>::max() - 1;
502
    constexpr static inline uint32_t ROWSET_SENTINEL_MARK =
503
            std::numeric_limits<uint32_t>::max() - 1;
504
505
    // When a delete bitmap is merged into tablet's delete bitmap, the version of entries in the delete bitmap
506
    // will be replaced to the correspoding correct version. So before we finally merge a delete bitmap into
507
    // tablet's delete bitmap we can use arbitary version number in BitmapKey. Here we define some version numbers
508
    // for specific usage during this periods to avoid conflicts
509
    constexpr static inline uint64_t TEMP_VERSION_COMMON = 0;
510
511
    /**
512
     * 
513
     * @param tablet_id the tablet which this delete bitmap associates with
514
     */
515
    DeleteBitmap(int64_t tablet_id);
516
517
    /**
518
     * Copy c-tor for making delete bitmap snapshot on read path
519
     */
520
    DeleteBitmap(const DeleteBitmap& r);
521
    DeleteBitmap& operator=(const DeleteBitmap& r);
522
    /**
523
     * Move c-tor for making delete bitmap snapshot on read path
524
     */
525
    DeleteBitmap(DeleteBitmap&& r) noexcept;
526
    DeleteBitmap& operator=(DeleteBitmap&& r) noexcept;
527
528
    static DeleteBitmap from_pb(const DeleteBitmapPB& pb, int64_t tablet_id);
529
530
    DeleteBitmapPB to_pb();
531
532
    /**
533
     * Makes a snapshot of delete bitmap, read lock will be acquired in this
534
     * process
535
     */
536
    DeleteBitmap snapshot() const;
537
538
    /**
539
     * Makes a snapshot of delete bitmap on given version, read lock will be
540
     * acquired temporary in this process
541
     */
542
    DeleteBitmap snapshot(Version version) const;
543
544
    /**
545
     * Marks the specific row deleted
546
     */
547
    void add(const BitmapKey& bmk, uint32_t row_id);
548
549
    /**
550
     * Clears the deletetion mark specific row
551
     *
552
     * @return non-zero if the associated delete bitmap does not exist
553
     */
554
    int remove(const BitmapKey& bmk, uint32_t row_id);
555
556
    /**
557
     * Clears bitmaps in range [lower_key, upper_key)
558
     */
559
    void remove(const BitmapKey& lower_key, const BitmapKey& upper_key);
560
    void remove(const std::vector<std::tuple<BitmapKey, BitmapKey>>& key_ranges);
561
562
    /**
563
     * Checks if the given row is marked deleted
564
     *
565
     * @return true if marked deleted
566
     */
567
    bool contains(const BitmapKey& bmk, uint32_t row_id) const;
568
    bool contain_rowsets(const RowsetIdUnorderedSet& rowset_ids) const;
569
570
    /**
571
     * Checks if this delete bitmap is empty
572
     *
573
     * @return true if empty
574
     */
575
    bool empty() const;
576
577
    /**
578
     * return the total cardinality of the Delete Bitmap
579
     */
580
    uint64_t cardinality() const;
581
582
    /**
583
     * return the total size of the Delete Bitmap(after serialized)
584
     */
585
586
    uint64_t get_size() const;
587
588
    /**
589
     * Sets the bitmap of specific segment, it's may be insertion or replacement
590
     *
591
     * @return 1 if the insertion took place, 0 if the assignment took place
592
     */
593
    int set(const BitmapKey& bmk, const roaring::Roaring& segment_delete_bitmap);
594
595
    /**
596
     * Gets a copy of specific delete bmk
597
     *
598
     * @param segment_delete_bitmap output param
599
     * @return non-zero if the associated delete bitmap does not exist
600
     */
601
    int get(const BitmapKey& bmk, roaring::Roaring* segment_delete_bitmap) const;
602
603
    /**
604
     * Gets reference to a specific delete map, DO NOT use this function on a
605
     * mutable DeleteBitmap object
606
     * @return nullptr if the given bitmap does not exist
607
     */
608
    const roaring::Roaring* get(const BitmapKey& bmk) const;
609
610
    /**
611
     * Gets subset of delete_bitmap with given range [start, end)
612
     *
613
     * @parma start start
614
     * @parma end end
615
     * @parma subset_delete_map output param
616
     */
617
    void subset(const BitmapKey& start, const BitmapKey& end,
618
                DeleteBitmap* subset_delete_map) const;
619
    void subset(const std::vector<RowsetIdWithSegmentIds>& rowsets, int64_t start_version,
620
                int64_t end_version, DeleteBitmap* subset_delete_map) const;
621
622
    /**
623
     * Gets subset of delete_bitmap of the input rowsets
624
     * with given version range [start_version, end_version] and agg to end_version,
625
     * then merge to subset_delete_map
626
     */
627
    void subset_and_agg(const std::vector<RowsetIdWithSegmentIds>& rowsets, int64_t start_version,
628
                        int64_t end_version, DeleteBitmap* subset_delete_map) const;
629
630
    /**
631
     * Gets count of delete_bitmap with given range [start, end)
632
     *
633
     * @parma start start
634
     * @parma end end
635
     */
636
    size_t get_count_with_range(const BitmapKey& start, const BitmapKey& end) const;
637
638
    /**
639
     * Merges the given segment delete bitmap into *this
640
     *
641
     * @param bmk
642
     * @param segment_delete_bitmap
643
     */
644
    void merge(const BitmapKey& bmk, const roaring::Roaring& segment_delete_bitmap);
645
646
    /**
647
     * Merges the given delete bitmap into *this
648
     *
649
     * @param other
650
     */
651
    void merge(const DeleteBitmap& other);
652
653
    /**
654
     * Checks if the given row is marked deleted in bitmap with the condition:
655
     * all the bitmaps that
656
     * RowsetId and SegmentId are the same as the given ones,
657
     * and Version <= the given Version
658
     *
659
     * Note: aggregation cache may be used.
660
     *
661
     * @return true if marked deleted
662
     */
663
    bool contains_agg(const BitmapKey& bitmap, uint32_t row_id) const;
664
665
    bool contains_agg_with_cache_if_eligible(const BitmapKey& bmk, uint32_t row_id) const;
666
    /**
667
     * Gets aggregated delete_bitmap on rowset_id and version, the same effect:
668
     * `select sum(roaring::Roaring) where RowsetId=rowset_id and SegmentId=seg_id and Version <= version`
669
     *
670
     * @return shared_ptr to a bitmap, which may be empty
671
     */
672
    std::shared_ptr<roaring::Roaring> get_agg(const BitmapKey& bmk) const;
673
    std::shared_ptr<roaring::Roaring> get_agg_without_cache(const BitmapKey& bmk,
674
                                                            const int64_t start_version = 0) const;
675
676
    void remove_sentinel_marks();
677
678
    uint64_t get_delete_bitmap_count();
679
680
    void traverse_rowset_and_version(
681
            const std::function<int(const RowsetId& rowsetId, int64_t version)>& func) const;
682
683
    bool has_calculated_for_multi_segments(const RowsetId& rowset_id) const;
684
685
    // return the size of the map
686
    size_t remove_rowset_cache_version(const RowsetId& rowset_id);
687
688
    void clear_rowset_cache_version();
689
690
    std::set<std::string> get_rowset_cache_version();
691
692
    DeleteBitmap agg_cache_snapshot();
693
694
    void set_tablet_id(int64_t tablet_id);
695
696
    /**
697
     * Calculate diffset with given `key_set`. All entries with keys contained in this delete bitmap but not
698
     * in given key_set will be added to the output delete bitmap.
699
     *
700
     * @return Deletebitmap containning all entries in diffset
701
    */
702
    DeleteBitmap diffset(const std::set<BitmapKey>& key_set) const;
703
704
private:
705
    DeleteBitmap::Version _get_rowset_cache_version(const BitmapKey& bmk) const;
706
707
    int64_t _tablet_id;
708
    mutable std::shared_mutex _rowset_cache_version_lock;
709
    mutable std::map<RowsetId, std::map<SegmentId, Version>> _rowset_cache_version;
710
};
711
712
2.27M
inline TabletUid TabletMeta::tablet_uid() const {
713
2.27M
    return _tablet_uid;
714
2.27M
}
715
716
3.77M
inline int64_t TabletMeta::table_id() const {
717
3.77M
    return _table_id;
718
3.77M
}
719
720
3.36M
inline int64_t TabletMeta::index_id() const {
721
3.36M
    return _index_id;
722
3.36M
}
723
724
9.97M
inline int64_t TabletMeta::partition_id() const {
725
9.97M
    return _partition_id;
726
9.97M
}
727
728
3.80G
inline int64_t TabletMeta::tablet_id() const {
729
3.80G
    return _tablet_id;
730
3.80G
}
731
732
1.72M
inline int64_t TabletMeta::replica_id() const {
733
1.72M
    return _replica_id;
734
1.72M
}
735
736
1.95M
inline int32_t TabletMeta::schema_hash() const {
737
1.95M
    return _schema_hash;
738
1.95M
}
739
740
304k
inline int32_t TabletMeta::shard_id() const {
741
304k
    return _shard_id;
742
304k
}
743
744
17
inline void TabletMeta::set_shard_id(int32_t shard_id) {
745
17
    _shard_id = shard_id;
746
17
}
747
748
1.70M
inline int64_t TabletMeta::creation_time() const {
749
1.70M
    return _creation_time;
750
1.70M
}
751
752
inline void TabletMeta::set_creation_time(int64_t creation_time) {
753
    _creation_time = creation_time;
754
}
755
756
5.50k
inline int64_t TabletMeta::cumulative_layer_point() const {
757
5.50k
    return _cumulative_layer_point;
758
5.50k
}
759
760
0
inline void TabletMeta::set_cumulative_layer_point(int64_t new_point) {
761
0
    _cumulative_layer_point = new_point;
762
0
}
763
764
1.34M
inline size_t TabletMeta::num_rows() const {
765
1.34M
    size_t num_rows = 0;
766
2.29M
    for (const auto& [_, rs] : _rs_metas) {
767
2.29M
        num_rows += rs->num_rows();
768
2.29M
    }
769
1.34M
    return num_rows;
770
1.34M
}
771
772
1.33k
inline size_t TabletMeta::tablet_footprint() const {
773
1.33k
    size_t total_size = 0;
774
5.03k
    for (const auto& [_, rs] : _rs_metas) {
775
5.03k
        total_size += rs->total_disk_size();
776
5.03k
    }
777
1.33k
    return total_size;
778
1.33k
}
779
780
4.48M
inline size_t TabletMeta::tablet_local_size() const {
781
4.48M
    size_t total_size = 0;
782
7.68M
    for (const auto& [_, rs] : _rs_metas) {
783
7.68M
        if (rs->is_local()) {
784
7.68M
            total_size += rs->total_disk_size();
785
7.68M
        }
786
7.68M
    }
787
4.48M
    return total_size;
788
4.48M
}
789
790
4.48M
inline size_t TabletMeta::tablet_remote_size() const {
791
4.48M
    size_t total_size = 0;
792
7.68M
    for (const auto& [_, rs] : _rs_metas) {
793
7.68M
        if (!rs->is_local()) {
794
60
            total_size += rs->total_disk_size();
795
60
        }
796
7.68M
    }
797
4.48M
    return total_size;
798
4.48M
}
799
800
1.34M
inline size_t TabletMeta::tablet_local_index_size() const {
801
1.34M
    size_t total_size = 0;
802
2.29M
    for (const auto& [_, rs] : _rs_metas) {
803
2.29M
        if (rs->is_local()) {
804
2.29M
            total_size += rs->index_disk_size();
805
2.29M
        }
806
2.29M
    }
807
1.34M
    return total_size;
808
1.34M
}
809
810
1.34M
inline size_t TabletMeta::tablet_local_segment_size() const {
811
1.34M
    size_t total_size = 0;
812
2.29M
    for (const auto& [_, rs] : _rs_metas) {
813
2.29M
        if (rs->is_local()) {
814
2.29M
            total_size += rs->data_disk_size();
815
2.29M
        }
816
2.29M
    }
817
1.34M
    return total_size;
818
1.34M
}
819
820
1.34M
inline size_t TabletMeta::tablet_remote_index_size() const {
821
1.34M
    size_t total_size = 0;
822
2.29M
    for (const auto& [_, rs] : _rs_metas) {
823
2.29M
        if (!rs->is_local()) {
824
18
            total_size += rs->index_disk_size();
825
18
        }
826
2.29M
    }
827
1.34M
    return total_size;
828
1.34M
}
829
830
1.34M
inline size_t TabletMeta::tablet_remote_segment_size() const {
831
1.34M
    size_t total_size = 0;
832
2.29M
    for (const auto& [_, rs] : _rs_metas) {
833
2.29M
        if (!rs->is_local()) {
834
18
            total_size += rs->data_disk_size();
835
18
        }
836
2.29M
    }
837
1.34M
    return total_size;
838
1.34M
}
839
840
11.1M
inline size_t TabletMeta::version_count() const {
841
11.1M
    return _rs_metas.size();
842
11.1M
}
843
844
178
inline size_t TabletMeta::stale_version_count() const {
845
178
    return _rs_metas.size();
846
178
}
847
848
983M
inline TabletState TabletMeta::tablet_state() const {
849
983M
    return _tablet_state;
850
983M
}
851
852
11.2k
inline void TabletMeta::set_tablet_state(TabletState state) {
853
11.2k
    _tablet_state = state;
854
11.2k
}
855
856
5.50k
inline bool TabletMeta::in_restore_mode() const {
857
5.50k
    return _in_restore_mode;
858
5.50k
}
859
860
0
inline void TabletMeta::set_in_restore_mode(bool in_restore_mode) {
861
0
    _in_restore_mode = in_restore_mode;
862
0
}
863
864
8.16M
inline const TabletSchemaSPtr& TabletMeta::tablet_schema() const {
865
8.16M
    return _schema;
866
8.16M
}
867
868
61
inline TabletSchema* TabletMeta::mutable_tablet_schema() {
869
61
    return _schema.get();
870
61
}
871
872
11.7M
inline const RowsetMetaMapContainer& TabletMeta::all_rs_metas() const {
873
11.7M
    return _rs_metas;
874
11.7M
}
875
876
298k
inline RowsetMetaMapContainer& TabletMeta::all_mutable_rs_metas() {
877
298k
    return _rs_metas;
878
298k
}
879
880
743k
inline const RowsetMetaMapContainer& TabletMeta::all_stale_rs_metas() const {
881
743k
    return _stale_rs_metas;
882
743k
}
883
884
0
inline bool TabletMeta::all_beta() const {
885
0
    for (const auto& [_, rs] : _rs_metas) {
886
0
        if (rs->rowset_type() != RowsetTypePB::BETA_ROWSET) {
887
0
            return false;
888
0
        }
889
0
    }
890
0
    for (const auto& [_, rs] : _stale_rs_metas) {
891
0
        if (rs->rowset_type() != RowsetTypePB::BETA_ROWSET) {
892
0
            return false;
893
0
        }
894
0
    }
895
0
    return true;
896
0
}
897
898
std::string tablet_state_name(TabletState state);
899
900
// Only for unit test now.
901
bool operator==(const TabletMeta& a, const TabletMeta& b);
902
bool operator!=(const TabletMeta& a, const TabletMeta& b);
903
904
} // namespace doris