MCPcopy Create free account
hub / github.com/F-Stack/f-stack / raxAddChild

Function raxAddChild

app/redis-6.2.6/src/rax.c:256–387  ·  view source on GitHub ↗

Add a new child to the node 'n' representing the character 'c' and return * its new pointer, as well as the child pointer by reference. Additionally * '***parentlink' is populated with the raxNode pointer-to-pointer of where * the new child was stored, which is useful for the caller to replace the * child pointer if it gets reallocated. * * On success the new parent node pointer is returned

Source from the content-addressed store, hash-verified

254 * of the realloc, so the caller should discard 'n' and use the new value).
255 * On out of memory NULL is returned, and the old node is still valid. */
256raxNode *raxAddChild(raxNode *n, unsigned char c, raxNode **childptr, raxNode ***parentlink) {
257 assert(n->iscompr == 0);
258
259 size_t curlen = raxNodeCurrentLength(n);
260 n->size++;
261 size_t newlen = raxNodeCurrentLength(n);
262 n->size--; /* For now restore the orignal size. We'll update it only on
263 success at the end. */
264
265 /* Alloc the new child we will link to 'n'. */
266 raxNode *child = raxNewNode(0,0);
267 if (child == NULL) return NULL;
268
269 /* Make space in the original node. */
270 raxNode *newn = rax_realloc(n,newlen);
271 if (newn == NULL) {
272 rax_free(child);
273 return NULL;
274 }
275 n = newn;
276
277 /* After the reallocation, we have up to 8/16 (depending on the system
278 * pointer size, and the required node padding) bytes at the end, that is,
279 * the additional char in the 'data' section, plus one pointer to the new
280 * child, plus the padding needed in order to store addresses into aligned
281 * locations.
282 *
283 * So if we start with the following node, having "abde" edges.
284 *
285 * Note:
286 * - We assume 4 bytes pointer for simplicity.
287 * - Each space below corresponds to one byte
288 *
289 * [HDR*][abde][Aptr][Bptr][Dptr][Eptr]|AUXP|
290 *
291 * After the reallocation we need: 1 byte for the new edge character
292 * plus 4 bytes for a new child pointer (assuming 32 bit machine).
293 * However after adding 1 byte to the edge char, the header + the edge
294 * characters are no longer aligned, so we also need 3 bytes of padding.
295 * In total the reallocation will add 1+4+3 bytes = 8 bytes:
296 *
297 * (Blank bytes are represented by ".")
298 *
299 * [HDR*][abde][Aptr][Bptr][Dptr][Eptr]|AUXP|[....][....]
300 *
301 * Let's find where to insert the new child in order to make sure
302 * it is inserted in-place lexicographically. Assuming we are adding
303 * a child "c" in our case pos will be = 2 after the end of the following
304 * loop. */
305 int pos;
306 for (pos = 0; pos < n->size; pos++) {
307 if (n->data[pos] > c) break;
308 }
309
310 /* Now, if present, move auxiliary data pointer at the end
311 * so that we can mess with the other data without overwriting it.
312 * We will obtain something like that:
313 *

Callers 1

raxGenericInsertFunction · 0.85

Calls 3

raxNewNodeFunction · 0.85
memmoveFunction · 0.50
memcpyFunction · 0.50

Tested by

no test coverage detected