summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authororanagra <oran@redislabs.com>2016-05-09 18:01:09 +0300
committerantirez <antirez@gmail.com>2016-09-12 16:36:59 +0200
commit8c24325f8f1017d49596201903d8dd3c4da57482 (patch)
tree689594106c4e05044d2e281410e05754ad008892
parent68bf45fa1e77c7e2e3f3ab4a7894f9bc1a1da57b (diff)
downloadredis-8c24325f8f1017d49596201903d8dd3c4da57482.tar.gz
Adding objectComputeSize() function.
-rw-r--r--src/object.c113
1 files changed, 113 insertions, 0 deletions
diff --git a/src/object.c b/src/object.c
index a7c1e4c21..903143f4e 100644
--- a/src/object.c
+++ b/src/object.c
@@ -36,6 +36,8 @@
#define strtold(a,b) ((long double)strtod((a),(b)))
#endif
+/* ===================== Creation and parsing of objects ==================== */
+
robj *createObject(int type, void *ptr) {
robj *o = zmalloc(sizeof(*o));
o->type = type;
@@ -690,6 +692,117 @@ char *strEncoding(int encoding) {
}
}
+/* ========================== Objects introspection ========================= */
+
+/* Returns the size in bytes consumed by the key's value in RAM */
+size_t objectComputeSize(robj *o) {
+ robj *ele;
+ list *l;
+ listNode *ln;
+ dict *d;
+ dictIterator *di;
+ listIter li;
+ struct dictEntry *de;
+ size_t asize = 0, elesize;
+
+ if (o->type == OBJ_STRING) {
+ if(o->encoding == OBJ_ENCODING_INT) {
+ asize = sizeof(*o);
+ }
+ else if(o->encoding == OBJ_ENCODING_RAW) {
+ asize = sdsAllocSize(o->ptr)+sizeof(*o);
+ } else if(o->encoding == OBJ_ENCODING_EMBSTR) {
+ asize = sdslen(o->ptr)+2+sizeof(*o);
+ } else {
+ serverPanic("Unknown string encoding");
+ }
+ } else if (o->type == OBJ_LIST) {
+ if (o->encoding == OBJ_ENCODING_QUICKLIST) {
+ quicklist *ql = o->ptr;
+ quicklistNode *node = ql->head;
+ asize = sizeof(*o)+sizeof(quicklist);
+ do {
+ asize += sizeof(quicklistNode)+ziplistBlobLen(node->zl);
+ } while ((node = node->next));
+ } else if (o->encoding == OBJ_ENCODING_ZIPLIST) {
+ asize = sizeof(*o)+ziplistBlobLen(o->ptr);
+ } else if (o->encoding == OBJ_ENCODING_LINKEDLIST) {
+ l = o->ptr;
+ asize = sizeof(*o)+sizeof(list);
+ listRewind(l,&li);
+ while((ln = listNext(&li))) {
+ ele = ln->value;
+ elesize = (ele->encoding == OBJ_ENCODING_RAW) ?
+ (sizeof(*o)+sdsAllocSize(ele->ptr)) : sizeof(*o);
+ asize += (sizeof(listNode)+elesize);
+ }
+ } else {
+ serverPanic("Unknown list encoding");
+ }
+ } else if (o->type == OBJ_SET) {
+ if (o->encoding == OBJ_ENCODING_HT) {
+ d = o->ptr;
+ di = dictGetIterator(d);
+ asize = sizeof(*o)+sizeof(dict)+(sizeof(struct dictEntry*)*dictSlots(d));
+ while((de = dictNext(di)) != NULL) {
+ ele = dictGetKey(de);
+ elesize = (ele->encoding == OBJ_ENCODING_RAW) ?
+ (sizeof(*o)+sdsAllocSize(ele->ptr)) : sizeof(*o);
+ asize += (sizeof(struct dictEntry)+elesize);
+ }
+ dictReleaseIterator(di);
+ } else if (o->encoding == OBJ_ENCODING_INTSET) {
+ intset *is = o->ptr;
+ asize = sizeof(*o)+sizeof(*is)+is->encoding*is->length;
+ } else {
+ serverPanic("Unknown set encoding");
+ }
+ } else if (o->type == OBJ_ZSET) {
+ if (o->encoding == OBJ_ENCODING_ZIPLIST) {
+ asize = sizeof(*o)+(ziplistBlobLen(o->ptr));
+ } else if (o->encoding == OBJ_ENCODING_SKIPLIST) {
+ d = ((zset*)o->ptr)->dict;
+ di = dictGetIterator(d);
+ asize = sizeof(*o)+sizeof(zset)+(sizeof(struct dictEntry*)*dictSlots(d));
+ while((de = dictNext(di)) != NULL) {
+ ele = dictGetKey(de);
+ elesize = (ele->encoding == OBJ_ENCODING_RAW) ?
+ (sizeof(*o)+sdsAllocSize(ele->ptr)) : sizeof(*o);
+ asize += (sizeof(struct dictEntry)+elesize);
+ asize += sizeof(zskiplistNode)*dictSize(d);
+ }
+ dictReleaseIterator(di);
+ } else {
+ serverPanic("Unknown sorted set encoding");
+ }
+ } else if (o->type == OBJ_HASH) {
+ if (o->encoding == OBJ_ENCODING_ZIPLIST) {
+ asize = sizeof(*o)+(ziplistBlobLen(o->ptr));
+ } else if (o->encoding == OBJ_ENCODING_HT) {
+ d = o->ptr;
+ di = dictGetIterator(d);
+ asize = sizeof(*o)+sizeof(dict)+(sizeof(struct dictEntry*)*dictSlots(d));
+ while((de = dictNext(di)) != NULL) {
+ ele = dictGetKey(de);
+ elesize = (ele->encoding == OBJ_ENCODING_RAW) ?
+ (sizeof(*o)+sdsAllocSize(ele->ptr)) : sizeof(*o);
+ ele = dictGetVal(de);
+ elesize = (ele->encoding == OBJ_ENCODING_RAW) ?
+ (sizeof(*o)+sdsAllocSize(ele->ptr)) : sizeof(*o);
+ asize += (sizeof(struct dictEntry)+elesize);
+ }
+ dictReleaseIterator(di);
+ } else {
+ serverPanic("Unknown hash encoding");
+ }
+ } else {
+ serverPanic("Unknown object type");
+ }
+ return asize;
+}
+
+/* ============================ The OBJECT command ========================== */
+
/* This is a helper function for the OBJECT command. We need to lookup keys
* without any modification of LRU or other parameters. */
robj *objectCommandLookup(client *c, robj *key) {