Removed array bag, and restructured the tree bag to be WMBag
[wmaker-crm.git] / WINGs / bagtree.c
blob9787ad1cf13945c4c24fc8687853c6f5e52d9c34
5 #include <stdlib.h>
6 #include <string.h>
8 #include "WUtil.h"
11 typedef struct W_Node {
12 struct W_Node *parent;
13 struct W_Node *left;
14 struct W_Node *right;
15 int color;
17 void *data;
18 int index;
19 } W_Node;
22 typedef struct W_Bag {
23 W_Node *root;
25 W_Node *nil; /* sentinel */
27 int count;
29 void (*destructor)(void *item);
30 } W_Bag;
33 #if 0
34 static int getItemCount(WMBag *self);
35 static int appendBag(WMBag *self, WMBag *bag);
36 static int putInBag(WMBag *self, void *item);
37 static int insertInBag(WMBag *self, int index, void *item);
38 static int removeFromBag(WMBag *bag, void *item);
39 static int eraseFromBag(WMBag *bag, int index);
40 static int deleteFromBag(WMBag *bag, int index);
41 static void *getFromBag(WMBag *bag, int index);
42 static int countInBag(WMBag *bag, void *item);
43 static int firstInBag(WMBag *bag, void *item);
44 static void *replaceInBag(WMBag *bag, int index, void *item);
45 static int sortBag(WMBag *bag, int (*comparer)(const void*, const void*));
46 static void emptyBag(WMBag *bag);
47 static void freeBag(WMBag *bag);
48 static void mapBag(WMBag *bag, void (*function)(void*, void*), void *data);
49 static int findInBag(WMBag *bag, int (*match)(void*,void*), void *data);
50 static void *first(WMBag *bag, WMBagIterator *ptr);
51 static void *last(WMBag *bag, WMBagIterator *ptr);
52 static void *next(WMBag *bag, WMBagIterator *ptr);
53 static void *previous(WMBag *bag, WMBagIterator *ptr);
54 static void *iteratorAtIndex(WMBag *bag, int index, WMBagIterator *ptr);
55 static int indexForIterator(WMBag *bag, WMBagIterator ptr);
56 #endif
59 #define IS_LEFT(node) (node == node->parent->left)
60 #define IS_RIGHT(node) (node == node->parent->right)
64 static void
65 leftRotate(W_Bag *tree, W_Node *node)
67 W_Node *node2;
69 node2 = node->right;
70 node->right = node2->left;
72 node2->left->parent = node;
74 node2->parent = node->parent;
76 if (node->parent == tree->nil) {
77 tree->root = node2;
78 } else {
79 if (IS_LEFT(node)) {
80 node->parent->left = node2;
81 } else {
82 node->parent->right = node2;
85 node2->left = node;
86 node->parent = node2;
91 static void
92 rightRotate(W_Bag *tree, W_Node *node)
94 W_Node *node2;
96 node2 = node->left;
97 node->left = node2->right;
99 node2->right->parent = node;
101 node2->parent = node->parent;
103 if (node->parent == tree->nil) {
104 tree->root = node2;
105 } else {
106 if (IS_LEFT(node)) {
107 node->parent->left = node2;
108 } else {
109 node->parent->right = node2;
112 node2->right = node;
113 node->parent = node2;
117 static void
118 treeInsert(W_Bag *tree, W_Node *node)
120 W_Node *y = tree->nil;
121 W_Node *x = tree->root;
123 while (x != tree->nil) {
124 y = x;
125 if (node->index <= x->index)
126 x = x->left;
127 else
128 x = x->right;
130 node->parent = y;
131 if (y == tree->nil)
132 tree->root = node;
133 else if (node->index <= y->index)
134 y->left = node;
135 else
136 y->right = node;
140 static void
141 rbTreeInsert(W_Bag *tree, W_Node *node)
143 W_Node *y;
145 treeInsert(tree, node);
147 node->color = 'R';
149 while (node != tree->root && node->parent->color == 'R') {
150 if (IS_LEFT(node->parent)) {
151 y = node->parent->parent->right;
153 if (y->color == 'R') {
155 node->parent->color = 'B';
156 y->color = 'B';
157 node->parent->parent->color = 'R';
158 node = node->parent->parent;
160 } else {
161 if (IS_RIGHT(node)) {
162 node = node->parent;
163 leftRotate(tree, node);
165 node->parent->color = 'B';
166 node->parent->parent->color = 'R';
167 rightRotate(tree, node->parent->parent);
169 } else {
170 y = node->parent->parent->left;
172 if (y->color == 'R') {
174 node->parent->color = 'B';
175 y->color = 'B';
176 node->parent->parent->color = 'R';
177 node = node->parent->parent;
179 } else {
180 if (IS_LEFT(node)) {
181 node = node->parent;
182 rightRotate(tree, node);
184 node->parent->color = 'B';
185 node->parent->parent->color = 'R';
186 leftRotate(tree, node->parent->parent);
190 tree->root->color = 'B';
194 static void
195 rbDeleteFixup(W_Bag *tree, W_Node *node)
197 W_Node *w;
199 while (node != tree->root && node->color == 'B') {
200 if (IS_LEFT(node)) {
201 w = node->parent->right;
202 if (w->color == 'R') {
203 w->color = 'B';
204 node->parent->color = 'R';
205 leftRotate(tree, node->parent);
206 w = node->parent->right;
208 if (w->left->color == 'B' && w->right->color == 'B') {
209 w->color = 'R';
210 node = node->parent;
211 } else {
212 if (w->right->color == 'B') {
213 w->left->color = 'B';
214 w->color = 'R';
215 rightRotate(tree, w);
216 w = node->parent->right;
218 w->color = node->parent->color;
219 node->parent->color = 'B';
220 w->right->color = 'B';
221 leftRotate(tree, node->parent);
222 node = tree->root;
224 } else {
225 w = node->parent->left;
226 if (w->color == 'R') {
227 w->color = 'B';
228 node->parent->color = 'R';
229 rightRotate(tree, node->parent);
230 w = node->parent->left;
232 if (w->left->color == 'B' && w->right->color == 'B') {
233 w->color = 'R';
234 node = node->parent;
235 } else {
236 if (w->left->color == 'B') {
237 w->right->color = 'B';
238 w->color = 'R';
239 leftRotate(tree, w);
240 w = node->parent->left;
242 w->color = node->parent->color;
243 node->parent->color = 'B';
244 w->left->color = 'B';
245 rightRotate(tree, node->parent);
246 node = tree->root;
250 node->color = 'B';
255 static W_Node*
256 treeMinimum(W_Node *node, W_Node *nil)
258 while (node->left != nil)
259 node = node->left;
260 return node;
264 static W_Node*
265 treeMaximum(W_Node *node, W_Node *nil)
267 while (node->right != nil)
268 node = node->right;
269 return node;
273 static W_Node*
274 treeSuccessor(W_Node *node, W_Node *nil)
276 W_Node *y;
278 if (node->right != nil) {
279 return treeMinimum(node->right, nil);
281 y = node->parent;
282 while (y != nil && node == y->right) {
283 node = y;
284 y = y->parent;
286 return y;
290 static W_Node*
291 treePredecessor(W_Node *node, W_Node *nil)
293 W_Node *y;
295 if (node->left != nil) {
296 return treeMaximum(node->left, nil);
298 y = node->parent;
299 while (y != nil && node == y->left) {
300 node = y;
301 y = y->parent;
303 return y;
307 static W_Node*
308 rbTreeDelete(W_Bag *tree, W_Node *node)
310 W_Node *nil = tree->nil;
311 W_Node *x, *y;
313 if (node->left == nil || node->right == nil) {
314 y = node;
315 } else {
316 y = treeSuccessor(node, nil);
319 if (y->left != nil) {
320 x = y->left;
321 } else {
322 x = y->right;
325 x->parent = y->parent;
327 if (y->parent == nil) {
328 tree->root = x;
329 } else {
330 if (IS_LEFT(y)) {
331 y->parent->left = x;
332 } else {
333 y->parent->right = x;
336 if (y != node) {
337 node->index = y->index;
338 node->data = y->data;
340 if (y->color == 'B') {
341 rbDeleteFixup(tree, x);
344 return y;
348 static W_Node*
349 treeSearch(W_Node *root, W_Node *nil, int index)
351 if (root == nil || root->index == index) {
352 return root;
355 if (index < root->index) {
356 return treeSearch(root->left, nil, index);
357 } else {
358 return treeSearch(root->right, nil, index);
363 static W_Node*
364 treeFind(W_Node *root, W_Node *nil, void *data)
366 W_Node *tmp;
368 if (root == nil || root->data == data)
369 return root;
371 tmp = treeFind(root->left, nil, data);
372 if (tmp != nil)
373 return tmp;
375 tmp = treeFind(root->right, nil, data);
377 return tmp;
382 #if 0
383 static char buf[512];
385 static void printNodes(W_Node *node, W_Node *nil, int depth)
387 if (node == nil) {
388 return;
391 printNodes(node->left, nil, depth+1);
393 memset(buf, ' ', depth*2);
394 buf[depth*2] = 0;
395 if (IS_LEFT(node))
396 printf("%s/(%2i\n", buf, node->index);
397 else
398 printf("%s\\(%2i\n", buf, node->index);
400 printNodes(node->right, nil, depth+1);
404 void PrintTree(WMBag *bag)
406 W_TreeBag *tree = (W_TreeBag*)bag->data;
408 printNodes(tree->root, tree->nil, 0);
410 #endif
413 //#define SELF ((W_TreeBag*)self->data)
415 WMBag*
416 WMCreateTreeBag(void)
418 return WMCreateTreeBagWithDestructor(NULL);
422 WMBag*
423 WMCreateTreeBagWithDestructor(void (*destructor)(void*))
425 WMBag *bag;
427 bag = wmalloc(sizeof(WMBag));
429 memset(bag, 0, sizeof(WMBag));
431 bag->nil = wmalloc(sizeof(W_Node));
432 memset(bag->nil, 0, sizeof(W_Node));
433 bag->nil->left = bag->nil->right = bag->nil->parent = bag->nil;
434 bag->nil->index = WBNotFound;
436 bag->root = bag->nil;
438 bag->destructor = destructor;
440 return bag;
445 WMGetBagItemCount(WMBag *self)
447 return self->count;
452 WMAppendBag(WMBag *self, WMBag *bag)
454 WMBagIterator ptr;
455 void *data;
457 for (data = WMBagFirst(bag, &ptr); data != NULL; data = WMBagNext(bag, &ptr)) {
458 if (!WMPutInBag(self, data))
459 return 0;
462 return 1;
465 //extern WMBag *bla;
468 WMPutInBag(WMBag *self, void *item)
470 W_Node *ptr;
473 ptr = wmalloc(sizeof(W_Node));
475 ptr->data = item;
476 ptr->index = self->count;
477 ptr->left = self->nil;
478 ptr->right = self->nil;
479 ptr->parent = self->nil;
481 rbTreeInsert(self, ptr);
483 self->count++;
485 return 1;
490 WMInsertInBag(WMBag *self, int index, void *item)
492 W_Node *ptr;
494 ptr = wmalloc(sizeof(W_Node));
496 ptr->data = item;
497 ptr->index = index;
498 ptr->left = self->nil;
499 ptr->right = self->nil;
500 ptr->parent = self->nil;
502 rbTreeInsert(self, ptr);
504 while ((ptr = treeSuccessor(ptr, self->nil)) != self->nil) {
505 ptr->index++;
509 self->count++;
511 return 1;
516 WMRemoveFromBag(WMBag *self, void *item)
518 W_Node *ptr = treeFind(self->root, self->nil, item);
520 if (ptr != self->nil) {
521 W_Node *tmp;
523 self->count--;
525 tmp = treeSuccessor(ptr, self->nil);
526 while (tmp != self->nil) {
527 tmp->index--;
528 tmp = treeSuccessor(tmp, self->nil);
531 ptr = rbTreeDelete(self, ptr);
532 if (self->destructor)
533 self->destructor(ptr->data);
534 free(ptr);
536 return 1;
537 } else {
538 return 0;
544 WMEraseFromBag(WMBag *self, int index)
546 W_Node *ptr = treeSearch(self->root, self->nil, index);
548 if (ptr != self->nil) {
550 self->count--;
552 ptr = rbTreeDelete(self, ptr);
553 if (self->destructor)
554 self->destructor(ptr->data);
555 free(ptr);
557 wassertrv(self->count == 0||self->root->index >= 0, 1);
559 return 1;
560 } else {
561 return 0;
567 WMDeleteFromBag(WMBag *self, int index)
569 W_Node *ptr = treeSearch(self->root, self->nil, index);
571 if (ptr != self->nil) {
572 W_Node *tmp;
574 self->count--;
576 tmp = treeSuccessor(ptr, self->nil);
577 while (tmp != self->nil) {
578 tmp->index--;
579 tmp = treeSuccessor(tmp, self->nil);
582 ptr = rbTreeDelete(self, ptr);
583 if (self->destructor)
584 self->destructor(ptr->data);
585 free(ptr);
587 wassertrv(self->count == 0||self->root->index >= 0, 1);
589 return 1;
590 } else {
591 return 0;
596 void*
597 WMGetFromBag(WMBag *self, int index)
599 W_Node *node;
601 node = treeSearch(self->root, self->nil, index);
602 if (node != self->nil)
603 return node->data;
604 else
605 return NULL;
610 WMGetFirstInBag(WMBag *self, void *item)
612 W_Node *node;
614 node = treeFind(self->root, self->nil, item);
615 if (node != self->nil)
616 return node->index;
617 else
618 return WBNotFound;
623 static int
624 treeCount(W_Node *root, W_Node *nil, void *item)
626 int count = 0;
628 if (root == nil)
629 return 0;
631 if (root->data == item)
632 count++;
634 if (root->left != nil)
635 count += treeCount(root->left, nil, item);
637 if (root->right != nil)
638 count += treeCount(root->right, nil, item);
640 return count;
646 WMCountInBag(WMBag *self, void *item)
648 return treeCount(self->root, self->nil, item);
652 void*
653 WMReplaceInBag(WMBag *self, int index, void *item)
655 W_Node *ptr = treeSearch(self->root, self->nil, index);
656 void *old = NULL;
658 if (item == NULL) {
659 self->count--;
660 ptr = rbTreeDelete(self, ptr);
661 if (self->destructor)
662 self->destructor(ptr->data);
663 free(ptr);
664 } else if (ptr != self->nil) {
665 old = ptr->data;
666 ptr->data = item;
667 } else {
668 W_Node *ptr;
670 ptr = wmalloc(sizeof(W_Node));
672 ptr->data = item;
673 ptr->index = index;
674 ptr->left = self->nil;
675 ptr->right = self->nil;
676 ptr->parent = self->nil;
678 rbTreeInsert(self, ptr);
680 self->count++;
683 return old;
688 WMSortBag(WMBag *self, int (*comparer)(const void*, const void*))
690 void **items;
691 W_Node *tmp;
692 int i;
694 if (self->count == 0)
695 return 1;
697 items = wmalloc(sizeof(void*)*self->count);
698 i = 0;
700 tmp = treeMinimum(self->root, self->nil);
701 while (tmp != self->nil) {
702 items[i++] = tmp->data;
703 tmp = treeSuccessor(tmp, self->nil);
706 qsort(&items[0], self->count, sizeof(void*), comparer);
708 i = 0;
709 tmp = treeMinimum(self->root, self->nil);
710 while (tmp != self->nil) {
711 tmp->index = i;
712 tmp->data = items[i++];
713 tmp = treeSuccessor(tmp, self->nil);
716 wfree(items);
718 return 1;
722 static void
723 deleteTree(WMBag *self, W_Node *node)
725 if (node == self->nil)
726 return;
728 deleteTree(self, node->left);
730 if (self->destructor)
731 self->destructor(node->data);
733 deleteTree(self, node->right);
735 free(node);
739 void
740 WMEmptyBag(WMBag *self)
742 deleteTree(self, self->root);
743 self->root = self->nil;
744 self->count = 0;
748 void
749 WMFreeBag(WMBag *self)
751 WMEmptyBag(self);
753 free(self->nil);
755 free(self);
759 static void
760 mapTree(W_Bag *tree, W_Node *node, void (*function)(void*, void*), void *data)
762 if (node == tree->nil)
763 return;
765 mapTree(tree, node->left, function, data);
767 (*function)(node->data, data);
769 mapTree(tree, node->right, function, data);
773 void
774 WMMapBag(WMBag *self, void (*function)(void*, void*), void *data)
776 mapTree(self, self->root, function, data);
781 static int
782 findInTree(W_Bag *tree, W_Node *node, int (*function)(void*,void*), void *cdata)
784 int index;
786 if (node == tree->nil)
787 return WBNotFound;
789 index = findInTree(tree, node->left, function, cdata);
790 if (index != WBNotFound)
791 return index;
793 if ((*function)(node->data, cdata)) {
794 return node->index;
797 return findInTree(tree, node->right, function, cdata);
802 WMFindInBag(WMBag *self, int (*match)(void*,void*), void *cdata)
804 return findInTree(self, self->root, match, cdata);
808 void*
809 WMBagFirst(WMBag *self, WMBagIterator *ptr)
811 W_Node *node;
813 node = treeMinimum(self->root, self->nil);
815 if (node == self->nil) {
816 *ptr = NULL;
818 return NULL;
819 } else {
820 *ptr = node;
822 return node->data;
827 void*
828 WMBagLast(WMBag *self, WMBagIterator *ptr)
831 W_Node *node;
833 node = treeMaximum(self->root, self->nil);
835 if (node == self->nil) {
836 *ptr = NULL;
838 return NULL;
839 } else {
840 *ptr = node;
842 return node->data;
847 void*
848 WMBagNext(WMBag *self, WMBagIterator *ptr)
850 W_Node *node;
852 if (*ptr == NULL)
853 return NULL;
855 node = treeSuccessor(*ptr, self->nil);
857 if (node == self->nil) {
858 *ptr = NULL;
860 return NULL;
861 } else {
862 *ptr = node;
864 return node->data;
869 void*
870 WMBagPrevious(WMBag *self, WMBagIterator *ptr)
872 W_Node *node;
874 if (*ptr == NULL)
875 return NULL;
877 node = treePredecessor(*ptr, self->nil);
879 if (node == self->nil) {
880 *ptr = NULL;
882 return NULL;
883 } else {
884 *ptr = node;
886 return node->data;
891 void*
892 WMBagIteratorAtIndex(WMBag *self, int index, WMBagIterator *ptr)
894 W_Node *node;
896 node = treeSearch(self->root, self->nil, index);
898 if (node == self->nil) {
899 *ptr = NULL;
900 return NULL;
901 } else {
902 *ptr = node;
903 return node->data;
909 WMBagIndexForIterator(WMBag *bag, WMBagIterator ptr)
911 return ((W_Node*)ptr)->index;