mirror of
https://github.com/dragonflydb/dragonfly.git
synced 2025-05-10 18:05:44 +02:00
fix: debug object encoding names (#4188)
Signed-off-by: Roman Gershman <roman@dragonflydb.io>
This commit is contained in:
parent
2f748c24dd
commit
f84e1eeac8
5 changed files with 85 additions and 38 deletions
|
@ -26,26 +26,6 @@ void InitRedisTables() {
|
||||||
server.stream_node_max_entries = 100;
|
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
|
/* Toggle the 64 bit unsigned integer pointed by *p from little endian to
|
||||||
* big endian */
|
* big endian */
|
||||||
void memrev64(void* p) {
|
void memrev64(void* p) {
|
||||||
|
|
|
@ -28,9 +28,6 @@ extern Server server;
|
||||||
|
|
||||||
void InitRedisTables();
|
void InitRedisTables();
|
||||||
|
|
||||||
const char *strEncoding(int encoding);
|
|
||||||
|
|
||||||
|
|
||||||
/* The actual Redis Object */
|
/* The actual Redis Object */
|
||||||
#define OBJ_STRING 0U /* String object. */
|
#define OBJ_STRING 0U /* String object. */
|
||||||
#define OBJ_LIST 1U /* List object. */
|
#define OBJ_LIST 1U /* List object. */
|
||||||
|
|
|
@ -57,6 +57,7 @@ struct PopulateBatch {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ObjInfo {
|
struct ObjInfo {
|
||||||
|
unsigned type = 0;
|
||||||
unsigned encoding;
|
unsigned encoding;
|
||||||
unsigned bucket_id = 0;
|
unsigned bucket_id = 0;
|
||||||
unsigned slot_id = 0;
|
unsigned slot_id = 0;
|
||||||
|
@ -309,6 +310,7 @@ ObjInfo InspectOp(ConnectionContext* cntx, string_view key) {
|
||||||
const PrimeValue& pv = it->second;
|
const PrimeValue& pv = it->second;
|
||||||
|
|
||||||
oinfo.found = true;
|
oinfo.found = true;
|
||||||
|
oinfo.type = pv.ObjType();
|
||||||
oinfo.encoding = pv.Encoding();
|
oinfo.encoding = pv.Encoding();
|
||||||
oinfo.bucket_id = it.bucket_id();
|
oinfo.bucket_id = it.bucket_id();
|
||||||
oinfo.slot_id = it.slot_id();
|
oinfo.slot_id = it.slot_id();
|
||||||
|
@ -365,6 +367,50 @@ OpResult<ValueCompressInfo> EstimateCompression(ConnectionContext* cntx, string_
|
||||||
return info;
|
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
|
} // namespace
|
||||||
|
|
||||||
DebugCmd::DebugCmd(ServerFamily* owner, cluster::ClusterFamily* cf, ConnectionContext* cntx)
|
DebugCmd::DebugCmd(ServerFamily* owner, cluster::ClusterFamily* cf, ConnectionContext* cntx)
|
||||||
|
@ -818,7 +864,8 @@ void DebugCmd::Inspect(string_view key, CmdArgList args, facade::SinkReplyBuilde
|
||||||
return;
|
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);
|
StrAppend(&resp, " slot:", res.slot_id, " shard:", sid);
|
||||||
|
|
||||||
if (res.ttl != INT64_MAX) {
|
if (res.ttl != INT64_MAX) {
|
||||||
|
|
|
@ -783,6 +783,25 @@ TEST_F(DflyEngineTest, MemoryUsage) {
|
||||||
EXPECT_GT(*resp.GetInt(), 100000);
|
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.
|
// 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
|
// 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.
|
// unconditionally from number of cpus. TO TEST BLPOP under multi for single/multi argument case.
|
||||||
|
|
|
@ -129,13 +129,17 @@ zlexrangespec GetLexRange(bool reverse, const ZSetFamily::LexInterval& li) {
|
||||||
return range;
|
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
|
/* Delete the element 'ele' from the sorted set, returning 1 if the element
|
||||||
* existed and was deleted, 0 otherwise (the element was not there).
|
* existed and was deleted, 0 otherwise (the element was not there).
|
||||||
* taken from t_zset.c
|
* taken from t_zset.c
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int ZsetDel(detail::RobjWrapper* robj_wrapper, sds ele) {
|
int ZsetDel(detail::RobjWrapper* robj_wrapper, sds ele) {
|
||||||
if (robj_wrapper->encoding() == OBJ_ENCODING_LISTPACK) {
|
if (IsListPack(robj_wrapper)) {
|
||||||
unsigned char* eptr;
|
unsigned char* eptr;
|
||||||
uint8_t* lp = (uint8_t*)robj_wrapper->inner_obj();
|
uint8_t* lp = (uint8_t*)robj_wrapper->inner_obj();
|
||||||
if ((eptr = zzlFind(lp, ele, NULL)) != NULL) {
|
if ((eptr = zzlFind(lp, ele, NULL)) != NULL) {
|
||||||
|
@ -153,7 +157,7 @@ int ZsetDel(detail::RobjWrapper* robj_wrapper, sds ele) {
|
||||||
|
|
||||||
// taken from t_zset.c
|
// taken from t_zset.c
|
||||||
std::optional<double> GetZsetScore(const detail::RobjWrapper* robj_wrapper, sds member) {
|
std::optional<double> GetZsetScore(const detail::RobjWrapper* robj_wrapper, sds member) {
|
||||||
if (robj_wrapper->encoding() == OBJ_ENCODING_LISTPACK) {
|
if (IsListPack(robj_wrapper)) {
|
||||||
double score;
|
double score;
|
||||||
if (zzlFind((uint8_t*)robj_wrapper->inner_obj(), member, &score) == NULL)
|
if (zzlFind((uint8_t*)robj_wrapper->inner_obj(), member, &score) == NULL)
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
|
@ -429,7 +433,7 @@ void IntervalVisitor::ActionRange(unsigned start, unsigned end) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void IntervalVisitor::ActionRange(const zrangespec& range) {
|
void IntervalVisitor::ActionRange(const zrangespec& range) {
|
||||||
if (robj_wrapper_->encoding() == OBJ_ENCODING_LISTPACK) {
|
if (IsListPack(robj_wrapper_)) {
|
||||||
ExtractListPack(range);
|
ExtractListPack(range);
|
||||||
} else {
|
} else {
|
||||||
CHECK_EQ(robj_wrapper_->encoding(), OBJ_ENCODING_SKIPLIST);
|
CHECK_EQ(robj_wrapper_->encoding(), OBJ_ENCODING_SKIPLIST);
|
||||||
|
@ -438,7 +442,7 @@ void IntervalVisitor::ActionRange(const zrangespec& range) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void IntervalVisitor::ActionRange(const zlexrangespec& range) {
|
void IntervalVisitor::ActionRange(const zlexrangespec& range) {
|
||||||
if (robj_wrapper_->encoding() == OBJ_ENCODING_LISTPACK) {
|
if (IsListPack(robj_wrapper_)) {
|
||||||
ExtractListPack(range);
|
ExtractListPack(range);
|
||||||
} else {
|
} else {
|
||||||
CHECK_EQ(robj_wrapper_->encoding(), OBJ_ENCODING_SKIPLIST);
|
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) {
|
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();
|
uint8_t* zl = (uint8_t*)robj_wrapper_->inner_obj();
|
||||||
|
|
||||||
removed_ = (end - start) + 1;
|
removed_ = (end - start) + 1;
|
||||||
|
@ -461,7 +465,7 @@ void IntervalVisitor::ActionRem(unsigned start, unsigned end) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void IntervalVisitor::ActionRem(const zrangespec& range) {
|
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();
|
uint8_t* zl = (uint8_t*)robj_wrapper_->inner_obj();
|
||||||
unsigned long deleted = 0;
|
unsigned long deleted = 0;
|
||||||
zl = zzlDeleteRangeByScore(zl, &range, &deleted);
|
zl = zzlDeleteRangeByScore(zl, &range, &deleted);
|
||||||
|
@ -475,7 +479,7 @@ void IntervalVisitor::ActionRem(const zrangespec& range) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void IntervalVisitor::ActionRem(const zlexrangespec& 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();
|
uint8_t* zl = (uint8_t*)robj_wrapper_->inner_obj();
|
||||||
unsigned long deleted = 0;
|
unsigned long deleted = 0;
|
||||||
zl = zzlDeleteRangeByLex(zl, &range, &deleted);
|
zl = zzlDeleteRangeByLex(zl, &range, &deleted);
|
||||||
|
@ -490,7 +494,7 @@ void IntervalVisitor::ActionRem(const zlexrangespec& range) {
|
||||||
|
|
||||||
void IntervalVisitor::ActionPop(ZSetFamily::TopNScored sc) {
|
void IntervalVisitor::ActionPop(ZSetFamily::TopNScored sc) {
|
||||||
if (sc > 0) {
|
if (sc > 0) {
|
||||||
if (robj_wrapper_->encoding() == OBJ_ENCODING_LISTPACK) {
|
if (IsListPack(robj_wrapper_)) {
|
||||||
PopListPack(sc);
|
PopListPack(sc);
|
||||||
} else {
|
} else {
|
||||||
CHECK_EQ(robj_wrapper_->encoding(), OBJ_ENCODING_SKIPLIST);
|
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;
|
OpStatus op_status = OpStatus::OK;
|
||||||
AddResult aresult;
|
AddResult aresult;
|
||||||
detail::RobjWrapper* robj_wrapper = res_it->it->second.GetRobjWrapper();
|
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.
|
// opportunistically reserve space if multiple entries are about to be added.
|
||||||
if ((zparams.flags & ZADD_IN_XX) == 0 && members.size() > 2) {
|
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 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);
|
DbTableStats* stats = db_slice.MutableStats(op_args.db_cntx.db_index);
|
||||||
--stats->listpack_blob_cnt;
|
--stats->listpack_blob_cnt;
|
||||||
}
|
}
|
||||||
|
@ -1399,7 +1403,7 @@ OpResult<RankResult> OpRank(const OpArgs& op_args, string_view key, string_view
|
||||||
return res_it.status();
|
return res_it.status();
|
||||||
|
|
||||||
const detail::RobjWrapper* robj_wrapper = res_it.value()->second.GetRobjWrapper();
|
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* zl = (uint8_t*)robj_wrapper->inner_obj();
|
||||||
unsigned char *eptr, *sptr;
|
unsigned char *eptr, *sptr;
|
||||||
|
|
||||||
|
@ -1462,7 +1466,7 @@ OpResult<unsigned> OpCount(const OpArgs& op_args, std::string_view key,
|
||||||
zrangespec range = GetZrangeSpec(false, interval);
|
zrangespec range = GetZrangeSpec(false, interval);
|
||||||
unsigned count = 0;
|
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* zl = (uint8_t*)robj_wrapper->inner_obj();
|
||||||
uint8_t *eptr, *sptr;
|
uint8_t *eptr, *sptr;
|
||||||
double score;
|
double score;
|
||||||
|
@ -1512,7 +1516,7 @@ OpResult<unsigned> OpLexCount(const OpArgs& op_args, string_view key,
|
||||||
unsigned count = 0;
|
unsigned count = 0;
|
||||||
const detail::RobjWrapper* robj_wrapper = res_it.value()->second.GetRobjWrapper();
|
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* zl = (uint8_t*)robj_wrapper->inner_obj();
|
||||||
uint8_t *eptr, *sptr;
|
uint8_t *eptr, *sptr;
|
||||||
|
|
||||||
|
@ -1614,7 +1618,7 @@ OpResult<StringVec> OpScan(const OpArgs& op_args, std::string_view key, uint64_t
|
||||||
StringVec res;
|
StringVec res;
|
||||||
char buf[128];
|
char buf[128];
|
||||||
|
|
||||||
if (pv.Encoding() == OBJ_ENCODING_LISTPACK) {
|
if (IsListPack(pv.GetRobjWrapper())) {
|
||||||
ZSetFamily::RangeParams params;
|
ZSetFamily::RangeParams params;
|
||||||
params.with_scores = true;
|
params.with_scores = true;
|
||||||
IntervalVisitor iv{Action::RANGE, params, const_cast<PrimeValue*>(&pv)};
|
IntervalVisitor iv{Action::RANGE, params, const_cast<PrimeValue*>(&pv)};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue