/* Position node in btree so that key might be inside */ static node_buf* record_find_node(btree* tree, void *key) { int start, end, mid, comp; // components of a binary search void *p = NULL; char curr_key[tree->head.max_key_len]; // The current key under examination hfsp_key_read readkey = tree->kread; hfsp_key_compare key_compare = tree->kcomp; UInt32 index; node_buf* node = btree_node_by_index(tree, tree->head.root); if (!node) HFSP_ERROR(-1, "record_find_node: Cant position to root node"); while (node->desc.kind == HFSP_NODE_NDX) { mid = start = 0; end = node->desc.num_rec; comp = -1; while (start < end) { mid = (start + end) >> 1; p = btree_key_by_index(tree, node, mid); if (!p) HFSP_ERROR(-1, "record_find_node: unexpected error"); p = readkey (p, curr_key); if (!p) HFSP_ERROR(-1, "record_find_node: unexpected error"); comp = key_compare(curr_key, key); if (comp > 0) start = mid + 1; else if (comp < 0) end = mid; else break; } if (!p) // Empty tree, fascinating ... HFSP_ERROR(-1, "record_find_node: unexpected empty node"); if (comp < 0) // mmh interesting key is before this key ... { if (mid == 0) return NULL; // nothing before this key .. p = btree_key_by_index(tree, node, mid-1); if (!p) HFSP_ERROR(-1, "record_find_node: unexpected error"); p = readkey (p, curr_key); if (!p) HFSP_ERROR(-1, "record_find_node: unexpected error"); } index = bswabU32_inc(p); node = btree_node_by_index(tree, index); } return node; // go on and use the found node fail: return NULL; }
/* find correct node record for given node and *pindex. * * index of record in this (or next) node * */ static node_buf* prepare_next(btree* tree, UInt16 node_index, UInt16* pindex) { node_buf* buf = btree_node_by_index(tree, node_index); btree_node_desc* desc = &buf->desc; UInt32 numrec = desc->num_rec; if (*pindex >= numrec) // move on to next node { UInt16 next = desc->next; *pindex = 0; if (!next /* is there a next node ? */ || !( buf = btree_node_by_index(tree, next))) return NULL; } return buf; }
/* intialize the record to the first record of the tree * which is (per design) the root node. */ int record_init_root(record* r, btree* tree) { // Position to first leaf node ... UInt32 leaf_head = tree->head.leaf_head; node_buf* buf = btree_node_by_index(tree, leaf_head); if (!buf) return -1; return record_init(r, tree, buf, 0); }
/* Update the record using its node- and key-index. * * Only use this function with a write lock, directly * after reading the record, otherwise use update_bykey(). */ int record_update(record* r) { btree *tree= r->tree; node_buf *buf = btree_node_by_index(tree, r->node_index, NODE_DIRTY); void *p = btree_key_by_index (tree, buf, r->keyind); if (!p) return -1; p = record_writekey (p, &r->key); if (!p) return -1; p = record_writeentry(p, &r->record); if (!p) return -1; return 0; }