00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "log.h"
00022 #include "tree.h"
00023
00024 typedef struct AVTreeNode {
00025 struct AVTreeNode *child[2];
00026 void *elem;
00027 int state;
00028 } AVTreeNode;
00029
00030 const int av_tree_node_size = sizeof(AVTreeNode);
00031
00032 void *av_tree_find(const AVTreeNode *t, void *key,
00033 int (*cmp)(void *key, const void *b), void *next[2])
00034 {
00035 if (t) {
00036 unsigned int v = cmp(key, t->elem);
00037 if (v) {
00038 if (next) next[v >> 31] = t->elem;
00039 return av_tree_find(t->child[(v >> 31) ^ 1], key, cmp, next);
00040 } else {
00041 if (next) {
00042 av_tree_find(t->child[0], key, cmp, next);
00043 av_tree_find(t->child[1], key, cmp, next);
00044 }
00045 return t->elem;
00046 }
00047 }
00048 return NULL;
00049 }
00050
00051 void *av_tree_insert(AVTreeNode **tp, void *key,
00052 int (*cmp)(void *key, const void *b), AVTreeNode **next)
00053 {
00054 AVTreeNode *t = *tp;
00055 if (t) {
00056 unsigned int v = cmp(t->elem, key);
00057 void *ret;
00058 if (!v) {
00059 if (*next)
00060 return t->elem;
00061 else if (t->child[0] || t->child[1]) {
00062 int i = !t->child[0];
00063 void *next_elem[2];
00064 av_tree_find(t->child[i], key, cmp, next_elem);
00065 key = t->elem = next_elem[i];
00066 v = -i;
00067 } else {
00068 *next = t;
00069 *tp = NULL;
00070 return NULL;
00071 }
00072 }
00073 ret = av_tree_insert(&t->child[v >> 31], key, cmp, next);
00074 if (!ret) {
00075 int i = (v >> 31) ^ !!*next;
00076 AVTreeNode **child = &t->child[i];
00077 t->state += 2 * i - 1;
00078
00079 if (!(t->state & 1)) {
00080 if (t->state) {
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 if (( *child )->state * 2 == -t->state) {
00100 *tp = (*child)->child[i ^ 1];
00101 (*child)->child[i ^ 1] = (*tp)->child[i];
00102 (*tp)->child[i] = *child;
00103 *child = ( *tp )->child[i ^ 1];
00104 (*tp)->child[i ^ 1] = t;
00105
00106 (*tp)->child[0]->state = -((*tp)->state > 0);
00107 (*tp)->child[1]->state = (*tp)->state < 0;
00108 (*tp)->state = 0;
00109 } else {
00110 *tp = *child;
00111 *child = (*child)->child[i ^ 1];
00112 (*tp)->child[i ^ 1] = t;
00113 if ((*tp)->state) t->state = 0;
00114 else t->state >>= 1;
00115 (*tp)->state = -t->state;
00116 }
00117 }
00118 }
00119 if (!(*tp)->state ^ !!*next)
00120 return key;
00121 }
00122 return ret;
00123 } else {
00124 *tp = *next;
00125 *next = NULL;
00126 if (*tp) {
00127 (*tp)->elem = key;
00128 return NULL;
00129 } else
00130 return key;
00131 }
00132 }
00133
00134 void av_tree_destroy(AVTreeNode *t)
00135 {
00136 if (t) {
00137 av_tree_destroy(t->child[0]);
00138 av_tree_destroy(t->child[1]);
00139 av_free(t);
00140 }
00141 }
00142
00143 void av_tree_enumerate(AVTreeNode *t, void *opaque,
00144 int (*cmp)(void *opaque, void *elem),
00145 int (*enu)(void *opaque, void *elem))
00146 {
00147 if (t) {
00148 int v = cmp ? cmp(opaque, t->elem) : 0;
00149 if (v >= 0)
00150 av_tree_enumerate(t->child[0], opaque, cmp, enu);
00151 if (v == 0)
00152 enu(opaque, t->elem);
00153 if (v <= 0)
00154 av_tree_enumerate(t->child[1], opaque, cmp, enu);
00155 }
00156 }
00157
00158 #ifdef TEST
00159
00160 #include "lfg.h"
00161
00162 static int check(AVTreeNode *t)
00163 {
00164 if (t) {
00165 int left = check(t->child[0]);
00166 int right = check(t->child[1]);
00167
00168 if (left>999 || right>999)
00169 return 1000;
00170 if (right - left != t->state)
00171 return 1000;
00172 if (t->state>1 || t->state<-1)
00173 return 1000;
00174 return FFMAX(left, right) + 1;
00175 }
00176 return 0;
00177 }
00178
00179 static void print(AVTreeNode *t, int depth)
00180 {
00181 int i;
00182 for (i = 0; i < depth * 4; i++) av_log(NULL, AV_LOG_ERROR, " ");
00183 if (t) {
00184 av_log(NULL, AV_LOG_ERROR, "Node %p %2d %p\n", t, t->state, t->elem);
00185 print(t->child[0], depth + 1);
00186 print(t->child[1], depth + 1);
00187 } else
00188 av_log(NULL, AV_LOG_ERROR, "NULL\n");
00189 }
00190
00191 static int cmp(void *a, const void *b)
00192 {
00193 return (uint8_t *) a - (const uint8_t *) b;
00194 }
00195
00196 int main (void)
00197 {
00198 int i;
00199 void *k;
00200 AVTreeNode *root = NULL, *node = NULL;
00201 AVLFG prng;
00202
00203 av_lfg_init(&prng, 1);
00204
00205 for (i = 0; i < 10000; i++) {
00206 int j = av_lfg_get(&prng) % 86294;
00207 if (check(root) > 999) {
00208 av_log(NULL, AV_LOG_ERROR, "FATAL error %d\n", i);
00209 print(root, 0);
00210 return -1;
00211 }
00212 av_log(NULL, AV_LOG_ERROR, "inserting %4d\n", j);
00213 if (!node)
00214 node = av_mallocz(av_tree_node_size);
00215 av_tree_insert(&root, (void *) (j + 1), cmp, &node);
00216
00217 j = av_lfg_get(&prng) % 86294;
00218 {
00219 AVTreeNode *node2 = NULL;
00220 av_log(NULL, AV_LOG_ERROR, "removing %4d\n", j);
00221 av_tree_insert(&root, (void *) (j + 1), cmp, &node2);
00222 k = av_tree_find(root, (void *) (j + 1), cmp, NULL);
00223 if (k)
00224 av_log(NULL, AV_LOG_ERROR, "removal failure %d\n", i);
00225 }
00226 }
00227 return 0;
00228 }
00229 #endif