/* 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; }
/* intialize the record with the given index entry in the btree. */ int record_init(record* r, btree* bt, node_buf* buf, UInt16 index) { void *p; r-> tree = bt; p = btree_key_by_index(bt,buf,index); if (!p) return -1; p = record_readkey (p, &r->key); if (!p) return -1; /* void *help = p; // se comment below */ p = record_readentry(p, &r->record); /* This was for testing write cache only void * help; help = record_writeentry(help, &r->record); if (p != help) HFSP_ERROR(-1, "Error in write entry"); */ if (!p) return -1; r->node_index = buf->index; r-> keyind = index; return 0; /* fail: return -1; */ }
/* 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; }
/* intialize the record with the given index entry in the btree. */ static int record_init_extent(extent_record* r, btree* bt, node_buf* buf, UInt16 index) { void *p; r-> tree = bt; p = btree_key_by_index(bt, buf,index); if (!p) return -1; p = record_extent_readkey(p, &r->key); if (!p) return -1; p = volume_readextent(p, r->extent); if (!p) return -1; r->node_index = buf->index; r-> keyind = index; return 0; }
/* intialize the record with the given index entry in the btree. */ static int record_init(record* r, btree* bt, node_buf* buf, UInt16 index) { void *p; r-> tree = bt; p = btree_key_by_index(bt,buf,index); if (!p) return -1; p = record_readkey (p, &r->key); if (!p) return -1; p = record_readentry(p, &r->record); if (!p) return -1; r->node_index = buf->index; r-> keyind = index; return 0; }
/* search for the given key in the btree. * * returns pointer to memory just after key or NULL * In any case *keyind recives the index where the * key was found (or could be inserted.) */ static void * record_find_key(btree* tree, void* key, int* keyind, UInt16* node_index) { node_buf* buf = record_find_node(tree, key); if (buf) { int comp = -1; int start = 0; // components of a binary search int end = buf->desc.num_rec; int mid = -1; void *p = NULL; char curr_key[tree->head.max_key_len]; hfsp_key_read readkey = tree->kread; hfsp_key_compare key_compare = tree->kcomp; while (start < end) { mid = (start + end) >> 1; p = btree_key_by_index(tree, buf, mid); if (!p) HFSP_ERROR(-1, "record_init_key: unexpected error"); p = readkey (p, curr_key); if (!p) HFSP_ERROR(-1, "record_init_cat_key: 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(ENOENT, "record_init_key: unexpected empty node"); *keyind = mid; *node_index = buf->index; if (!comp) // found something ... return p; } HFSP_ERROR(ENOENT, NULL); fail: return NULL; }