Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: simplify BumpUps deduplication #4098

Merged
merged 2 commits into from
Nov 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 4 additions & 27 deletions src/server/db_slice.cc
Original file line number Diff line number Diff line change
Expand Up @@ -118,20 +118,6 @@ class PrimeEvictionPolicy {
const bool apply_memory_limit_;
};

class PrimeBumpPolicy {
public:
PrimeBumpPolicy(const absl::flat_hash_set<CompactObjectView>& fetched_items)
: fetched_items_(fetched_items) {
}
// returns true if we can change the object location in dash table.
bool CanBump(const CompactObj& obj) const {
return !obj.IsSticky() && !fetched_items_.contains(obj);
}

private:
const absl::flat_hash_set<CompactObjectView>& fetched_items_;
};

bool PrimeEvictionPolicy::CanGrow(const PrimeTable& tbl) const {
ssize_t mem_available = db_slice_->memory_budget() + mem_offset_;
if (!apply_memory_limit_ || mem_available > soft_limit_)
Expand Down Expand Up @@ -217,22 +203,14 @@ unsigned PrimeEvictionPolicy::Evict(const PrimeTable::HotspotBuckets& eb, PrimeT
return 1;
}

// Helper class to cache and restore fetched_items_ of DbSlice for flows that preempt
// because some other transaction might conclude and clear the fetched_items_ with OnCbFinish()
// Deprecated and should be removed.
class FetchedItemsRestorer {
public:
using RestoreType = absl::flat_hash_set<CompactObjectView>;
explicit FetchedItemsRestorer(RestoreType* dst) : dst_to_restore_(dst) {
cached_ = std::move(*dst_to_restore_);
template <typename U> explicit FetchedItemsRestorer(U&& u) {
}

~FetchedItemsRestorer() {
*dst_to_restore_ = std::move(cached_);
}

private:
RestoreType cached_;
RestoreType* dst_to_restore_;
};

} // namespace
Expand Down Expand Up @@ -487,12 +465,12 @@ OpResult<DbSlice::PrimeItAndExp> DbSlice::FindInternal(const Context& cntx, std:
};
db.prime.CVCUponBump(change_cb_.back().first, res.it, bump_cb);
}
auto bump_it = db.prime.BumpUp(res.it, PrimeBumpPolicy{fetched_items_});

auto bump_it = db.prime.BumpUp(res.it, PrimeBumpPolicy{&fetched_items_});
if (bump_it != res.it) { // the item was bumped
res.it = bump_it;
++events_.bumpups;
}
fetched_items_.insert(res.it->first.AsRef());
}

std::move(update_stats_on_miss).Cancel();
Expand Down Expand Up @@ -704,7 +682,6 @@ bool DbSlice::Del(Context cntx, Iterator it) {
string_view key = it->first.GetSlice(&tmp);
doc_del_cb_(key, cntx, it->second);
}
fetched_items_.erase(it->first.AsRef());
PerformDeletion(it, db.get());

return true;
Expand Down
35 changes: 33 additions & 2 deletions src/server/db_slice.h
Original file line number Diff line number Diff line change
Expand Up @@ -592,14 +592,27 @@ class DbSlice {

DbTableArray db_arr_;

struct FpHasher {
size_t operator()(uint64_t val) const {
return val;
}
};

Comment on lines +595 to +600
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not use the default hasher?
(I get that this is not the core of this draft PR, still I'm curious :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default one hashes :)
I find it redundant for keys that are already mixed (results of a hash function )

// Used in temporary computations in Acquire/Release.
mutable absl::flat_hash_set<uint64_t> uniq_fps_;
mutable absl::flat_hash_set<uint64_t, FpHasher> uniq_fps_;

// ordered from the smallest to largest version.
std::list<std::pair<uint64_t, ChangeCallback>> change_cb_;

// Used in temporary computations in Find item and CbFinish
mutable absl::flat_hash_set<CompactObjectView> fetched_items_;
// This set is used to hold fingerprints of key accessed during the run of
// a transaction callback (not the whole transaction).
// We track them to avoid bumping them again (in any direction) so that the iterators to
// the fetched keys will not be invalidated. We must do it for atomic operations,
// for operations that preempt in the middle we have another mechanism -
// auto laundering iterators, so in case of preemption we do not mind that fetched_items are
// cleared or changed.
mutable absl::flat_hash_set<uint64_t, FpHasher> fetched_items_;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets add a comment why we need this hashset , why we can not bumpup item twice in transaction without preemption but ok to to bumpup twice when we do preempt

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

expect this comment the changes looks ok and we can merge


// Registered by shard indices on when first document index is created.
DocDeletionCallback doc_del_cb_;
Expand Down Expand Up @@ -632,6 +645,24 @@ class DbSlice {
absl::container_internal::hash_default_hash<std::string>,
absl::container_internal::hash_default_eq<std::string>, AllocatorType>
client_tracking_map_;

class PrimeBumpPolicy {
public:
PrimeBumpPolicy(absl::flat_hash_set<uint64_t, FpHasher>* items) : fetched_items_(items) {
}

// returns true if we can change the object location in dash table.
bool CanBump(const CompactObj& obj) const {
if (obj.IsSticky()) {
return false;
}
auto hc = obj.HashCode();
return fetched_items_->insert(hc).second;
}

private:
mutable absl::flat_hash_set<uint64_t, FpHasher>* fetched_items_;
};
};

inline bool IsValid(const DbSlice::Iterator& it) {
Expand Down
Loading