diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 57da38a7d..7eb8fb73c 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -20,7 +20,7 @@ cxx_test(compact_object_test dfly_core LABELS DFLY) cxx_test(extent_tree_test dfly_core LABELS DFLY) cxx_test(dash_test dfly_core file redis_test_lib DATA testdata/ids.txt LABELS DFLY) cxx_test(interpreter_test dfly_core LABELS DFLY) -cxx_test(lru_test dfly_core LABELS DFLY) + cxx_test(string_set_test dfly_core LABELS DFLY) cxx_test(string_map_test dfly_core LABELS DFLY) cxx_test(sorted_map_test dfly_core redis_test_lib LABELS DFLY) diff --git a/src/core/lru.h b/src/core/lru.h deleted file mode 100644 index 1c923887c..000000000 --- a/src/core/lru.h +++ /dev/null @@ -1,200 +0,0 @@ -// Copyright 2023, DragonflyDB authors. All rights reserved. -// See LICENSE for licensing terms. -// -#pragma once - -#include - -#include - -#include "base/logging.h" -#include "base/pmr/memory_resource.h" - -namespace dfly { - -enum class Position { - kHead, - kTail, -}; - -template class Lru { - struct Node { - const T* data_ptr; - - uint32_t prev; - uint32_t next; - - Node() : prev(0), next(0) { - } - }; - - public: - explicit Lru(uint32_t capacity, PMR_NS::memory_resource* mr) : table_(mr), node_arr_(mr) { - CHECK_GT(capacity, 1u); - node_arr_.reserve(capacity); - } - - // Get prev item. In case item is head return tail. - std::optional GetPrev(const T& data) const; - std::optional GetTail() const; - std::optional GetHead() const; - - void Put(const T& data, Position position = Position::kHead); - bool Remove(const T& data); - - size_t Size() const { - DCHECK_EQ(table_.size(), node_arr_.size()); - return table_.size(); - } - - private: - void MoveToPosition(uint32_t index, Position position); - using AllocatorType = PMR_NS::polymorphic_allocator>; - absl::node_hash_map, std::equal_to<>, AllocatorType> - table_; // map from item to index in node arr - std::vector> node_arr_; - uint32_t head_ = 0; -}; - -template std::optional Lru::GetPrev(const T& data) const { - auto it = table_.find(data); - if (it == table_.end()) { - return std::nullopt; - } - DCHECK_GT(node_arr_.size(), it->second); - const auto& node = node_arr_[it->second]; - - DCHECK_EQ(node.data_ptr, &it->first); - const auto& node_prev = node_arr_[node.prev]; - - return *node_prev.data_ptr; -} - -template std::optional Lru::GetTail() const { - if (table_.size() == 0) { - return std::nullopt; - } - unsigned tail = node_arr_[head_].prev; - return *node_arr_[tail].data_ptr; -} - -template std::optional Lru::GetHead() const { - if (table_.size() == 0) { - return std::nullopt; - } - return *node_arr_[head_].data_ptr; -} - -template void Lru::Put(const T& data, Position position) { - DCHECK_EQ(table_.size(), node_arr_.size()); - auto [it, inserted] = table_.emplace(data, table_.size()); - if (inserted) { - unsigned tail = 0; - if (node_arr_.size() > 0) { - tail = node_arr_[head_].prev; - } - - Node node; - // add new item between head and tail. - node.prev = tail; - node.next = head_; - node_arr_[tail].next = it->second; - node_arr_[head_].prev = it->second; - - node.data_ptr = &(it->first); - node_arr_.push_back(node); - - if (position == Position::kHead) { - head_ = it->second; - } - } else { // not inserted. - MoveToPosition(it->second, position); - } -} - -template bool Lru::Remove(const T& data) { - auto it = table_.find(data); - if (it == table_.end()) { - return false; - } - uint32_t remove_index = it->second; - auto& node = node_arr_[remove_index]; - - // remove from list - node_arr_[node.prev].next = node.next; - node_arr_[node.next].prev = node.prev; - - // remove item from table. - if (remove_index == head_) { - head_ = node.next; - } - table_.erase(it); - - if (table_.size() == remove_index) { - node_arr_.pop_back(); - DCHECK_EQ(table_.size(), node_arr_.size()); - return true; // if the removed item was the last in the node array nothing else to do. - } - - // move last item from node array to the removed index - uint32_t move_index = table_.size(); - auto& node_to_move = node_arr_[move_index]; - it = table_.find(*node_to_move.data_ptr); - CHECK(it != table_.end()); - - it->second = remove_index; - // now update the next and prev to point to it - node_arr_[node_to_move.prev].next = remove_index; - node_arr_[node_to_move.next].prev = remove_index; - - // move the data from the node to the removed node. - node = node_to_move; - node_arr_.pop_back(); - - if (head_ == move_index) { - head_ = remove_index; - } - DCHECK_EQ(table_.size(), node_arr_.size()); - return true; -} - -template void Lru::MoveToPosition(uint32_t index, Position position) { - DCHECK_LT(index, node_arr_.size()); - uint32_t tail = node_arr_[head_].prev; - uint32_t curr_node_index = position == Position::kHead ? head_ : tail; - if (index == curr_node_index) { // the index is already head/tail. nothing to change. - return; - } - - auto& node = node_arr_[index]; - CHECK_NE(node.prev, node.next); - - if (position == Position::kHead && index == tail) { - head_ = index; // just shift the cycle. - return; - } - if (position == Position::kTail && index == head_) { - head_ = node.next; // just shift the cycle. - return; - } - - // remove from list - node_arr_[node.prev].next = node.next; - node_arr_[node.next].prev = node.prev; - - // update node next and prev - node.prev = tail; - node.next = head_; - - // update tail to point to new head - node_arr_[tail].next = index; - - // update last head to point to new head - node_arr_[head_].prev = index; - - if (position == Position::kHead) { - head_ = index; - } -} - -}; // namespace dfly diff --git a/src/core/lru_test.cc b/src/core/lru_test.cc deleted file mode 100644 index 6b1019034..000000000 --- a/src/core/lru_test.cc +++ /dev/null @@ -1,175 +0,0 @@ -// Copyright 2023, DragonflyDB authors. All rights reserved. -// See LICENSE for licensing terms. -// - -#include "core/lru.h" - -#include - -#include "base/gtest.h" -#include "base/logging.h" -#include "core/compact_object.h" -#include "core/mi_memory_resource.h" - -using namespace std; - -namespace dfly { - -class StringLruTest : public ::testing::Test { - protected: - StringLruTest() : mr_(mi_heap_get_backing()), cache_(kSize, &mr_) { - } - - const size_t kSize = 4; - MiMemoryResource mr_; - Lru cache_; -}; - -TEST_F(StringLruTest, PutAndGet) { - cache_.Put("a"); - ASSERT_EQ("a", cache_.GetHead()); - ASSERT_EQ("a", cache_.GetPrev("a")); - ASSERT_EQ("a", cache_.GetTail()); - cache_.Put("a"); - ASSERT_EQ("a", cache_.GetHead()); - ASSERT_EQ("a", cache_.GetTail()); - cache_.Put("b"); - ASSERT_EQ("b", cache_.GetHead()); - ASSERT_EQ("a", cache_.GetTail()); - cache_.Put("c"); - ASSERT_EQ("c", cache_.GetHead()); - ASSERT_EQ("a", cache_.GetTail()); - cache_.Put("d"); - ASSERT_EQ("d", cache_.GetHead()); - ASSERT_EQ("a", cache_.GetTail()); - cache_.Put("a"); - ASSERT_EQ("a", cache_.GetHead()); - ASSERT_EQ("b", cache_.GetTail()); - cache_.Put("e"); - ASSERT_EQ("e", cache_.GetHead()); - ASSERT_EQ("b", cache_.GetTail()); - cache_.Put("f"); - ASSERT_EQ("f", cache_.GetHead()); - ASSERT_EQ("b", cache_.GetTail()); -} - -TEST_F(StringLruTest, PutAndPutTail) { - cache_.Put("a"); - cache_.Put("a"); // a - cache_.Put("b"); // b -> a - cache_.Put("c"); // c -> b -> a - cache_.Put("d"); // d-> c -> b -> a - ASSERT_EQ("a", cache_.GetTail()); - cache_.Put("a"); // a -> d -> c -> b - ASSERT_EQ("b", cache_.GetTail()); - ASSERT_EQ("c", cache_.GetPrev("b")); - ASSERT_EQ("d", cache_.GetPrev("c")); - ASSERT_EQ("b", cache_.GetPrev("a")); - cache_.Put("d", Position::kTail); // a -> c -> b -> d - ASSERT_EQ("d", cache_.GetTail()); - ASSERT_EQ("b", cache_.GetPrev("d")); - ASSERT_EQ("c", cache_.GetPrev("b")); - ASSERT_EQ("a", cache_.GetPrev("c")); - ASSERT_EQ("d", cache_.GetPrev("a")); - cache_.Put("a"); // a -> c -> b -> d - ASSERT_EQ("d", cache_.GetTail()); - cache_.Put("e", Position::kTail); // a -> c -> b -> d -> e - ASSERT_EQ("e", cache_.GetTail()); - ASSERT_EQ("d", cache_.GetPrev("e")); - ASSERT_EQ("b", cache_.GetPrev("d")); - ASSERT_EQ("a", cache_.GetPrev("c")); - ASSERT_EQ("e", cache_.GetPrev("a")); - cache_.Put("e", Position::kTail); // a -> c -> b -> d -> e - ASSERT_EQ("e", cache_.GetTail()); - ASSERT_EQ("d", cache_.GetPrev("e")); - ASSERT_EQ("b", cache_.GetPrev("d")); - ASSERT_EQ("a", cache_.GetPrev("c")); - ASSERT_EQ("e", cache_.GetPrev("a")); -} - -TEST_F(StringLruTest, BumpTest) { - cache_.Put("a"); - cache_.Put("b"); - cache_.Put("c"); - cache_.Put("d"); - ASSERT_EQ("a", cache_.GetTail()); - cache_.Put("c"); - ASSERT_EQ("a", cache_.GetTail()); - ASSERT_EQ("d", cache_.GetPrev("b")); - ASSERT_EQ("c", cache_.GetPrev("d")); -} - -TEST_F(StringLruTest, DifferentOrder) { - for (uint32_t i = 0; i < kSize * 2; ++i) { - cache_.Put(absl::StrCat(i)); - } - ASSERT_EQ("0", cache_.GetTail()); - - for (uint32_t i = kSize; i > 0; --i) { - cache_.Put(absl::StrCat(i)); - } - ASSERT_EQ("0", cache_.GetTail()); - cache_.Put("0"); - ASSERT_EQ("5", cache_.GetTail()); -} - -TEST_F(StringLruTest, Delete) { - cache_.Put("a"); // a - cache_.Put("b"); // b -> a - cache_.Put("c"); // c -> b -> a - cache_.Put("d"); // d-> c -> b -> a - cache_.Put("e"); // e -> d-> c -> b -> a - ASSERT_EQ("e", cache_.GetHead()); - ASSERT_TRUE(cache_.Remove("e")); // d-> c -> b -> a - ASSERT_EQ("d", cache_.GetHead()); - ASSERT_EQ("a", cache_.GetTail()); - ASSERT_EQ("b", cache_.GetPrev("a")); - ASSERT_EQ("c", cache_.GetPrev("b")); - ASSERT_EQ("d", cache_.GetPrev("c")); - ASSERT_EQ("a", cache_.GetPrev("d")); - ASSERT_FALSE(cache_.Remove("e")); // d-> c -> b -> a - - ASSERT_TRUE(cache_.Remove("c")); // d -> b -> a - ASSERT_EQ("d", cache_.GetHead()); - ASSERT_EQ("a", cache_.GetTail()); - ASSERT_EQ("b", cache_.GetPrev("a")); - ASSERT_EQ("d", cache_.GetPrev("b")); - ASSERT_EQ("a", cache_.GetPrev("d")); - cache_.Put("c"); // c -> d -> b -> a - ASSERT_EQ("c", cache_.GetHead()); - ASSERT_EQ("a", cache_.GetTail()); - ASSERT_EQ("b", cache_.GetPrev("a")); - ASSERT_EQ("d", cache_.GetPrev("b")); - ASSERT_EQ("c", cache_.GetPrev("d")); - ASSERT_EQ("a", cache_.GetPrev("c")); - ASSERT_TRUE(cache_.Remove("a")); // c -> d -> b - ASSERT_EQ("b", cache_.GetTail()); - ASSERT_EQ("d", cache_.GetPrev("b")); - ASSERT_EQ("c", cache_.GetPrev("d")); - ASSERT_EQ("b", cache_.GetPrev("c")); -} - -class COVLruTest : public ::testing::Test { - protected: - COVLruTest() : mr_(mi_heap_get_backing()), cache_(kSize, &mr_) { - } - - const size_t kSize = 100; - MiMemoryResource mr_; - Lru cache_; -}; - -TEST_F(COVLruTest, MemoryUsagePrint) { - size_t before = mr_.used(); - std::array obj_arr; - for (int i = 0; i < 100; ++i) { - obj_arr[i].SetString(absl::StrCat(i)); - cache_.Put(obj_arr[i]); - } - - size_t after = mr_.used(); - LOG(INFO) << "CompactObjectView lru 100 items memory : " << absl::StrCat(after - before) - << " bytes"; -} - -} // namespace dfly diff --git a/src/redis/quicklist.c b/src/redis/quicklist.c index 495ab802a..5ba4708b4 100644 --- a/src/redis/quicklist.c +++ b/src/redis/quicklist.c @@ -35,7 +35,6 @@ #include "zmalloc.h" #include "config.h" #include "listpack.h" -#include "util.h" /* for ll2string */ #include "lzfP.h" diff --git a/src/redis/util.c b/src/redis/util.c index 30933d79a..27efbc2ff 100644 --- a/src/redis/util.c +++ b/src/redis/util.c @@ -164,111 +164,6 @@ int stringmatchlen(const char *pattern, int patternLen, return 0; } -int stringmatch(const char *pattern, const char *string, int nocase) { - return stringmatchlen(pattern,strlen(pattern),string,strlen(string),nocase); -} - -/* Fuzz stringmatchlen() trying to crash it with bad input. */ -int stringmatchlen_fuzz_test(void) { - char str[32]; - char pat[32]; - int cycles = 10000000; - int total_matches = 0; - while(cycles--) { - int strlen = rand() % sizeof(str); - int patlen = rand() % sizeof(pat); - for (int j = 0; j < strlen; j++) str[j] = rand() % 128; - for (int j = 0; j < patlen; j++) pat[j] = rand() % 128; - total_matches += stringmatchlen(pat, patlen, str, strlen, 0); - } - return total_matches; -} - -/* Convert a string representing an amount of memory into the number of - * bytes, so for instance memtoll("1Gb") will return 1073741824 that is - * (1024*1024*1024). - * - * On parsing error, if *err is not NULL, it's set to 1, otherwise it's - * set to 0. On error the function return value is 0, regardless of the - * fact 'err' is NULL or not. */ -long long memtoll(const char *p, int *err) { - const char *u; - char buf[128]; - long mul; /* unit multiplier */ - long long val; - unsigned int digits; - - if (err) *err = 0; - - /* Search the first non digit character. */ - u = p; - if (*u == '-') u++; - while(*u && isdigit(*u)) u++; - if (*u == '\0' || !strcasecmp(u,"b")) { - mul = 1; - } else if (!strcasecmp(u,"k")) { - mul = 1000; - } else if (!strcasecmp(u,"kb")) { - mul = 1024; - } else if (!strcasecmp(u,"m")) { - mul = 1000*1000; - } else if (!strcasecmp(u,"mb")) { - mul = 1024*1024; - } else if (!strcasecmp(u,"g")) { - mul = 1000L*1000*1000; - } else if (!strcasecmp(u,"gb")) { - mul = 1024L*1024*1024; - } else { - if (err) *err = 1; - return 0; - } - - /* Copy the digits into a buffer, we'll use strtoll() to convert - * the digit (without the unit) into a number. */ - digits = u-p; - if (digits >= sizeof(buf)) { - if (err) *err = 1; - return 0; - } - memcpy(buf,p,digits); - buf[digits] = '\0'; - - char *endptr; - errno = 0; - val = strtoll(buf,&endptr,10); - if ((val == 0 && errno == EINVAL) || *endptr != '\0') { - if (err) *err = 1; - return 0; - } - return val*mul; -} - -/* Search a memory buffer for any set of bytes, like strpbrk(). - * Returns pointer to first found char or NULL. - */ -const char *mempbrk(const char *s, size_t len, const char *chars, size_t charslen) { - for (size_t j = 0; j < len; j++) { - for (size_t n = 0; n < charslen; n++) - if (s[j] == chars[n]) return &s[j]; - } - - return NULL; -} - -/* Modify the buffer replacing all occurrences of chars from the 'from' - * set with the corresponding char in the 'to' set. Always returns s. - */ -char *memmapchars(char *s, size_t len, const char *from, const char *to, size_t setlen) { - for (size_t j = 0; j < len; j++) { - for (size_t i = 0; i < setlen; i++) { - if (s[j] == from[i]) { - s[j] = to[i]; - break; - } - } - } - return s; -} /* Return the number of digits of 'v' when converted to string in radix 10. * See ll2string() for more information. */ uint32_t digits10(uint64_t v) { @@ -446,42 +341,6 @@ int string2ll(const char *s, size_t slen, long long *value) { return 1; } -/* Helper function to convert a string to an unsigned long long value. - * The function attempts to use the faster string2ll() function inside - * Redis: if it fails, strtoull() is used instead. The function returns - * 1 if the conversion happened successfully or 0 if the number is - * invalid or out of range. */ -int string2ull(const char *s, unsigned long long *value) { - long long ll; - if (string2ll(s,strlen(s),&ll)) { - if (ll < 0) return 0; /* Negative values are out of range. */ - *value = ll; - return 1; - } - errno = 0; - char *endptr = NULL; - *value = strtoull(s,&endptr,10); - if (errno == EINVAL || errno == ERANGE || !(*s != '\0' && *endptr == '\0')) - return 0; /* strtoull() failed. */ - return 1; /* Conversion done! */ -} - -/* Convert a string into a long. Returns 1 if the string could be parsed into a - * (non-overflowing) long, 0 otherwise. The value will be set to the parsed - * value when appropriate. */ -int string2l(const char *s, size_t slen, long *lval) { - long long llval; - - if (!string2ll(s,slen,&llval)) - return 0; - - if (llval < LONG_MIN || llval > LONG_MAX) - return 0; - - *lval = (long)llval; - return 1; -} - /* Convert a string into a double. Returns 1 if the string could be parsed * into a (non-overflowing) double, 0 otherwise. The value will be set to * the parsed value when appropriate. @@ -510,66 +369,4 @@ int string2ld(const char *s, size_t slen, long double *dp) { if (dp) *dp = value; return 1; -} - -/* Create a string object from a long double. - * If mode is humanfriendly it does not use exponential format and trims trailing - * zeroes at the end (may result in loss of precision). - * If mode is default exp format is used and the output of snprintf() - * is not modified (may result in loss of precision). - * If mode is hex hexadecimal format is used (no loss of precision) - * - * The function returns the length of the string or zero if there was not - * enough buffer room to store it. */ -int ld2string(char *buf, size_t len, long double value, ld2string_mode mode) { - size_t l = 0; - - if (isinf(value)) { - /* Libc in odd systems (Hi Solaris!) will format infinite in a - * different way, so better to handle it in an explicit way. */ - if (len < 5) return 0; /* No room. 5 is "-inf\0" */ - if (value > 0) { - memcpy(buf,"inf",3); - l = 3; - } else { - memcpy(buf,"-inf",4); - l = 4; - } - } else { - switch (mode) { - case LD_STR_AUTO: - l = snprintf(buf,len,"%.17Lg",value); - if (l+1 > len) return 0; /* No room. */ - break; - case LD_STR_HEX: - l = snprintf(buf,len,"%La",value); - if (l+1 > len) return 0; /* No room. */ - break; - case LD_STR_HUMAN: - /* We use 17 digits precision since with 128 bit floats that precision - * after rounding is able to represent most small decimal numbers in a - * way that is "non surprising" for the user (that is, most small - * decimal numbers will be represented in a way that when converted - * back into a string are exactly the same as what the user typed.) */ - l = snprintf(buf,len,"%.17Lf",value); - if (l+1 > len) return 0; /* No room. */ - /* Now remove trailing zeroes after the '.' */ - if (strchr(buf,'.') != NULL) { - char *p = buf+l-1; - while(*p == '0') { - p--; - l--; - } - if (*p == '.') l--; - } - if (l == 2 && buf[0] == '-' && buf[1] == '0') { - buf[0] = '0'; - l = 1; - } - break; - default: return 0; /* Invalid mode. */ - } - } - buf[l] = '\0'; - return l; -} +} \ No newline at end of file diff --git a/src/redis/util.h b/src/redis/util.h index 6408619be..d622066f3 100644 --- a/src/redis/util.h +++ b/src/redis/util.h @@ -44,28 +44,12 @@ #define C_OK 0 #define C_ERR -1 -/* long double to string conversion options */ -typedef enum { - LD_STR_AUTO, /* %.17Lg */ - LD_STR_HUMAN, /* %.17Lf + Trimming of trailing zeros */ - LD_STR_HEX /* %La */ -} ld2string_mode; - int stringmatchlen(const char *p, int plen, const char *s, int slen, int nocase); -int stringmatch(const char *p, const char *s, int nocase); -int stringmatchlen_fuzz_test(void); -long long memtoll(const char *p, int *err); -const char *mempbrk(const char *s, size_t len, const char *chars, size_t charslen); -char *memmapchars(char *s, size_t len, const char *from, const char *to, size_t setlen); -uint32_t digits10(uint64_t v); -uint32_t sdigits10(int64_t v); + + int ll2string(char *s, size_t len, long long value); int string2ll(const char *s, size_t slen, long long *value); -int string2ull(const char *s, unsigned long long *value); -int string2l(const char *s, size_t slen, long *value); int string2ld(const char *s, size_t slen, long double *dp); -int d2string(char *buf, size_t len, double value); -int ld2string(char *buf, size_t len, long double value, ld2string_mode mode); #define LOG_MAX_LEN 1024 /* Default maximum length of syslog messages.*/ @@ -77,10 +61,6 @@ int ld2string(char *buf, size_t len, long double value, ld2string_mode mode); #define LL_RAW (1<<10) /* Modifier to log without timestamp */ -#define LRU_BITS 24 -#define LRU_CLOCK_MAX ((1<lru */ -#define LRU_CLOCK_RESOLUTION 1000 /* LRU clock resolution in ms */ - /* Bytes needed for long -> str + '\0' */ #define LONG_STR_SIZE 21 diff --git a/src/server/db_slice.cc b/src/server/db_slice.cc index 8323fc4e5..4e2c57577 100644 --- a/src/server/db_slice.cc +++ b/src/server/db_slice.cc @@ -218,16 +218,6 @@ unsigned PrimeEvictionPolicy::Evict(const PrimeTable::HotspotBuckets& eb, PrimeT return 1; } -// Deprecated and should be removed. -class FetchedItemsRestorer { - public: - template explicit FetchedItemsRestorer(U&& u) { - } - - ~FetchedItemsRestorer() { - } -}; - } // namespace #define ADD(x) (x) += o.x @@ -270,6 +260,24 @@ SliceEvents& SliceEvents::operator+=(const SliceEvents& o) { #undef ADD +class DbSlice::PrimeBumpPolicy { + public: + PrimeBumpPolicy(absl::flat_hash_set* 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* fetched_items_; +}; + DbSlice::DbSlice(uint32_t index, bool cache_mode, EngineShard* owner) : shard_id_(index), cache_mode_(cache_mode), @@ -474,7 +482,6 @@ OpResult DbSlice::FindInternal(const Context& cntx, std: if (IsCacheMode() && IsValid(res.it)) { if (!change_cb_.empty()) { - FetchedItemsRestorer fetched_restorer(&fetched_items_); auto bump_cb = [&](PrimeTable::bucket_iterator bit) { CallChangeCallbacks(cntx.db_index, key, bit); }; @@ -567,8 +574,6 @@ OpResult DbSlice::AddOrFindInternal(const Context& cnt auto status = res.status(); CHECK(status == OpStatus::KEY_NOTFOUND || status == OpStatus::OUT_OF_MEMORY) << status; - FetchedItemsRestorer fetched_restorer(&fetched_items_); - // It's a new entry. CallChangeCallbacks(cntx.db_index, key, {key}); @@ -1059,7 +1064,6 @@ bool DbSlice::CheckLock(IntentLock::Mode mode, DbIndex dbid, uint64_t fp) const } void DbSlice::PreUpdate(DbIndex db_ind, Iterator it, std::string_view key) { - FetchedItemsRestorer fetched_restorer(&fetched_items_); CallChangeCallbacks(db_ind, key, ChangeReq{it.GetInnerIt()}); it.GetInnerIt().SetVersion(NextVersion()); } @@ -1178,8 +1182,7 @@ uint64_t DbSlice::RegisterOnChange(ChangeCallback cb) { } void DbSlice::FlushChangeToEarlierCallbacks(DbIndex db_ind, Iterator it, uint64_t upper_bound) { - FetchedItemsRestorer fetched_restorer(&fetched_items_); - std::unique_lock lk(block_counter_); + unique_lock lk(block_counter_); uint64_t bucket_version = it.GetVersion(); // change_cb_ is ordered by version. diff --git a/src/server/db_slice.h b/src/server/db_slice.h index 55458cfe1..0cae9d6f0 100644 --- a/src/server/db_slice.h +++ b/src/server/db_slice.h @@ -657,23 +657,7 @@ class DbSlice { absl::container_internal::hash_default_eq, AllocatorType> client_tracking_map_; - class PrimeBumpPolicy { - public: - PrimeBumpPolicy(absl::flat_hash_set* 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* fetched_items_; - }; + class PrimeBumpPolicy; }; inline bool IsValid(const DbSlice::Iterator& it) {