mirror of
https://github.com/fluencelabs/redis
synced 2025-06-18 03:31:21 +00:00
Merge remote-tracking branch 'upstream/unstable' into help_subcommands
This commit is contained in:
63
src/object.c
63
src/object.c
@ -232,6 +232,13 @@ robj *createZsetZiplistObject(void) {
|
||||
return o;
|
||||
}
|
||||
|
||||
robj *createStreamObject(void) {
|
||||
stream *s = streamNew();
|
||||
robj *o = createObject(OBJ_STREAM,s);
|
||||
o->encoding = OBJ_ENCODING_STREAM;
|
||||
return o;
|
||||
}
|
||||
|
||||
robj *createModuleObject(moduleType *mt, void *value) {
|
||||
moduleValue *mv = zmalloc(sizeof(*mv));
|
||||
mv->type = mt;
|
||||
@ -303,6 +310,10 @@ void freeModuleObject(robj *o) {
|
||||
zfree(mv);
|
||||
}
|
||||
|
||||
void freeStreamObject(robj *o) {
|
||||
freeStream(o->ptr);
|
||||
}
|
||||
|
||||
void incrRefCount(robj *o) {
|
||||
if (o->refcount != OBJ_SHARED_REFCOUNT) o->refcount++;
|
||||
}
|
||||
@ -316,6 +327,7 @@ void decrRefCount(robj *o) {
|
||||
case OBJ_ZSET: freeZsetObject(o); break;
|
||||
case OBJ_HASH: freeHashObject(o); break;
|
||||
case OBJ_MODULE: freeModuleObject(o); break;
|
||||
case OBJ_STREAM: freeStreamObject(o); break;
|
||||
default: serverPanic("Unknown object type"); break;
|
||||
}
|
||||
zfree(o);
|
||||
@ -788,6 +800,49 @@ size_t objectComputeSize(robj *o, size_t sample_size) {
|
||||
} else {
|
||||
serverPanic("Unknown hash encoding");
|
||||
}
|
||||
} else if (o->type == OBJ_STREAM) {
|
||||
stream *s = o->ptr;
|
||||
/* Note: to guess the size of the radix tree is not trivial, so we
|
||||
* approximate it considering 64 bytes of data overhead for each
|
||||
* key (the ID), and then adding the number of bare nodes, plus some
|
||||
* overhead due by the data and child pointers. This secret recipe
|
||||
* was obtained by checking the average radix tree created by real
|
||||
* workloads, and then adjusting the constants to get numbers that
|
||||
* more or less match the real memory usage.
|
||||
*
|
||||
* Actually the number of nodes and keys may be different depending
|
||||
* on the insertion speed and thus the ability of the radix tree
|
||||
* to compress prefixes. */
|
||||
asize = sizeof(*o);
|
||||
asize += s->rax->numele * 64;
|
||||
asize += s->rax->numnodes * sizeof(raxNode);
|
||||
asize += s->rax->numnodes * 32*7; /* Add a few child pointers... */
|
||||
|
||||
/* Now we have to add the listpacks. The last listpack is often non
|
||||
* complete, so we estimate the size of the first N listpacks, and
|
||||
* use the average to compute the size of the first N-1 listpacks, and
|
||||
* finally add the real size of the last node. */
|
||||
raxIterator ri;
|
||||
raxStart(&ri,s->rax);
|
||||
raxSeek(&ri,"^",NULL,0);
|
||||
size_t lpsize = 0, samples = 0;
|
||||
while(samples < sample_size && raxNext(&ri)) {
|
||||
unsigned char *lp = ri.data;
|
||||
lpsize += lpBytes(lp);
|
||||
samples++;
|
||||
}
|
||||
if (s->rax->numele <= samples) {
|
||||
asize += lpsize;
|
||||
} else {
|
||||
if (samples) lpsize /= samples; /* Compute the average. */
|
||||
asize += lpsize * (s->rax->numele-1);
|
||||
/* No need to check if seek succeeded, we enter this branch only
|
||||
* if there are a few elements in the radix tree. */
|
||||
raxSeek(&ri,"$",NULL,0);
|
||||
raxNext(&ri);
|
||||
asize += lpBytes(ri.data);
|
||||
}
|
||||
raxStop(&ri);
|
||||
} else if (o->type == OBJ_MODULE) {
|
||||
moduleValue *mv = o->ptr;
|
||||
moduleType *mt = mv->type;
|
||||
@ -1045,10 +1100,14 @@ void objectCommand(client *c) {
|
||||
if ((o = objectCommandLookupOrReply(c,c->argv[2],shared.nullbulk))
|
||||
== NULL) return;
|
||||
if (!(server.maxmemory_policy & MAXMEMORY_FLAG_LFU)) {
|
||||
addReplyError(c,"A non-LFU maxmemory policy is selected, access frequency not tracked. Please note that when switching between policies at runtime LRU and LFU data will take some time to adjust.");
|
||||
addReplyError(c,"An LFU maxmemory policy is not selected, access frequency not tracked. Please note that when switching between policies at runtime LRU and LFU data will take some time to adjust.");
|
||||
return;
|
||||
}
|
||||
addReplyLongLong(c,o->lru&255);
|
||||
/* LFUDecrAndReturn should be called
|
||||
* in case of the key has not been accessed for a long time,
|
||||
* because we update the access time only
|
||||
* when the key is read or overwritten. */
|
||||
addReplyLongLong(c,LFUDecrAndReturn(o));
|
||||
} else {
|
||||
addReplyErrorFormat(c, "Unknown subcommand or wrong number of arguments for '%s'. Try OBJECT help",
|
||||
(char *)c->argv[1]->ptr);
|
||||
|
Reference in New Issue
Block a user