MCPcopy Create free account
hub / github.com/Snapchat/KeyDB / lazyfreeGetFreeEffort

Function lazyfreeGetFreeEffort

src/lazyfree.cpp:86–137  ·  view source on GitHub ↗

Return the amount of work needed in order to free an object. * The return value is not always the actual number of allocations the * object is composed of, but a number proportional to it. * * For strings the function always returns 1. * * For aggregated objects represented by hash tables or other data structures * the function just returns the number of elements the object is composed of.

Source from the content-addressed store, hash-verified

84 * For lists the function returns the number of elements in the quicklist
85 * representing the list. */
86size_t lazyfreeGetFreeEffort(robj *key, robj *obj) {
87 if (obj->type == OBJ_LIST) {
88 quicklist *ql = (quicklist*)ptrFromObj(obj);
89 return ql->len;
90 } else if (obj->type == OBJ_SET && obj->encoding == OBJ_ENCODING_HT) {
91 dict *ht = (dict*)ptrFromObj(obj);
92 return dictSize(ht);
93 } else if (obj->type == OBJ_ZSET && obj->encoding == OBJ_ENCODING_SKIPLIST){
94 zset *zs = (zset*)ptrFromObj(obj);
95 return zs->zsl->length;
96 } else if (obj->type == OBJ_HASH && obj->encoding == OBJ_ENCODING_HT) {
97 dict *ht = (dict*)ptrFromObj(obj);
98 return dictSize(ht);
99 } else if (obj->type == OBJ_STREAM) {
100 size_t effort = 0;
101 stream *s = (stream*)ptrFromObj(obj);
102
103 /* Make a best effort estimate to maintain constant runtime. Every macro
104 * node in the Stream is one allocation. */
105 effort += s->rax->numnodes;
106
107 /* Every consumer group is an allocation and so are the entries in its
108 * PEL. We use size of the first group's PEL as an estimate for all
109 * others. */
110 if (s->cgroups && raxSize(s->cgroups)) {
111 raxIterator ri;
112 streamCG *cg;
113 raxStart(&ri,s->cgroups);
114 raxSeek(&ri,"^",NULL,0);
115 /* There must be at least one group so the following should always
116 * work. */
117 serverAssert(raxNext(&ri));
118 cg = (streamCG*)ri.data;
119 effort += raxSize(s->cgroups)*(1+raxSize(cg->pel));
120 raxStop(&ri);
121 }
122 return effort;
123 } else if (obj->type == OBJ_MODULE) {
124 moduleValue *mv = (moduleValue*)ptrFromObj(obj);
125 moduleType *mt = mv->type;
126 if (mt->free_effort != NULL) {
127 size_t effort = mt->free_effort(key,mv->value);
128 /* If the module's free_effort returns 0, it will use asynchronous free
129 memory by default */
130 return effort == 0 ? ULONG_MAX : effort;
131 } else {
132 return 1;
133 }
134 } else {
135 return 1; /* Everything else is a single allocation. */
136 }
137}
138
139/* Delete a key, value, and associated expiration entry if any, from the DB.
140 * If there are enough allocations to free the value object may be put into

Callers 2

asyncDeleteMethod · 0.85
freeObjAsyncFunction · 0.85

Calls 6

ptrFromObjFunction · 0.85
raxSizeFunction · 0.85
raxStartFunction · 0.85
raxSeekFunction · 0.85
raxNextFunction · 0.85
raxStopFunction · 0.85

Tested by

no test coverage detected