Adding objectComputeSize() function.

This commit is contained in:
oranagra 2016-05-09 18:01:09 +03:00 committed by antirez
parent 68bf45fa1e
commit 8c24325f8f

View File

@ -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) {