@@ -935,6 +935,7 @@ void TabletMeta::delete_stale_rs_meta_by_version(const Version& version) {
935
935
// remove rowset delete bitmap
936
936
delete_bitmap ().remove ({(*it)->rowset_id (), 0 , 0 },
937
937
{(*it)->rowset_id (), UINT32_MAX, 0 });
938
+ delete_bitmap ().remove_rowset_cache_version ((*it)->rowset_id ());
938
939
}
939
940
it = _stale_rs_metas.erase (it);
940
941
} else {
@@ -1283,6 +1284,23 @@ bool DeleteBitmap::has_calculated_for_multi_segments(const RowsetId& rowset_id)
1283
1284
return contains ({rowset_id, INVALID_SEGMENT_ID, TEMP_VERSION_COMMON}, ROWSET_SENTINEL_MARK);
1284
1285
}
1285
1286
1287
+ void DeleteBitmap::remove_rowset_cache_version (const RowsetId& rowset_id) {
1288
+ std::lock_guard l (_rowset_cache_version_lock);
1289
+ _rowset_cache_version.erase (rowset_id);
1290
+ }
1291
+
1292
+ DeleteBitmap::Version DeleteBitmap::_get_rowset_cache_version (const BitmapKey& bmk) const {
1293
+ std::shared_lock l (_rowset_cache_version_lock);
1294
+ if (auto it = _rowset_cache_version.find (std::get<0 >(bmk)); it != _rowset_cache_version.end ()) {
1295
+ auto & segment_cache_version = it->second ;
1296
+ if (auto it1 = segment_cache_version.find (std::get<1 >(bmk));
1297
+ it1 != segment_cache_version.end ()) {
1298
+ return it1->second ;
1299
+ }
1300
+ }
1301
+ return 0 ;
1302
+ }
1303
+
1286
1304
// We cannot just copy the underlying memory to construct a string
1287
1305
// due to equivalent objects may have different padding bytes.
1288
1306
// Reading padding bytes is undefined behavior, neither copy nor
@@ -1314,9 +1332,27 @@ std::shared_ptr<roaring::Roaring> DeleteBitmap::get_agg(const BitmapKey& bmk) co
1314
1332
// of cache entries in some cases?
1315
1333
if (val == nullptr ) { // Renew if needed, put a new Value to cache
1316
1334
val = new AggCache::Value ();
1335
+ Version start_version = _get_rowset_cache_version (bmk);
1336
+ if (start_version > 0 ) {
1337
+ Cache::Handle * handle2 = _agg_cache->repr ()->lookup (
1338
+ agg_cache_key (_tablet_id, {std::get<0 >(bmk), std::get<1 >(bmk), start_version}));
1339
+ if (handle2 == nullptr ) {
1340
+ start_version = 0 ;
1341
+ } else {
1342
+ val->bitmap |=
1343
+ reinterpret_cast <AggCache::Value*>(_agg_cache->repr ()->value (handle2))
1344
+ ->bitmap ;
1345
+ _agg_cache->repr ()->release (handle2);
1346
+ VLOG_DEBUG << " get agg cache version=" << start_version
1347
+ << " for tablet=" << _tablet_id
1348
+ << " , rowset=" << std::get<0 >(bmk).to_string ()
1349
+ << " , segment=" << std::get<1 >(bmk);
1350
+ start_version += 1 ;
1351
+ }
1352
+ }
1317
1353
{
1318
1354
std::shared_lock l (lock);
1319
- DeleteBitmap::BitmapKey start {std::get<0 >(bmk), std::get<1 >(bmk), 0 };
1355
+ DeleteBitmap::BitmapKey start {std::get<0 >(bmk), std::get<1 >(bmk), start_version };
1320
1356
for (auto it = delete_bitmap.lower_bound (start); it != delete_bitmap.end (); ++it) {
1321
1357
auto & [k, bm] = *it;
1322
1358
if (std::get<0 >(k) != std::get<0 >(bmk) || std::get<1 >(k) != std::get<1 >(bmk) ||
@@ -1328,6 +1364,12 @@ std::shared_ptr<roaring::Roaring> DeleteBitmap::get_agg(const BitmapKey& bmk) co
1328
1364
}
1329
1365
size_t charge = val->bitmap .getSizeInBytes () + sizeof (AggCache::Value);
1330
1366
handle = _agg_cache->repr ()->insert (key, val, charge, charge, CachePriority::NORMAL);
1367
+ // this version is already agged
1368
+ std::lock_guard l (_rowset_cache_version_lock);
1369
+ _rowset_cache_version[std::get<0 >(bmk)][std::get<1 >(bmk)] = std::get<2 >(bmk);
1370
+ VLOG_DEBUG << " set agg cache version=" << std::get<2 >(bmk) << " for tablet=" << _tablet_id
1371
+ << " , rowset=" << std::get<0 >(bmk).to_string ()
1372
+ << " , segment=" << std::get<1 >(bmk);
1331
1373
}
1332
1374
1333
1375
// It is natural for the cache to reclaim the underlying memory
0 commit comments