chore: remove unused code (#4516)

Move PrimeBumpPolicy definition to cc file.

Signed-off-by: Roman Gershman <roman@dragonflydb.io>
This commit is contained in:
Roman Gershman 2025-01-28 10:41:11 +02:00 committed by GitHub
parent d945b831db
commit 44506ad2a9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 24 additions and 636 deletions

View file

@ -20,7 +20,7 @@ cxx_test(compact_object_test dfly_core LABELS DFLY)
cxx_test(extent_tree_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(dash_test dfly_core file redis_test_lib DATA testdata/ids.txt LABELS DFLY)
cxx_test(interpreter_test dfly_core 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_set_test dfly_core LABELS DFLY)
cxx_test(string_map_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) cxx_test(sorted_map_test dfly_core redis_test_lib LABELS DFLY)

View file

@ -1,200 +0,0 @@
// Copyright 2023, DragonflyDB authors. All rights reserved.
// See LICENSE for licensing terms.
//
#pragma once
#include <absl/container/node_hash_map.h>
#include <optional>
#include "base/logging.h"
#include "base/pmr/memory_resource.h"
namespace dfly {
enum class Position {
kHead,
kTail,
};
template <typename T> 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<T> GetPrev(const T& data) const;
std::optional<T> GetTail() const;
std::optional<T> 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<std::pair<T, uint32_t>>;
absl::node_hash_map<T, uint32_t, absl::Hash<T>, std::equal_to<>, AllocatorType>
table_; // map from item to index in node arr
std::vector<Node, PMR_NS::polymorphic_allocator<Node>> node_arr_;
uint32_t head_ = 0;
};
template <typename T> std::optional<T> Lru<T>::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 <typename T> std::optional<T> Lru<T>::GetTail() const {
if (table_.size() == 0) {
return std::nullopt;
}
unsigned tail = node_arr_[head_].prev;
return *node_arr_[tail].data_ptr;
}
template <typename T> std::optional<T> Lru<T>::GetHead() const {
if (table_.size() == 0) {
return std::nullopt;
}
return *node_arr_[head_].data_ptr;
}
template <typename T> void Lru<T>::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 <typename T> bool Lru<T>::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 <typename T> void Lru<T>::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

View file

@ -1,175 +0,0 @@
// Copyright 2023, DragonflyDB authors. All rights reserved.
// See LICENSE for licensing terms.
//
#include "core/lru.h"
#include <absl/strings/str_cat.h>
#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<std::string> 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<CompactObjectView> cache_;
};
TEST_F(COVLruTest, MemoryUsagePrint) {
size_t before = mr_.used();
std::array<CompactObj, 100> 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

View file

@ -35,7 +35,6 @@
#include "zmalloc.h" #include "zmalloc.h"
#include "config.h" #include "config.h"
#include "listpack.h" #include "listpack.h"
#include "util.h" /* for ll2string */
#include "lzfP.h" #include "lzfP.h"

View file

@ -164,111 +164,6 @@ int stringmatchlen(const char *pattern, int patternLen,
return 0; 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. /* Return the number of digits of 'v' when converted to string in radix 10.
* See ll2string() for more information. */ * See ll2string() for more information. */
uint32_t digits10(uint64_t v) { uint32_t digits10(uint64_t v) {
@ -446,42 +341,6 @@ int string2ll(const char *s, size_t slen, long long *value) {
return 1; 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 /* 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 * into a (non-overflowing) double, 0 otherwise. The value will be set to
* the parsed value when appropriate. * the parsed value when appropriate.
@ -510,66 +369,4 @@ int string2ld(const char *s, size_t slen, long double *dp) {
if (dp) *dp = value; if (dp) *dp = value;
return 1; 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;
}

View file

@ -44,28 +44,12 @@
#define C_OK 0 #define C_OK 0
#define C_ERR -1 #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 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 ll2string(char *s, size_t len, long long value);
int string2ll(const char *s, size_t slen, 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 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.*/ #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 LL_RAW (1<<10) /* Modifier to log without timestamp */
#define LRU_BITS 24
#define LRU_CLOCK_MAX ((1<<LRU_BITS)-1) /* Max value of obj->lru */
#define LRU_CLOCK_RESOLUTION 1000 /* LRU clock resolution in ms */
/* Bytes needed for long -> str + '\0' */ /* Bytes needed for long -> str + '\0' */
#define LONG_STR_SIZE 21 #define LONG_STR_SIZE 21

View file

@ -218,16 +218,6 @@ unsigned PrimeEvictionPolicy::Evict(const PrimeTable::HotspotBuckets& eb, PrimeT
return 1; return 1;
} }
// Deprecated and should be removed.
class FetchedItemsRestorer {
public:
template <typename U> explicit FetchedItemsRestorer(U&& u) {
}
~FetchedItemsRestorer() {
}
};
} // namespace } // namespace
#define ADD(x) (x) += o.x #define ADD(x) (x) += o.x
@ -270,6 +260,24 @@ SliceEvents& SliceEvents::operator+=(const SliceEvents& o) {
#undef ADD #undef ADD
class DbSlice::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_;
};
DbSlice::DbSlice(uint32_t index, bool cache_mode, EngineShard* owner) DbSlice::DbSlice(uint32_t index, bool cache_mode, EngineShard* owner)
: shard_id_(index), : shard_id_(index),
cache_mode_(cache_mode), cache_mode_(cache_mode),
@ -474,7 +482,6 @@ OpResult<DbSlice::PrimeItAndExp> DbSlice::FindInternal(const Context& cntx, std:
if (IsCacheMode() && IsValid(res.it)) { if (IsCacheMode() && IsValid(res.it)) {
if (!change_cb_.empty()) { if (!change_cb_.empty()) {
FetchedItemsRestorer fetched_restorer(&fetched_items_);
auto bump_cb = [&](PrimeTable::bucket_iterator bit) { auto bump_cb = [&](PrimeTable::bucket_iterator bit) {
CallChangeCallbacks(cntx.db_index, key, bit); CallChangeCallbacks(cntx.db_index, key, bit);
}; };
@ -567,8 +574,6 @@ OpResult<DbSlice::AddOrFindResult> DbSlice::AddOrFindInternal(const Context& cnt
auto status = res.status(); auto status = res.status();
CHECK(status == OpStatus::KEY_NOTFOUND || status == OpStatus::OUT_OF_MEMORY) << status; CHECK(status == OpStatus::KEY_NOTFOUND || status == OpStatus::OUT_OF_MEMORY) << status;
FetchedItemsRestorer fetched_restorer(&fetched_items_);
// It's a new entry. // It's a new entry.
CallChangeCallbacks(cntx.db_index, key, {key}); 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) { void DbSlice::PreUpdate(DbIndex db_ind, Iterator it, std::string_view key) {
FetchedItemsRestorer fetched_restorer(&fetched_items_);
CallChangeCallbacks(db_ind, key, ChangeReq{it.GetInnerIt()}); CallChangeCallbacks(db_ind, key, ChangeReq{it.GetInnerIt()});
it.GetInnerIt().SetVersion(NextVersion()); 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) { void DbSlice::FlushChangeToEarlierCallbacks(DbIndex db_ind, Iterator it, uint64_t upper_bound) {
FetchedItemsRestorer fetched_restorer(&fetched_items_); unique_lock<LocalBlockingCounter> lk(block_counter_);
std::unique_lock<LocalBlockingCounter> lk(block_counter_);
uint64_t bucket_version = it.GetVersion(); uint64_t bucket_version = it.GetVersion();
// change_cb_ is ordered by version. // change_cb_ is ordered by version.

View file

@ -657,23 +657,7 @@ class DbSlice {
absl::container_internal::hash_default_eq<std::string>, AllocatorType> absl::container_internal::hash_default_eq<std::string>, AllocatorType>
client_tracking_map_; client_tracking_map_;
class PrimeBumpPolicy { 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) { inline bool IsValid(const DbSlice::Iterator& it) {