mirror of
https://github.com/fluencelabs/redis
synced 2025-03-19 17:10:50 +00:00
Streams: add code to compute the stream memory usage.
It's a bit of black magic without actually tracking it inside rax.c, however Redis usage of the radix tree for the stream data structure is quite consistent, so a few magic constants apparently are producing results that make sense.
This commit is contained in:
parent
45fe1f5e00
commit
f42df6f43a
43
src/object.c
43
src/object.c
@ -800,6 +800,49 @@ size_t objectComputeSize(robj *o, size_t sample_size) {
|
|||||||
} else {
|
} else {
|
||||||
serverPanic("Unknown hash encoding");
|
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) {
|
} else if (o->type == OBJ_MODULE) {
|
||||||
moduleValue *mv = o->ptr;
|
moduleValue *mv = o->ptr;
|
||||||
moduleType *mt = mv->type;
|
moduleType *mt = mv->type;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user