Fix size() bug in dashtable
add more stats to info command fix warnings in -O3 mode.
This commit is contained in:
parent
f4cfce143c
commit
7a839b6081
|
@ -411,9 +411,11 @@ size_t DashTable<_Key, _Value, Policy>::Erase(const Key_t& key) {
|
|||
auto it = target->FindIt(key, key_hash, EqPred());
|
||||
if (!it.found())
|
||||
return 0;
|
||||
|
||||
policy_.DestroyKey(target->Key(it.index, it.slot));
|
||||
policy_.DestroyValue(target->Value(it.index, it.slot));
|
||||
target->Delete(it, key_hash);
|
||||
--size_;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -428,6 +430,7 @@ void DashTable<_Key, _Value, Policy>::Erase(iterator it) {
|
|||
policy_.DestroyValue(it->second);
|
||||
|
||||
target->Delete(sit, key_hash);
|
||||
--size_;
|
||||
}
|
||||
|
||||
template <typename _Key, typename _Value, typename Policy>
|
||||
|
|
|
@ -355,8 +355,11 @@ TEST_F(DashTest, Insert) {
|
|||
Dash64::const_iterator it = dt_.Find(i);
|
||||
ASSERT_TRUE(it == dt_.end());
|
||||
}
|
||||
EXPECT_EQ(kNumItems, dt_.size());
|
||||
EXPECT_EQ(1, dt_.Erase(0));
|
||||
EXPECT_EQ(0, dt_.Erase(0));
|
||||
EXPECT_EQ(kNumItems - 1, dt_.size());
|
||||
|
||||
auto it = dt_.begin();
|
||||
ASSERT_FALSE(it.is_done());
|
||||
auto some_val = it->second;
|
||||
|
|
|
@ -1375,7 +1375,8 @@ void lpRandomPair(unsigned char *lp, unsigned long total_count, listpackEntry *k
|
|||
|
||||
/* Generate even numbers, because listpack saved K-V pair */
|
||||
int r = (rand() % total_count) * 2;
|
||||
assert((p = lpSeek(lp, r)));
|
||||
p = lpSeek(lp, r);
|
||||
assert(p);
|
||||
key->sval = lpGetValue(p, &(key->slen), &(key->lval));
|
||||
|
||||
if (!val)
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
#include "config.h"
|
||||
#include "listpack.h"
|
||||
#include "util.h" /* for ll2string */
|
||||
#include "lzf.h"
|
||||
#include "lzfP.h"
|
||||
|
||||
|
||||
#ifndef REDIS_STATIC
|
||||
|
@ -224,10 +224,13 @@ REDIS_STATIC int __quicklistCompressNode(quicklistNode *node) {
|
|||
return 0;
|
||||
|
||||
quicklistLZF *lzf = zmalloc(sizeof(*lzf) + node->sz);
|
||||
|
||||
// TODO: roman - to move out of stack.
|
||||
LZF_STATE sdata;
|
||||
|
||||
/* Cancel if compression fails or doesn't compress small enough */
|
||||
if (((lzf->sz = lzf_compress(node->entry, node->sz, lzf->compressed,
|
||||
node->sz)) == 0) ||
|
||||
node->sz, sdata)) == 0) ||
|
||||
lzf->sz + MIN_COMPRESS_IMPROVE >= node->sz) {
|
||||
/* lzf_compress aborts/rejects compression if value not compressible. */
|
||||
zfree(lzf);
|
||||
|
|
|
@ -250,6 +250,7 @@ sds _sdsMakeRoomFor(sds s, size_t addlen, int greedy) {
|
|||
len = sdslen(s);
|
||||
sh = (char*)s-sdsHdrSize(oldtype);
|
||||
reqlen = newlen = (len+addlen);
|
||||
(void)reqlen;
|
||||
assert(newlen > len); /* Catch size_t overflow */
|
||||
if (greedy == 1) {
|
||||
if (newlen < SDS_MAX_PREALLOC)
|
||||
|
|
|
@ -22,6 +22,28 @@ using namespace boost;
|
|||
using namespace std;
|
||||
using namespace util;
|
||||
|
||||
#define ADD(x) (x) += o.x
|
||||
|
||||
DbStats& DbStats::operator+=(const DbStats& o) {
|
||||
ADD(key_count);
|
||||
ADD(expire_count);
|
||||
ADD(bucket_count);
|
||||
ADD(inline_keys);
|
||||
|
||||
ADD(obj_memory_usage);
|
||||
ADD(table_mem_usage);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
SliceEvents& SliceEvents::operator+=(const SliceEvents& o) {
|
||||
ADD(evicted_entries);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
#undef ADD
|
||||
|
||||
DbSlice::DbSlice(uint32_t index, EngineShard* owner) : shard_id_(index), owner_(owner) {
|
||||
db_arr_.emplace_back();
|
||||
CreateDb(0);
|
||||
|
@ -38,6 +60,25 @@ DbSlice::~DbSlice() {
|
|||
}
|
||||
}
|
||||
|
||||
auto DbSlice::GetStats() const -> Stats {
|
||||
Stats s;
|
||||
s.events = events_;
|
||||
|
||||
for (const auto& db : db_arr_) {
|
||||
if (!db)
|
||||
continue;
|
||||
|
||||
s.db.key_count += db->main_table.size();
|
||||
s.db.bucket_count += db->main_table.bucket_count();
|
||||
s.db.expire_count += db->expire_table.size();
|
||||
s.db.obj_memory_usage += db->stats.obj_memory_usage;
|
||||
s.db.inline_keys += db->stats.inline_keys;
|
||||
s.db.table_mem_usage += (db->main_table.mem_usage() + db->expire_table.mem_usage());
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
void DbSlice::Reserve(DbIndex db_ind, size_t key_size) {
|
||||
ActivateDb(db_ind);
|
||||
|
||||
|
|
|
@ -18,19 +18,64 @@ class ProactorBase;
|
|||
|
||||
namespace dfly {
|
||||
|
||||
struct DbStats {
|
||||
// number of active keys.
|
||||
size_t key_count = 0;
|
||||
|
||||
// number of keys that have expiry deadline.
|
||||
size_t expire_count = 0;
|
||||
|
||||
// number of buckets in dictionary (key capacity)
|
||||
size_t bucket_count = 0;
|
||||
|
||||
// Number of inline keys.
|
||||
size_t inline_keys = 0;
|
||||
|
||||
// Object memory usage besides hash-table capacity.
|
||||
// Applies for any non-inline objects.
|
||||
size_t obj_memory_usage = 0;
|
||||
|
||||
// Memory used by dictionaries.
|
||||
size_t table_mem_usage = 0;
|
||||
|
||||
DbStats& operator+=(const DbStats& o);
|
||||
};
|
||||
|
||||
struct SliceEvents {
|
||||
// Number of eviction events.
|
||||
uint64_t evicted_entries = 0;
|
||||
|
||||
SliceEvents& operator+=(const SliceEvents& o);
|
||||
};
|
||||
|
||||
|
||||
class DbSlice {
|
||||
struct InternalDbStats {
|
||||
// Number of inline keys.
|
||||
uint64_t inline_keys = 0;
|
||||
|
||||
// Object memory usage besides hash-table capacity.
|
||||
// Applies for any non-inline objects.
|
||||
size_t obj_memory_usage = 0;
|
||||
};
|
||||
|
||||
DbSlice(const DbSlice&) = delete;
|
||||
void operator=(const DbSlice&) = delete;
|
||||
|
||||
public:
|
||||
struct Stats {
|
||||
DbStats db;
|
||||
SliceEvents events;
|
||||
};
|
||||
|
||||
DbSlice(uint32_t index, EngineShard* owner);
|
||||
~DbSlice();
|
||||
|
||||
// Activates `db_ind` database if it does not exist (see ActivateDb below).
|
||||
void Reserve(DbIndex db_ind, size_t key_size);
|
||||
|
||||
Stats GetStats() const;
|
||||
|
||||
//! UpdateExpireClock updates the expire clock for this db slice.
|
||||
//! Must be a wall clock so we could replicate it betweeen machines.
|
||||
void UpdateExpireClock(uint64_t now_ms) {
|
||||
|
@ -111,6 +156,8 @@ class DbSlice {
|
|||
|
||||
uint64_t now_ms_ = 0; // Used for expire logic, represents a real clock.
|
||||
|
||||
SliceEvents events_;
|
||||
|
||||
using LockTable = absl::flat_hash_map<std::string, IntentLock>;
|
||||
|
||||
struct DbWrapper {
|
||||
|
|
|
@ -59,6 +59,12 @@ namespace dfly {
|
|||
using namespace std;
|
||||
namespace {
|
||||
|
||||
quicklistEntry QLEntry() {
|
||||
quicklistEntry res{.quicklist = NULL, .node = NULL, .zi = NULL, .value = NULL,
|
||||
.longval = 0, .sz = 0, .offset = 0};
|
||||
return res;
|
||||
}
|
||||
|
||||
quicklist* GetQL(const PrimeValue& mv) {
|
||||
return mv.GetQL();
|
||||
}
|
||||
|
@ -379,7 +385,7 @@ OpResult<string> ListFamily::OpIndex(const OpArgs& op_args, std::string_view key
|
|||
if (!res)
|
||||
return res.status();
|
||||
quicklist* ql = GetQL(res.value()->second);
|
||||
quicklistEntry entry;
|
||||
quicklistEntry entry = QLEntry();
|
||||
quicklistIter* iter = quicklistGetIteratorEntryAtIdx(ql, index, &entry);
|
||||
|
||||
if (!iter)
|
||||
|
|
|
@ -23,6 +23,7 @@ extern "C" {
|
|||
#include "server/main_service.h"
|
||||
#include "server/server_state.h"
|
||||
#include "server/transaction.h"
|
||||
#include "strings/human_readable.h"
|
||||
#include "util/accept_server.h"
|
||||
|
||||
DECLARE_uint32(port);
|
||||
|
@ -125,8 +126,10 @@ Metrics ServerFamily::GetMetrics() const {
|
|||
fibers::mutex mu;
|
||||
|
||||
auto cb = [&](EngineShard* shard) {
|
||||
auto local_stats = shard->db_slice().GetStats();
|
||||
lock_guard<fibers::mutex> lk(mu);
|
||||
|
||||
result.db += local_stats.db;
|
||||
result.conn_stats += *ServerState::tl_connection_stats();
|
||||
};
|
||||
|
||||
|
@ -148,6 +151,13 @@ tcp_port:)";
|
|||
string info = absl::StrCat(kInfo1, FLAGS_port, "\n");
|
||||
|
||||
Metrics m = GetMetrics();
|
||||
absl::StrAppend(&info, "\n# Memory\n");
|
||||
absl::StrAppend(&info, "object_used_memory:", m.db.obj_memory_usage, "\n");
|
||||
absl::StrAppend(&info, "table_used_memory:", m.db.table_mem_usage, "\n");
|
||||
absl::StrAppend(&info, "used_memory_human:",
|
||||
strings::HumanReadableNumBytes(m.db.table_mem_usage + m.db.obj_memory_usage),
|
||||
"\n");
|
||||
|
||||
absl::StrAppend(&info, "\n# Stats\n");
|
||||
absl::StrAppend(&info, "total_commands_processed:", m.conn_stats.command_cnt, "\n");
|
||||
absl::StrAppend(&info, "total_pipelined_commands:", m.conn_stats.pipelined_cmd_cnt, "\n");
|
||||
|
|
|
@ -19,6 +19,9 @@ class CommandRegistry;
|
|||
class Service;
|
||||
|
||||
struct Metrics {
|
||||
DbStats db;
|
||||
SliceEvents events;
|
||||
|
||||
ConnectionStats conn_stats;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue