Files
scoutfs/utils/src/btree.c
Zach Brown de0fdd1f9f Promote userspace btree block initialization
Signed-off-by: Zach Brown <zab@versity.com>
2025-01-22 09:58:23 -08:00

91 lines
2.3 KiB
C

#include <assert.h>
#include "sparse.h"
#include "util.h"
#include "format.h"
#include "key.h"
#include "avl.h"
#include "leaf_item_hash.h"
#include "btree.h"
void btree_init_block(struct scoutfs_btree_block *bt, int level)
{
int free;
free = SCOUTFS_BLOCK_LG_SIZE - sizeof(struct scoutfs_btree_block);
if (level == 0)
free -= SCOUTFS_BTREE_LEAF_ITEM_HASH_BYTES;
bt->level = level;
bt->mid_free_len = cpu_to_le16(free);
}
/*
* Point the root at the single leaf block that makes up a btree.
*/
void btree_init_root_single(struct scoutfs_btree_root *root,
struct scoutfs_btree_block *bt,
u64 seq, u64 blkno)
{
root->ref.blkno = cpu_to_le64(blkno);
root->ref.seq = cpu_to_le64(seq);
root->height = 1;
memset(bt, 0, SCOUTFS_BLOCK_LG_SIZE);
btree_init_block(bt, 0);
}
static void *alloc_val(struct scoutfs_btree_block *bt, int len)
{
le16_add_cpu(&bt->mid_free_len, -len);
le16_add_cpu(&bt->total_item_bytes, len);
return (void *)&bt->items[le16_to_cpu(bt->nr_items)] + le16_to_cpu(bt->mid_free_len);
}
/*
* Add a sorted item after all the items in the block.
*
* We simply implement the special case of a wildly imbalanced avl tree.
* Mkfs only ever inserts a handful of items and they'll be rebalanced
* over time.
*/
void btree_append_item(struct scoutfs_btree_block *bt,
struct scoutfs_key *key, void *val, int val_len)
{
struct scoutfs_btree_item *item;
struct scoutfs_avl_node *prev;
void *val_buf;
item = &bt->items[le16_to_cpu(bt->nr_items)];
if (bt->nr_items) {
assert(scoutfs_key_compare(key, &(item - 1)->key) > 0);
prev = &(item - 1)->node;
item->node.height = prev->height++;
item->node.left = avl_node_off(&bt->item_root, prev);
prev->parent = avl_node_off(&bt->item_root, &item->node);
}
bt->item_root.node = avl_node_off(&bt->item_root, &item->node);
le16_add_cpu(&bt->nr_items, 1);
le16_add_cpu(&bt->mid_free_len,
-(u16)sizeof(struct scoutfs_btree_item));
le16_add_cpu(&bt->total_item_bytes, sizeof(struct scoutfs_btree_item));
item->key = *key;
item->seq = cpu_to_le64(1);
item->flags = 0;
leaf_item_hash_insert(bt, &item->key,
cpu_to_le16((void *)item - (void *)bt));
if (val_len == 0)
return;
val_buf = alloc_val(bt, val_len);
item->val_off = cpu_to_le16((void *)val_buf - (void *)bt);
item->val_len = cpu_to_le16(val_len);
memcpy(val_buf, val, val_len);
}