1 1.1 christos /* 2 1.1 christos * rbtree.h -- generic red-black tree 3 1.1 christos * 4 1.1 christos * Copyright (c) 2001-2006, NLnet Labs. All rights reserved. 5 1.1 christos * 6 1.1 christos * See LICENSE for the license. 7 1.1 christos * 8 1.1 christos */ 9 1.1 christos 10 1.1.1.3 christos #ifndef RBTREE_H 11 1.1.1.3 christos #define RBTREE_H 12 1.1 christos 13 1.1 christos #include "region-allocator.h" 14 1.1 christos 15 1.1 christos /* 16 1.1 christos * This structure must be the first member of the data structure in 17 1.1.1.2 christos * the rbtree. This allows easy casting between an rbnode_type and the 18 1.1 christos * user data (poor man's inheritance). 19 1.1 christos */ 20 1.1.1.2 christos typedef struct rbnode rbnode_type; 21 1.1.1.2 christos struct rbnode { 22 1.1.1.2 christos rbnode_type *parent; 23 1.1.1.2 christos rbnode_type *left; 24 1.1.1.2 christos rbnode_type *right; 25 1.1.1.2 christos const void *key; 26 1.1.1.2 christos uint8_t color; 27 1.1.1.2 christos } ATTR_PACKED; 28 1.1 christos 29 1.1 christos #define RBTREE_NULL &rbtree_null_node 30 1.1.1.2 christos extern rbnode_type rbtree_null_node; 31 1.1 christos 32 1.1.1.2 christos typedef struct rbtree rbtree_type; 33 1.1.1.2 christos struct rbtree { 34 1.1 christos region_type *region; 35 1.1 christos 36 1.1 christos /* The root of the red-black tree */ 37 1.1.1.2 christos rbnode_type *root; 38 1.1 christos 39 1.1 christos /* The number of the nodes in the tree */ 40 1.1 christos size_t count; 41 1.1 christos 42 1.1 christos /* Current node for walks... */ 43 1.1.1.2 christos rbnode_type *_node; 44 1.1 christos 45 1.1 christos /* Key compare function. <0,0,>0 like strcmp. Return 0 on two NULL ptrs. */ 46 1.1 christos int (*cmp) (const void *, const void *); 47 1.1.1.2 christos } ATTR_PACKED; 48 1.1 christos 49 1.1 christos /* rbtree.c */ 50 1.1.1.2 christos rbtree_type *rbtree_create(region_type *region, int (*cmpf)(const void *, const void *)); 51 1.1.1.2 christos rbnode_type *rbtree_insert(rbtree_type *rbtree, rbnode_type *data); 52 1.1 christos /* returns node that is now unlinked from the tree. User to delete it. 53 1.1 christos * returns 0 if node not present */ 54 1.1.1.2 christos rbnode_type *rbtree_delete(rbtree_type *rbtree, const void *key); 55 1.1.1.2 christos rbnode_type *rbtree_search(rbtree_type *rbtree, const void *key); 56 1.1 christos /* returns true if exact match in result. Else result points to <= element, 57 1.1 christos or NULL if key is smaller than the smallest key. */ 58 1.1.1.2 christos int rbtree_find_less_equal(rbtree_type *rbtree, const void *key, rbnode_type **result); 59 1.1.1.2 christos rbnode_type *rbtree_first(rbtree_type *rbtree); 60 1.1.1.2 christos rbnode_type *rbtree_last(rbtree_type *rbtree); 61 1.1.1.2 christos rbnode_type *rbtree_next(rbnode_type *rbtree); 62 1.1.1.2 christos rbnode_type *rbtree_previous(rbnode_type *rbtree); 63 1.1 christos 64 1.1 christos #define RBTREE_WALK(rbtree, k, d) \ 65 1.1 christos for((rbtree)->_node = rbtree_first(rbtree);\ 66 1.1 christos (rbtree)->_node != RBTREE_NULL && ((k) = (rbtree)->_node->key) && \ 67 1.1 christos ((d) = (void *) (rbtree)->_node); (rbtree)->_node = rbtree_next((rbtree)->_node)) 68 1.1 christos 69 1.1.1.2 christos /* call with node=variable of struct* with rbnode_type as first element. 70 1.1 christos with type is the type of a pointer to that struct. */ 71 1.1 christos #define RBTREE_FOR(node, type, rbtree) \ 72 1.1 christos for(node=(type)rbtree_first(rbtree); \ 73 1.1.1.2 christos (rbnode_type*)node != RBTREE_NULL; \ 74 1.1.1.2 christos node = (type)rbtree_next((rbnode_type*)node)) 75 1.1 christos 76 1.1.1.3 christos #endif /* RBTREE_H */ 77