1
0
Fork 0
mirror of https://github.com/dragonflydb/dragonfly.git synced 2024-12-14 11:58:02 +00:00

Simplify cursor encoding and state clearly cursor valid range

This commit is contained in:
Roman Gershman 2022-01-24 01:07:13 +02:00
parent ec91b2c026
commit b2953293cd
3 changed files with 11 additions and 5 deletions

View file

@ -283,6 +283,7 @@ class DashTable : public detail::DashTableBase {
// before returning. Unlike begin/end interface, traverse is more stable during table mutations.
// It guarantees that if key exists at the beginning of traversal, stays in the table during the
// traversal, it will eventually reach it even when the table shrinks or grows.
// Returns: cursor that is guaranteed to be less than 2^40.
template <typename Cb> uint64_t Traverse(uint64_t cursor, Cb&& cb);
// Takes an iterator pointing to an entry in a dash bucket and traverses all bucket's entries by
@ -376,9 +377,13 @@ template <typename _Key, typename _Value, typename Policy>
template <typename U>
auto DashTable<_Key, _Value, Policy>::Find(U&& key) const -> const_iterator {
uint64_t key_hash = DoHash(key);
size_t seg_id = SegmentId(key_hash);
size_t seg_id = SegmentId(key_hash); // seg_id takes up global_depth_ high bits.
const auto* target = segment_[seg_id];
// Hash structure is like this: [SSUUUUBF], where S is segment id, U - unused,
// B - bucket id and F is a fingerprint. Segment id is needed to identify the correct segment.
// Once identified, the segment instance uses the lower part of hash to locate the key.
// It uses 8 least significant bits for a fingerprint and few more bits for bucket id.
auto seg_it = target->FindIt(key, key_hash, EqPred());
if (seg_it.found()) {
@ -548,12 +553,12 @@ void DashTable<_Key, _Value, Policy>::Split(uint32_t seg_id) {
template <typename _Key, typename _Value, typename Policy>
template <typename Cb>
uint64_t DashTable<_Key, _Value, Policy>::Traverse(uint64_t cursor, Cb&& cb) {
unsigned bid = (cursor >> 8) & 0xFF;
unsigned bid = cursor & 0xFF;
if (bid >= kLogicalBucketNum) // sanity.
return 0;
uint32_t sid = SegmentId(cursor);
uint32_t sid = cursor >> (40 - global_depth_);
auto hash_fun = [this](const auto& k) { return policy_.HashFn(k); };
bool fetched = false;
@ -574,7 +579,7 @@ uint64_t DashTable<_Key, _Value, Policy>::Traverse(uint64_t cursor, Cb&& cb) {
}
} while (!fetched);
return (uint64_t(sid) << (64 - global_depth_)) | (bid << 8);
return (uint64_t(sid) << (40 - global_depth_)) | bid;
}
template <typename _Key, typename _Value, typename Policy>

View file

@ -533,6 +533,7 @@ class DashTableBase {
uint32_t unique_segments() const {
return unique_segments_;
}
uint32_t depth() const {
return global_depth_;
}

View file

@ -381,7 +381,7 @@ TEST_F(DashTest, Traverse) {
}
uint64_t cursor = 0;
vector<unsigned> nums;
auto tr_cb = [&](const Dash64::iterator& it) {
auto tr_cb = [&](Dash64::iterator it) {
nums.push_back(it->first);
VLOG(1) << it.bucket_id() << " " << it.slot_id() << " " << it->first;
};