chore(snapshot): Small cleanup in Snapshot code (#4377)

* chore(snapshot): Small cleanup in Snapshot code

Signed-off-by: Stepan Bagritsevich <stefan@dragonflydb.io>

* refactor: address comments

Signed-off-by: Stepan Bagritsevich <stefan@dragonflydb.io>

---------

Signed-off-by: Stepan Bagritsevich <stefan@dragonflydb.io>
This commit is contained in:
Stepan Bagritsevich 2024-12-26 20:02:20 +04:00 committed by GitHub
parent 0065c27f27
commit 9fbb301988
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 21 additions and 22 deletions

View file

@ -225,6 +225,7 @@ class RdbSerializer : public SerializerBase {
// Must be called in the thread to which `it` belongs. // Must be called in the thread to which `it` belongs.
// Returns the serialized rdb_type or the error. // Returns the serialized rdb_type or the error.
// expire_ms = 0 means no expiry. // expire_ms = 0 means no expiry.
// This function might preempt if flush_fun_ is used.
io::Result<uint8_t> SaveEntry(const PrimeKey& pk, const PrimeValue& pv, uint64_t expire_ms, io::Result<uint8_t> SaveEntry(const PrimeKey& pk, const PrimeValue& pv, uint64_t expire_ms,
uint32_t mc_flags, DbIndex dbid); uint32_t mc_flags, DbIndex dbid);

View file

@ -38,8 +38,11 @@ constexpr size_t kMinBlobSize = 32_KB;
SliceSnapshot::SliceSnapshot(CompressionMode compression_mode, DbSlice* slice, SliceSnapshot::SliceSnapshot(CompressionMode compression_mode, DbSlice* slice,
SnapshotDataConsumerInterface* consumer, Context* cntx) SnapshotDataConsumerInterface* consumer, Context* cntx)
: db_slice_(slice), compression_mode_(compression_mode), consumer_(consumer), cntx_(cntx) { : db_slice_(slice),
db_array_ = slice->databases(); db_array_(slice->databases()),
compression_mode_(compression_mode),
consumer_(consumer),
cntx_(cntx) {
tl_slice_snapshots.insert(this); tl_slice_snapshots.insert(this);
} }
@ -163,7 +166,6 @@ void SliceSnapshot::IterateBucketsFb(bool send_full_sync_cut) {
uint64_t last_yield = 0; uint64_t last_yield = 0;
PrimeTable* pt = &db_array_[db_indx]->prime; PrimeTable* pt = &db_array_[db_indx]->prime;
current_db_ = db_indx;
VLOG(1) << "Start traversing " << pt->size() << " items for index " << db_indx; VLOG(1) << "Start traversing " << pt->size() << " items for index " << db_indx;
do { do {
@ -171,8 +173,8 @@ void SliceSnapshot::IterateBucketsFb(bool send_full_sync_cut) {
return; return;
} }
PrimeTable::Cursor next = PrimeTable::Cursor next = pt->TraverseBuckets(
pt->TraverseBuckets(cursor, [this](auto it) { return BucketSaveCb(it); }); cursor, [this, &db_indx](auto it) { return BucketSaveCb(db_indx, it); });
cursor = next; cursor = next;
PushSerialized(false); PushSerialized(false);
@ -248,7 +250,7 @@ void SliceSnapshot::SwitchIncrementalFb(LSN lsn) {
} }
} }
bool SliceSnapshot::BucketSaveCb(PrimeTable::bucket_iterator it) { bool SliceSnapshot::BucketSaveCb(DbIndex db_index, PrimeTable::bucket_iterator it) {
std::lock_guard guard(big_value_mu_); std::lock_guard guard(big_value_mu_);
++stats_.savecb_calls; ++stats_.savecb_calls;
@ -267,7 +269,7 @@ bool SliceSnapshot::BucketSaveCb(PrimeTable::bucket_iterator it) {
return false; return false;
} }
db_slice_->FlushChangeToEarlierCallbacks(current_db_, DbSlice::Iterator::FromPrime(it), db_slice_->FlushChangeToEarlierCallbacks(db_index, DbSlice::Iterator::FromPrime(it),
snapshot_version_); snapshot_version_);
auto* blocking_counter = db_slice_->BlockingCounter(); auto* blocking_counter = db_slice_->BlockingCounter();
@ -276,7 +278,7 @@ bool SliceSnapshot::BucketSaveCb(PrimeTable::bucket_iterator it) {
// zero. // zero.
std::lock_guard blocking_counter_guard(*blocking_counter); std::lock_guard blocking_counter_guard(*blocking_counter);
stats_.loop_serialized += SerializeBucket(current_db_, it); stats_.loop_serialized += SerializeBucket(db_index, it);
return false; return false;
} }
@ -292,20 +294,19 @@ unsigned SliceSnapshot::SerializeBucket(DbIndex db_index, PrimeTable::bucket_ite
while (!it.is_done()) { while (!it.is_done()) {
++result; ++result;
// might preempt due to big value serialization. // might preempt due to big value serialization.
SerializeEntry(db_index, it->first, it->second, nullopt, serializer_.get()); SerializeEntry(db_index, it->first, it->second);
++it; ++it;
} }
serialize_bucket_running_ = false; serialize_bucket_running_ = false;
return result; return result;
} }
void SliceSnapshot::SerializeEntry(DbIndex db_indx, const PrimeKey& pk, const PrimeValue& pv, void SliceSnapshot::SerializeEntry(DbIndex db_indx, const PrimeKey& pk, const PrimeValue& pv) {
optional<uint64_t> expire, RdbSerializer* serializer) {
if (pv.IsExternal() && pv.IsCool()) if (pv.IsExternal() && pv.IsCool())
return SerializeEntry(db_indx, pk, pv.GetCool().record->value, expire, serializer); return SerializeEntry(db_indx, pk, pv.GetCool().record->value);
time_t expire_time = expire.value_or(0); time_t expire_time = 0;
if (!expire && pv.HasExpire()) { if (pv.HasExpire()) {
auto eit = db_array_[db_indx]->expire.Find(pk); auto eit = db_array_[db_indx]->expire.Find(pk);
expire_time = db_slice_->ExpireTime(eit); expire_time = db_slice_->ExpireTime(eit);
} }
@ -322,7 +323,7 @@ void SliceSnapshot::SerializeEntry(DbIndex db_indx, const PrimeKey& pk, const Pr
{db_indx, PrimeKey(pk.ToString()), std::move(future), expire_time, mc_flags}); {db_indx, PrimeKey(pk.ToString()), std::move(future), expire_time, mc_flags});
++type_freq_map_[RDB_TYPE_STRING]; ++type_freq_map_[RDB_TYPE_STRING];
} else { } else {
io::Result<uint8_t> res = serializer->SaveEntry(pk, pv, expire_time, mc_flags, db_indx); io::Result<uint8_t> res = serializer_->SaveEntry(pk, pv, expire_time, mc_flags, db_indx);
CHECK(res); CHECK(res);
++type_freq_map_[*res]; ++type_freq_map_[*res];
} }

View file

@ -98,15 +98,14 @@ class SliceSnapshot {
void SwitchIncrementalFb(LSN lsn); void SwitchIncrementalFb(LSN lsn);
// Called on traversing cursor by IterateBucketsFb. // Called on traversing cursor by IterateBucketsFb.
bool BucketSaveCb(PrimeTable::bucket_iterator it); bool BucketSaveCb(DbIndex db_index, PrimeTable::bucket_iterator it);
// Serialize single bucket. // Serialize single bucket.
// Returns number of serialized entries, updates bucket version to snapshot version. // Returns number of serialized entries, updates bucket version to snapshot version.
unsigned SerializeBucket(DbIndex db_index, PrimeTable::bucket_iterator bucket_it); unsigned SerializeBucket(DbIndex db_index, PrimeTable::bucket_iterator bucket_it);
// Serialize entry into passed serializer. // Serialize entry into passed serializer.
void SerializeEntry(DbIndex db_index, const PrimeKey& pk, const PrimeValue& pv, void SerializeEntry(DbIndex db_index, const PrimeKey& pk, const PrimeValue& pv);
std::optional<uint64_t> expire, RdbSerializer* serializer);
// DbChange listener // DbChange listener
void OnDbChange(DbIndex db_index, const DbSlice::ChangeReq& req); void OnDbChange(DbIndex db_index, const DbSlice::ChangeReq& req);
@ -150,9 +149,7 @@ class SliceSnapshot {
}; };
DbSlice* db_slice_; DbSlice* db_slice_;
DbTableArray db_array_; const DbTableArray db_array_;
DbIndex current_db_;
std::unique_ptr<RdbSerializer> serializer_; std::unique_ptr<RdbSerializer> serializer_;
std::vector<DelayedEntry> delayed_entries_; // collected during atomic bucket traversal std::vector<DelayedEntry> delayed_entries_; // collected during atomic bucket traversal
@ -161,7 +158,7 @@ class SliceSnapshot {
bool serialize_bucket_running_ = false; bool serialize_bucket_running_ = false;
util::fb2::Fiber snapshot_fb_; // IterateEntriesFb util::fb2::Fiber snapshot_fb_; // IterateEntriesFb
util::fb2::CondVarAny seq_cond_; util::fb2::CondVarAny seq_cond_;
CompressionMode compression_mode_; const CompressionMode compression_mode_;
RdbTypeFreqMap type_freq_map_; RdbTypeFreqMap type_freq_map_;
// version upper bound for entries that should be saved (not included). // version upper bound for entries that should be saved (not included).