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:
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;
|
||||
}
|
||||
|
||||
|
||||
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) {
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)};
|
||||
|
|
Loading…
Reference in a new issue