00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef RBTREE_H
00014 #define RBTREE_H
00015
00016
00017
00018 #include "array.h"
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 struct rb_node_hdr
00038 {
00039 struct rb_node_hdr *prev, *next;
00040 unsigned INT16 flags;
00041
00042 };
00043
00044 #define RB_RED 0x2000
00045 #define RB_THREAD_PREV 0x4000
00046 #define RB_THREAD_NEXT 0x8000
00047 #define RB_FLAG_MASK 0xe000
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 #define keep_flags(node, code) do { \
00071 int kept_flags_ = (node)->flags; \
00072 {code;} \
00073 (node)->flags = \
00074 ((node)->flags & ~RB_FLAG_MASK) | (kept_flags_ & RB_FLAG_MASK); \
00075 } while (0)
00076
00077 PMOD_EXPORT struct rb_node_hdr *rb_first (struct rb_node_hdr *root);
00078 PMOD_EXPORT struct rb_node_hdr *rb_last (struct rb_node_hdr *root);
00079 PMOD_EXPORT struct rb_node_hdr *rb_link_prev (struct rb_node_hdr *node);
00080 PMOD_EXPORT struct rb_node_hdr *rb_link_next (struct rb_node_hdr *node);
00081
00082 #define rb_prev(node) \
00083 (DO_IF_RB_STATS (rb_num_sidesteps++ COMMA) \
00084 (node)->flags & RB_THREAD_PREV ? \
00085 DO_IF_RB_STATS (rb_num_sidestep_ops++ COMMA) (node)->prev : \
00086 rb_link_prev (node))
00087 #define rb_next(node) \
00088 (DO_IF_RB_STATS (rb_num_sidesteps++ COMMA) \
00089 (node)->flags & RB_THREAD_NEXT ? \
00090 DO_IF_RB_STATS (rb_num_sidestep_ops++ COMMA) (node)->next : \
00091 rb_link_next (node))
00092
00093 #ifdef PIKE_DEBUG
00094
00095 static INLINE struct rb_node_hdr *rb_node_check (struct rb_node_hdr *node)
00096 {return node;}
00097 #else
00098 #define rb_node_check(node) ((struct rb_node_hdr *) (node))
00099 #endif
00100
00101 typedef int rb_find_fn (void *key, struct rb_node_hdr *node);
00102 typedef int rb_cmp_fn (struct rb_node_hdr *a, struct rb_node_hdr *b, void *extra);
00103 typedef int rb_equal_fn (struct rb_node_hdr *a, struct rb_node_hdr *b, void *extra);
00104 typedef struct rb_node_hdr *rb_copy_fn (struct rb_node_hdr *node, void *extra);
00105 typedef void rb_free_fn (struct rb_node_hdr *node, void *extra);
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155 struct rb_node_hdr *rb_insert (struct rb_node_hdr **root,
00156 rb_find_fn *find_fn, void *key,
00157 struct rb_node_hdr *new);
00158 void rb_add (struct rb_node_hdr **root,
00159 rb_find_fn *find_fn, void *key,
00160 struct rb_node_hdr *new);
00161 void rb_add_after (struct rb_node_hdr **root,
00162 rb_find_fn *find_fn, void *key,
00163 struct rb_node_hdr *new,
00164 struct rb_node_hdr *existing);
00165 struct rb_node_hdr *rb_remove (struct rb_node_hdr **root,
00166 rb_find_fn *find_fn, void *key);
00167 void rb_remove_node (struct rb_node_hdr **root,
00168 rb_find_fn *find_fn, void *key,
00169 struct rb_node_hdr *node);
00170 struct rb_node_hdr *rb_remove_with_move (struct rb_node_hdr **root,
00171 rb_find_fn *find_fn, void *key,
00172 size_t node_size,
00173 rb_free_fn *cleanup_fn,
00174 void *cleanup_fn_extra);
00175 struct rb_node_hdr *rb_remove_node_with_move (struct rb_node_hdr **root,
00176 rb_find_fn *find_fn, void *key,
00177 struct rb_node_hdr *node,
00178 size_t node_size);
00179
00180 struct rb_node_hdr *rb_find_eq (struct rb_node_hdr *root,
00181 rb_find_fn *find_fn, void *key);
00182 struct rb_node_hdr *rb_find_lt (struct rb_node_hdr *root,
00183 rb_find_fn *find_fn, void *key);
00184 struct rb_node_hdr *rb_find_gt (struct rb_node_hdr *root,
00185 rb_find_fn *find_fn, void *key);
00186 struct rb_node_hdr *rb_find_le (struct rb_node_hdr *root,
00187 rb_find_fn *find_fn, void *key);
00188 struct rb_node_hdr *rb_find_ge (struct rb_node_hdr *root,
00189 rb_find_fn *find_fn, void *key);
00190 struct rb_node_hdr *rb_get_nth (struct rb_node_hdr *root, size_t n);
00191 size_t rb_sizeof (struct rb_node_hdr *root);
00192
00193 void rb_free (struct rb_node_hdr *root, rb_free_fn *free_node_fn, void *extra);
00194 int rb_equal (struct rb_node_hdr *a, struct rb_node_hdr *b,
00195 rb_equal_fn *node_equal_fn, void *extra);
00196 struct rb_node_hdr *rb_copy (struct rb_node_hdr *source,
00197 rb_copy_fn *copy_node_fn, void *extra);
00198
00199 struct rb_node_hdr *rb_make_list (struct rb_node_hdr *tree);
00200 struct rb_node_hdr *rb_make_tree (struct rb_node_hdr *list, size_t length);
00201
00202 #define PIKE_MERGE_DESTR_A 0x2000
00203 #define PIKE_MERGE_DESTR_B 0x1000
00204
00205 enum rb_merge_trees {MERGE_TREE_A, MERGE_TREE_B, MERGE_TREE_RES};
00206
00207 typedef struct rb_node_hdr *rb_merge_copy_fn (struct rb_node_hdr *node, void *extra,
00208 enum rb_merge_trees tree);
00209 typedef void rb_merge_free_fn (struct rb_node_hdr *node, void *extra,
00210 enum rb_merge_trees tree);
00211
00212 struct rb_node_hdr *rb_linear_merge (
00213 struct rb_node_hdr *a, struct rb_node_hdr *b, int operation,
00214 rb_cmp_fn *cmp_fn, void *cmp_fn_extra,
00215 rb_merge_copy_fn *copy_node_fn, void *copy_fn_extra,
00216 rb_merge_free_fn *free_node_fn, void *free_fn_extra,
00217 size_t *length);
00218
00219 #ifdef RB_STATS
00220 extern size_t rb_num_sidesteps, rb_num_sidestep_ops;
00221 extern size_t rb_num_finds, rb_find_depth;
00222 extern size_t rb_num_tracks, rb_track_depth;
00223 extern size_t rb_num_sidetracks, rb_num_sidetrack_ops;
00224 extern size_t rb_max_depth;
00225 extern size_t rb_num_traverses, rb_num_traverse_ops;
00226 extern size_t rbstack_slice_allocs;
00227 extern size_t rb_num_adds, rb_add_rebalance_cnt;
00228 extern size_t rb_num_deletes, rb_del_rebalance_cnt;
00229 void reset_rb_stats();
00230 void print_rb_stats (int reset);
00231 #define DO_IF_RB_STATS(X) X
00232 #else
00233 #define DO_IF_RB_STATS(X)
00234 #endif
00235
00236 #endif