STATIC void lf_move_recs(Node_s *node, Node_s *sibling) { int i; int j; int size; int total; node_compact(node); j = node->numrecs; for (i = 0; i < sibling->numrecs; i++, j++) { unint x = sibling->rec[i]; u8 *start = &((u8 *)sibling)[x]; size = start[sizeof(Key_t)]; size |= start[sizeof(Key_t) + 1] << 8; size += sizeof(u16) + sizeof(Key_t); total = size + sizeof(u16); aver(total <= node->free); node->end -= size; node->rec[j] = node->end; node->free -= total; memmove(&((u8 *)node)[node->end], start, size); ++node->numrecs; } sibling->numrecs = 0; sibling->free = BLOCK_SIZE - SZ_HEAD; }
/* *nodeptr == node is the only pointer to the node from the parent! */ static gpointer radixtree_remove(liRadixNode **nodeptr, rdxBase *input, guint32 bits) { liRadixNode **nextnode; gpointer data; rdxBase current, mask; liRadixNode *node = *nodeptr; if (!node) return NULL; current = *input; mask = RDX_MASK(node->width); if (node->width > bits) return NULL; /* prefix longer than key */ if ((current & mask) != node->key) return NULL; /* doesn't match */ if (node->width == bits) { /* exact match */ data = node->data; node->data = NULL; node_compact(nodeptr, node); return data; } if (mask & 0x1) { /* next "layer" */ input++; bits -= RDXBITS; nextnode = (current & RDX_BIT(0)) ? &node->right : &node->left; } else { nextnode = (current & RDX_BIT(node->width)) ? &node->right : &node->left; } data = radixtree_remove(nextnode, input, bits); if (data == NULL) return NULL; /* nothing deleted */ node_compact(nodeptr, node); return data; }