#ifndef RBTREE_H
#define RBTREE_H
#include "region-allocator.h"
typedef struct rbnode rbnode_type;
struct rbnode {
rbnode_type *parent;
rbnode_type *left;
rbnode_type *right;
const void *key;
uint8_t color;
} ATTR_PACKED;
#define RBTREE_NULL &rbtree_null_node
extern rbnode_type rbtree_null_node;
typedef struct rbtree rbtree_type;
struct rbtree {
region_type *region;
rbnode_type *root;
size_t count;
rbnode_type *_node;
int (*cmp) (const void *, const void *);
} ATTR_PACKED;
rbtree_type *rbtree_create(region_type *region, int (*cmpf)(const void *, const void *));
rbnode_type *rbtree_insert(rbtree_type *rbtree, rbnode_type *data);
rbnode_type *rbtree_delete(rbtree_type *rbtree, const void *key);
rbnode_type *rbtree_search(rbtree_type *rbtree, const void *key);
int rbtree_find_less_equal(rbtree_type *rbtree, const void *key, rbnode_type **result);
rbnode_type *rbtree_first(rbtree_type *rbtree);
rbnode_type *rbtree_last(rbtree_type *rbtree);
rbnode_type *rbtree_next(rbnode_type *rbtree);
rbnode_type *rbtree_previous(rbnode_type *rbtree);
#define RBTREE_WALK(rbtree, k, d) \
for((rbtree)->_node = rbtree_first(rbtree);\
(rbtree)->_node != RBTREE_NULL && ((k) = (rbtree)->_node->key) && \
((d) = (void *) (rbtree)->_node); (rbtree)->_node = rbtree_next((rbtree)->_node))
#define RBTREE_FOR(node, type, rbtree) \
for(node=(type)rbtree_first(rbtree); \
(rbnode_type*)node != RBTREE_NULL; \
node = (type)rbtree_next((rbnode_type*)node))
#endif