#ifndef SOCKS_BTREE_H_ #define SOCKS_BTREE_H_ #include #define BTREE_CONTAINER(t, m, v) ((void *)((v) ? (uintptr_t)(v) - (offsetof(t, m)) : 0)) #define BTREE_DEFINE_SIMPLE_INSERT(node_type, container_node_member, container_key_member, function_name) \ static void function_name(btree_t *tree, node_type *node) \ { \ if (!tree->b_root) { \ tree->b_root = &node->container_node_member; \ btree_insert_fixup(tree, &node->container_node_member); \ return; \ } \ \ btree_node_t *cur = tree->b_root; \ while (1) { \ node_type *cur_node = BTREE_CONTAINER(node_type, container_node_member, cur); \ btree_node_t *next = NULL; \ \ if (node->container_key_member > cur_node->container_key_member) { \ next = btree_right(cur); \ \ if (!next) { \ btree_put_right(cur, &node->container_node_member); \ break; \ } \ } else if (node->container_key_member < cur_node->container_key_member) { \ next = btree_left(cur); \ \ if (!next) { \ btree_put_left(cur, &node->container_node_member); \ break; \ } \ } else { \ return; \ } \ \ cur = next; \ } \ \ btree_insert_fixup(tree, &node->container_node_member); \ } #define BTREE_DEFINE_INSERT(node_type, container_node_member, container_key_member, function_name, comparator) \ static void function_name(btree_t *tree, node_type *node) \ { \ if (!tree->b_root) { \ tree->b_root = &node->container_node_member; \ btree_insert_fixup(tree, &node->container_node_member); \ return; \ } \ \ btree_node_t *cur = tree->b_root; \ while (1) { \ node_type *cur_node = BTREE_CONTAINER(node_type, container_node_member, cur); \ btree_node_t *next = NULL; \ int cmp = comparator(node, cur_node); \ \ if (cmp == 1) { \ next = btree_right(cur); \ \ if (!next) { \ btree_put_right(cur, &node->container_node_member); \ break; \ } \ } else if (cmp == -1) { \ next = btree_left(cur); \ \ if (!next) { \ btree_put_left(cur, &node->container_node_member); \ break; \ } \ } else { \ return; \ } \ \ cur = next; \ } \ \ btree_insert_fixup(tree, &node->container_node_member); \ } typedef struct btree_node { struct btree_node *b_parent, *b_left, *b_right; unsigned short b_height; } btree_node_t; typedef struct btree { struct btree_node *b_root; } btree_t; extern void btree_insert_fixup(btree_t *tree, btree_node_t *node); extern void btree_delete(btree_t *tree, btree_node_t *node); static inline void btree_put_left(btree_node_t *parent, btree_node_t *child) { parent->b_left = child; child->b_parent = parent; } static inline void btree_put_right(btree_node_t *parent, btree_node_t *child) { parent->b_right = child; child->b_parent = parent; } static inline btree_node_t *btree_left(btree_node_t *node) { return node->b_left; } static inline btree_node_t *btree_right(btree_node_t *node) { return node->b_right; } static inline btree_node_t *btree_parent(btree_node_t *node) { return node->b_parent; } static inline unsigned short btree_height(btree_node_t *node) { return node->b_height; } #endif