5 enum color { RED, BLACK };
9 struct tm_node *left, *right, *parent;
11 struct map_pair *pair;
26 tm_new(comparator *cmp, void *cmp_aux)
28 treemap *t = malloc(sizeof *t);
45 tm_dtor(treemap *t, dtor *key_dtor, dtor *val_dtor, void *dtor_aux)
49 t->key_dtor = key_dtor;
50 t->val_dtor = val_dtor;
51 t->dtor_aux = dtor_aux;
55 _tm_length(const struct tm_node *n)
59 return 1 + _tm_length(n->left) + _tm_length(n->right);
63 tm_length(const treemap *t)
65 return t ? _tm_length(t->root) : 0;
69 tm_is_empty(const treemap *t)
71 return tm_length(t) == 0;
75 _tm_at(const treemap *t, const struct tm_node *n, const void *key)
79 int x = t->cmp(n->pair->k, key, t->cmp_aux);
83 return _tm_at(t, n->left, key);
84 return _tm_at(t, n->right, key);
88 tm_at(const treemap *t, const void *key)
90 return t ? _tm_at(t, t->root, key) : NULL;
94 _tm_left_rotate(treemap *t, struct tm_node *x)
96 struct tm_node *y = x->right;
100 y->parent = x->parent;
103 else if (x == x->parent->left)
106 x->parent->right = y;
112 _tm_right_rotate(treemap *t, struct tm_node *x)
114 struct tm_node *y = x->left;
117 y->right->parent = x;
118 y->parent = x->parent;
121 else if (x == x->parent->right)
122 x->parent->right = y;
129 static struct tm_node *
130 _tm_insert(treemap *t, void *key, void *val)
132 struct tm_node *parent = NULL, *cursor = t->root;
136 int diff = t->cmp(key, cursor->pair->k, t->cmp_aux);
139 if (val != cursor->pair->v && t->val_dtor)
140 t->val_dtor(cursor->pair->v, t->dtor_aux);
141 cursor->pair->v = val;
145 cursor = cursor->left;
147 cursor = cursor->right;
150 struct map_pair *p = malloc(sizeof *p);
151 struct tm_node *node = malloc(sizeof *node);
158 *p = (struct map_pair){
161 *node = (struct tm_node){
162 .color = RED, .parent = parent, .pair = p
166 else if (t->cmp(key, parent->pair->k, t->cmp_aux))
169 parent->right = node;
174 _tm_insert_fixup(treemap *t, struct tm_node *x)
176 struct tm_node *uncle;
177 while (x->parent && x->parent->color == RED)
179 if (x->parent->parent->left == x->parent)
181 uncle = x->parent->parent->right;
182 if (uncle->color == RED)
184 x->parent->parent->color = RED;
185 x->parent->color = BLACK;
186 uncle->color = BLACK;
187 x = x->parent->parent;
191 if (x == x->parent->right)
194 _tm_left_rotate(t, x);
196 x->parent->color = BLACK;
197 x->parent->parent->color = RED;
198 _tm_right_rotate(t, x->parent->parent);
203 uncle = x->parent->parent->left;
204 if (uncle->color == RED)
206 x->parent->parent->color = RED;
207 x->parent->color = BLACK;
208 uncle->color = BLACK;
209 x = x->parent->parent;
213 if (x == x->parent->left)
216 _tm_right_rotate(t, x);
218 x->parent->color = BLACK;
219 x->parent->parent->color = RED;
220 _tm_left_rotate(t, x->parent->parent);
224 t->root->color = BLACK;
228 tm_insert(treemap *t, void *key, void *val)
230 struct tm_node *n = _tm_insert(t, key, val);
233 _tm_insert_fixup(t, n);
238 tm_remove(treemap *t, void *key)