00001 #ifndef RBT_COMMON_H
00002 #define RBT_COMMON_H
00003
00004 #include <stdint.h>
00005 #include <stdbool.h>
00006
00007 #if defined(RBT_IMPLICIT_LOCKING)
00008 # include <pthread.h>
00009 #endif
00010
00011 typedef enum {
00012 RBT_GENKEY,
00013 RBT_STRKEY,
00014 RBT_I32KEY,
00015 RBT_I64KEY
00016 } rbt_type_t;
00017
00018 typedef enum {
00019 RBT_WALK_PREORDER,
00020 RBT_WALK_INORDER,
00021 RBT_WALK_POSTORDER,
00022 RBT_WALK_LEVELORDER
00023 } rbt_walk_t;
00024
00029 struct rbt_node {
00030 struct rbt_node *_chld[2];
00031 uint8_t _node[];
00032 };
00033
00034 #define RBT_NODE_CB 0
00035 #define RBT_NODE_CR 1
00036 #define RBT_NODE_SL 0
00037 #define RBT_NODE_SR 1
00038
00039 #define rbt_node_ptr(np) ((struct rbt_node *)((uintptr_t)(np)&(UINTPTR_MAX << 1)))
00040 #define rbt_node_setptr(dst,src) (dst) = (struct rbt_node *)((uintptr_t)rbt_node_ptr(src)|((uintptr_t)(dst)&1))
00041
00042 #define rbt_node_setcolor(np, cb) \
00043 do { \
00044 register struct rbt_node *__n = rbt_node_ptr(np); \
00045 register uint8_t __c = (cb) & 1; \
00046 \
00047 if (__n != NULL) { \
00048 if (__c) __n->_chld[0] = (struct rbt_node *)((uintptr_t)(__n->_chld[0]) | 1); \
00049 else __n->_chld[0] = rbt_node_ptr(__n->_chld[0]); \
00050 } \
00051 } while(0)
00052 #define rbt_node_getcolor_raw(cp) ((uintptr_t)(cp) & 1)
00053 #define rbt_node_getcolor(np) (rbt_node_ptr(np) == NULL ? RBT_NODE_CB : rbt_node_getcolor_raw(rbt_node_ptr(np)->_chld[0]))
00054 #define rbt_node_cpycolor(dn, sn) rbt_node_setcolor((dn), rbt_node_getcolor(sn))
00055
00056 #define rbt_hpush4(__a, __p) \
00057 do { \
00058 __a[3] = __a[2]; \
00059 __a[2] = __a[1]; \
00060 __a[1] = __a[0]; \
00061 __a[0] = __p; \
00062 } while(0)
00063
00064 #define rbt_hpush3(__a, __p) \
00065 do { \
00066 __a[2] = __a[1]; \
00067 __a[1] = __a[0]; \
00068 __a[0] = __p; \
00069 } while(0)
00070
00071 #define rbt_redfix(__h, __d, v) \
00072 do { \
00073 if (((__d) & 3) < 2) { \
00074 if (((__d) & 3) == 0) { \
00075 rbt_node_setptr(v, rbt_node_rotate_R(__h[2])); \
00076 } else { \
00077 rbt_node_setptr(v, rbt_node_rotate_RL(__h[2])); \
00078 } \
00079 } else { \
00080 if (((__d) & 3) == 2) { \
00081 rbt_node_setptr(v, rbt_node_rotate_LR(__h[2])); \
00082 } else { \
00083 rbt_node_setptr(v, rbt_node_rotate_L(__h[2])); \
00084 } \
00085 } \
00086 } while(0)
00087
00088 struct rbt {
00089 struct rbt_node *root;
00090 size_t size;
00091 rbt_type_t type;
00092 #if defined(RBT_IMPLICIT_LOCKING)
00093 pthread_rwlock_t lock;
00094 #endif
00095 };
00096
00097 typedef struct rbt rbt_t;
00098
00103 rbt_t *rbt_new(rbt_type_t type);
00104
00111 void rbt_free(rbt_t *rbt, void (*callback)(void *));
00112
00117 int rbt_rlock(rbt_t *rbt);
00118
00123 void rbt_runlock(rbt_t *rbt);
00124
00129 int rbt_wlock(rbt_t *rbt);
00130
00135 void rbt_wunlock(rbt_t *rbt);
00136
00137 struct rbt_node *rbt_node_rotate_L(struct rbt_node *);
00138 struct rbt_node *rbt_node_rotate_R(struct rbt_node *);
00139 struct rbt_node *rbt_node_rotate_LR(struct rbt_node *);
00140 struct rbt_node *rbt_node_rotate_RL(struct rbt_node *);
00141
00142 size_t rbt_size(rbt_t *rbt);
00143
00144 #define rbt_walk_push(n) stack[depth++] = (n)
00145 #define rbt_walk_pop() stack[--depth]
00146 #define rbt_walk_top() stack[depth-1]
00147
00148 int rbt_walk_preorder(rbt_t *rbt, int (*callback)(void *));
00149 int rbt_walk_inorder(rbt_t *rbt, int (*callback)(void *));
00150 int rbt_walk_postorder(rbt_t *rbt, int (*callback)(void *));
00151
00152 #endif