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

fix: debug object encoding names (#4188)

Signed-off-by: Roman Gershman <roman@dragonflydb.io>
This commit is contained in:
Roman Gershman 2024-11-26 16:11:18 +02:00 committed by GitHub
parent 2f748c24dd
commit f84e1eeac8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 85 additions and 38 deletions

View file

@ -26,26 +26,6 @@ void InitRedisTables() {
server.stream_node_max_entries = 100;
}
const char *strEncoding(int encoding) {
switch(encoding) {
case OBJ_ENCODING_RAW: return "raw";
case OBJ_ENCODING_INT: return "int";
case OBJ_ENCODING_HT: return "hashtable";
case OBJ_ENCODING_ZIPMAP: return "zipmap";
case OBJ_ENCODING_LINKEDLIST: return "linkedlist";
case OBJ_ENCODING_ZIPLIST: return "ziplist";
case OBJ_ENCODING_INTSET: return "intset";
case OBJ_ENCODING_SKIPLIST: return "skiplist";
case OBJ_ENCODING_EMBSTR: return "embstr";
case OBJ_ENCODING_QUICKLIST: return "quicklist";
case OBJ_ENCODING_STREAM: return "stream";
case OBJ_ENCODING_LISTPACK: return "listpack";
case OBJ_ENCODING_COMPRESS_INTERNAL: return "compress_internal";
default: return "unknown";
}
}
/* Toggle the 64 bit unsigned integer pointed by *p from little endian to
* big endian */
void memrev64(void* p) {

View file

@ -28,9 +28,6 @@ extern Server server;
void InitRedisTables();
const char *strEncoding(int encoding);
/* The actual Redis Object */
#define OBJ_STRING 0U /* String object. */
#define OBJ_LIST 1U /* List object. */

View file

@ -57,6 +57,7 @@ struct PopulateBatch {
};
struct ObjInfo {
unsigned type = 0;
unsigned encoding;
unsigned bucket_id = 0;
unsigned slot_id = 0;
@ -309,6 +310,7 @@ ObjInfo InspectOp(ConnectionContext* cntx, string_view key) {
const PrimeValue& pv = it->second;
oinfo.found = true;
oinfo.type = pv.ObjType();
oinfo.encoding = pv.Encoding();
oinfo.bucket_id = it.bucket_id();
oinfo.slot_id = it.slot_id();
@ -365,6 +367,50 @@ OpResult<ValueCompressInfo> EstimateCompression(ConnectionContext* cntx, string_
return info;
};
const char* EncodingName(unsigned obj_type, unsigned encoding) {
switch (obj_type) {
case OBJ_STRING:
return "raw";
case OBJ_LIST:
switch (encoding) {
case kEncodingQL2:
case OBJ_ENCODING_QUICKLIST:
return "quicklist";
}
break;
case OBJ_SET:
ABSL_FALLTHROUGH_INTENDED;
case OBJ_ZSET:
ABSL_FALLTHROUGH_INTENDED;
case OBJ_HASH:
switch (encoding) {
case kEncodingIntSet:
return "intset";
case kEncodingStrMap2:
return "dense_set";
case OBJ_ENCODING_SKIPLIST: // we kept the old enum for zset
return "btree";
case OBJ_ENCODING_LISTPACK:
ABSL_FALLTHROUGH_INTENDED;
case kEncodingListPack:
return "listpack";
}
break;
case OBJ_JSON:
switch (encoding) {
case kEncodingJsonCons:
return "jsoncons";
case kEncodingJsonFlat:
return "jsonflat";
}
break;
case OBJ_STREAM:
return "stream";
default:;
}
return "unknown";
}
} // namespace
DebugCmd::DebugCmd(ServerFamily* owner, cluster::ClusterFamily* cf, ConnectionContext* cntx)
@ -818,7 +864,8 @@ void DebugCmd::Inspect(string_view key, CmdArgList args, facade::SinkReplyBuilde
return;
}
StrAppend(&resp, "encoding:", strEncoding(res.encoding), " bucket_id:", res.bucket_id);
StrAppend(&resp, "encoding:", EncodingName(res.type, res.encoding),
" bucket_id:", res.bucket_id);
StrAppend(&resp, " slot:", res.slot_id, " shard:", sid);
if (res.ttl != INT64_MAX) {

View file

@ -783,6 +783,25 @@ TEST_F(DflyEngineTest, MemoryUsage) {
EXPECT_GT(*resp.GetInt(), 100000);
}
TEST_F(DflyEngineTest, DebugObject) {
Run({"set", "key", "value"});
Run({"lpush", "l1", "a", "b"});
Run({"sadd", "s1", "1", "2", "3"});
Run({"sadd", "s2", "a", "b", "c"});
Run({"zadd", "z1", "1", "a", "2", "b", "3", "c"});
Run({"hset", "h1", "a", "1", "b", "2", "c", "3"});
auto resp = Run({"debug", "object", "key"});
EXPECT_THAT(resp.GetString(), HasSubstr("encoding:raw"));
resp = Run({"debug", "object", "l1"});
EXPECT_THAT(resp.GetString(), HasSubstr("encoding:quicklist"));
resp = Run({"debug", "object", "s1"});
EXPECT_THAT(resp.GetString(), HasSubstr("encoding:intset"));
resp = Run({"debug", "object", "s2"});
EXPECT_THAT(resp.GetString(), HasSubstr("encoding:dense_set"));
resp = Run({"debug", "object", "z1"});
EXPECT_THAT(resp.GetString(), HasSubstr("encoding:listpack"));
}
// TODO: to test transactions with a single shard since then all transactions become local.
// To consider having a parameter in dragonfly engine controlling number of shards
// unconditionally from number of cpus. TO TEST BLPOP under multi for single/multi argument case.

View file

@ -129,13 +129,17 @@ zlexrangespec GetLexRange(bool reverse, const ZSetFamily::LexInterval& li) {
return range;
}
bool IsListPack(const detail::RobjWrapper* robj_wrapper) {
return robj_wrapper->encoding() == OBJ_ENCODING_LISTPACK;
}
/* Delete the element 'ele' from the sorted set, returning 1 if the element
* existed and was deleted, 0 otherwise (the element was not there).
* taken from t_zset.c
*/
int ZsetDel(detail::RobjWrapper* robj_wrapper, sds ele) {
if (robj_wrapper->encoding() == OBJ_ENCODING_LISTPACK) {
if (IsListPack(robj_wrapper)) {
unsigned char* eptr;
uint8_t* lp = (uint8_t*)robj_wrapper->inner_obj();
if ((eptr = zzlFind(lp, ele, NULL)) != NULL) {
@ -153,7 +157,7 @@ int ZsetDel(detail::RobjWrapper* robj_wrapper, sds ele) {
// taken from t_zset.c
std::optional<double> GetZsetScore(const detail::RobjWrapper* robj_wrapper, sds member) {
if (robj_wrapper->encoding() == OBJ_ENCODING_LISTPACK) {
if (IsListPack(robj_wrapper)) {
double score;
if (zzlFind((uint8_t*)robj_wrapper->inner_obj(), member, &score) == NULL)
return std::nullopt;
@ -429,7 +433,7 @@ void IntervalVisitor::ActionRange(unsigned start, unsigned end) {
}
void IntervalVisitor::ActionRange(const zrangespec& range) {
if (robj_wrapper_->encoding() == OBJ_ENCODING_LISTPACK) {
if (IsListPack(robj_wrapper_)) {
ExtractListPack(range);
} else {
CHECK_EQ(robj_wrapper_->encoding(), OBJ_ENCODING_SKIPLIST);
@ -438,7 +442,7 @@ void IntervalVisitor::ActionRange(const zrangespec& range) {
}
void IntervalVisitor::ActionRange(const zlexrangespec& range) {
if (robj_wrapper_->encoding() == OBJ_ENCODING_LISTPACK) {
if (IsListPack(robj_wrapper_)) {
ExtractListPack(range);
} else {
CHECK_EQ(robj_wrapper_->encoding(), OBJ_ENCODING_SKIPLIST);
@ -447,7 +451,7 @@ void IntervalVisitor::ActionRange(const zlexrangespec& range) {
}
void IntervalVisitor::ActionRem(unsigned start, unsigned end) {
if (robj_wrapper_->encoding() == OBJ_ENCODING_LISTPACK) {
if (IsListPack(robj_wrapper_)) {
uint8_t* zl = (uint8_t*)robj_wrapper_->inner_obj();
removed_ = (end - start) + 1;
@ -461,7 +465,7 @@ void IntervalVisitor::ActionRem(unsigned start, unsigned end) {
}
void IntervalVisitor::ActionRem(const zrangespec& range) {
if (robj_wrapper_->encoding() == OBJ_ENCODING_LISTPACK) {
if (IsListPack(robj_wrapper_)) {
uint8_t* zl = (uint8_t*)robj_wrapper_->inner_obj();
unsigned long deleted = 0;
zl = zzlDeleteRangeByScore(zl, &range, &deleted);
@ -475,7 +479,7 @@ void IntervalVisitor::ActionRem(const zrangespec& range) {
}
void IntervalVisitor::ActionRem(const zlexrangespec& range) {
if (robj_wrapper_->encoding() == OBJ_ENCODING_LISTPACK) {
if (IsListPack(robj_wrapper_)) {
uint8_t* zl = (uint8_t*)robj_wrapper_->inner_obj();
unsigned long deleted = 0;
zl = zzlDeleteRangeByLex(zl, &range, &deleted);
@ -490,7 +494,7 @@ void IntervalVisitor::ActionRem(const zlexrangespec& range) {
void IntervalVisitor::ActionPop(ZSetFamily::TopNScored sc) {
if (sc > 0) {
if (robj_wrapper_->encoding() == OBJ_ENCODING_LISTPACK) {
if (IsListPack(robj_wrapper_)) {
PopListPack(sc);
} else {
CHECK_EQ(robj_wrapper_->encoding(), OBJ_ENCODING_SKIPLIST);
@ -984,7 +988,7 @@ OpResult<AddResult> OpAdd(const OpArgs& op_args, const ZParams& zparams, string_
OpStatus op_status = OpStatus::OK;
AddResult aresult;
detail::RobjWrapper* robj_wrapper = res_it->it->second.GetRobjWrapper();
bool is_list_pack = robj_wrapper->encoding() == OBJ_ENCODING_LISTPACK;
bool is_list_pack = IsListPack(robj_wrapper);
// opportunistically reserve space if multiple entries are about to be added.
if ((zparams.flags & ZADD_IN_XX) == 0 && members.size() > 2) {
@ -1027,7 +1031,7 @@ OpResult<AddResult> OpAdd(const OpArgs& op_args, const ZParams& zparams, string_
}
// if we migrated to skip_list - update listpack stats.
if (is_list_pack && robj_wrapper->encoding() != OBJ_ENCODING_LISTPACK) {
if (is_list_pack && !IsListPack(robj_wrapper)) {
DbTableStats* stats = db_slice.MutableStats(op_args.db_cntx.db_index);
--stats->listpack_blob_cnt;
}
@ -1399,7 +1403,7 @@ OpResult<RankResult> OpRank(const OpArgs& op_args, string_view key, string_view
return res_it.status();
const detail::RobjWrapper* robj_wrapper = res_it.value()->second.GetRobjWrapper();
if (robj_wrapper->encoding() == OBJ_ENCODING_LISTPACK) {
if (IsListPack(robj_wrapper)) {
unsigned char* zl = (uint8_t*)robj_wrapper->inner_obj();
unsigned char *eptr, *sptr;
@ -1462,7 +1466,7 @@ OpResult<unsigned> OpCount(const OpArgs& op_args, std::string_view key,
zrangespec range = GetZrangeSpec(false, interval);
unsigned count = 0;
if (robj_wrapper->encoding() == OBJ_ENCODING_LISTPACK) {
if (IsListPack(robj_wrapper)) {
uint8_t* zl = (uint8_t*)robj_wrapper->inner_obj();
uint8_t *eptr, *sptr;
double score;
@ -1512,7 +1516,7 @@ OpResult<unsigned> OpLexCount(const OpArgs& op_args, string_view key,
unsigned count = 0;
const detail::RobjWrapper* robj_wrapper = res_it.value()->second.GetRobjWrapper();
if (robj_wrapper->encoding() == OBJ_ENCODING_LISTPACK) {
if (IsListPack(robj_wrapper)) {
uint8_t* zl = (uint8_t*)robj_wrapper->inner_obj();
uint8_t *eptr, *sptr;
@ -1614,7 +1618,7 @@ OpResult<StringVec> OpScan(const OpArgs& op_args, std::string_view key, uint64_t
StringVec res;
char buf[128];
if (pv.Encoding() == OBJ_ENCODING_LISTPACK) {
if (IsListPack(pv.GetRobjWrapper())) {
ZSetFamily::RangeParams params;
params.with_scores = true;
IntervalVisitor iv{Action::RANGE, params, const_cast<PrimeValue*>(&pv)};