comparison src/lib-index/mail-tree-redblack.c @ 903:fd8888f6f037 HEAD

Naming style changes, finally got tired of most of the typedefs. Also the previous enum -> macro change reverted so that we don't use the highest bit anymore, that's incompatible with old indexes so they will be rebuilt.
author Timo Sirainen <tss@iki.fi>
date Sun, 05 Jan 2003 15:09:51 +0200
parents 41dde6822eea
children e291bf36d57f
comparison
equal deleted inserted replaced
902:5043e48c022f 903:fd8888f6f037
82 ** red and black nodes) is only twice as long as the shortest 82 ** red and black nodes) is only twice as long as the shortest
83 ** path (all black nodes). Thus the tree remains fairly balanced. 83 ** path (all black nodes). Thus the tree remains fairly balanced.
84 */ 84 */
85 85
86 static unsigned int 86 static unsigned int
87 rb_alloc(MailTree *tree) 87 rb_alloc(struct mail_tree *tree)
88 { 88 {
89 unsigned int x; 89 unsigned int x;
90 90
91 if (tree->mmap_used_length == tree->mmap_full_length) { 91 if (tree->mmap_used_length == tree->mmap_full_length) {
92 if (!_mail_tree_grow(tree)) 92 if (!_mail_tree_grow(tree))
93 return RBNULL; 93 return RBNULL;
94 } 94 }
95 95
96 i_assert(tree->header->used_file_size == tree->mmap_used_length); 96 i_assert(tree->header->used_file_size == tree->mmap_used_length);
97 i_assert(tree->mmap_used_length + sizeof(MailTreeNode) <= 97 i_assert(tree->mmap_used_length + sizeof(struct mail_tree_node) <=
98 tree->mmap_full_length); 98 tree->mmap_full_length);
99 99
100 x = (tree->mmap_used_length - sizeof(MailTreeHeader)) / 100 x = (tree->mmap_used_length - sizeof(struct mail_tree_header)) /
101 sizeof(MailTreeNode); 101 sizeof(struct mail_tree_node);
102 102
103 tree->header->used_file_size += sizeof(MailTreeNode); 103 tree->header->used_file_size += sizeof(struct mail_tree_node);
104 tree->mmap_used_length += sizeof(MailTreeNode); 104 tree->mmap_used_length += sizeof(struct mail_tree_node);
105 105
106 memset(&tree->node_base[x], 0, sizeof(MailTreeNode)); 106 memset(&tree->node_base[x], 0, sizeof(struct mail_tree_node));
107 return x; 107 return x;
108 } 108 }
109 109
110 static void 110 static void
111 rb_move(MailTree *tree, unsigned int src, unsigned int dest) 111 rb_move(struct mail_tree *tree, unsigned int src, unsigned int dest)
112 { 112 {
113 MailTreeNode *node = tree->node_base; 113 struct mail_tree_node *node = tree->node_base;
114 114
115 /* update parent */ 115 /* update parent */
116 if (node[src].up != RBNULL) { 116 if (node[src].up != RBNULL) {
117 if (node[node[src].up].left == src) 117 if (node[node[src].up].left == src)
118 node[node[src].up].left = dest; 118 node[node[src].up].left = dest;
128 128
129 /* update root */ 129 /* update root */
130 if (tree->header->root == src) 130 if (tree->header->root == src)
131 tree->header->root = dest; 131 tree->header->root = dest;
132 132
133 memcpy(&node[dest], &node[src], sizeof(MailTreeNode)); 133 memcpy(&node[dest], &node[src], sizeof(struct mail_tree_node));
134 memset(&node[src], 0, sizeof(MailTreeNode)); 134 memset(&node[src], 0, sizeof(struct mail_tree_node));
135 } 135 }
136 136
137 static void 137 static void
138 rb_free(MailTree *tree, unsigned int x) 138 rb_free(struct mail_tree *tree, unsigned int x)
139 { 139 {
140 unsigned int last; 140 unsigned int last;
141 141
142 i_assert(tree->mmap_used_length >= 142 i_assert(tree->mmap_used_length >=
143 sizeof(MailTreeHeader) + sizeof(MailTreeNode)); 143 sizeof(struct mail_tree_header) +
144 sizeof(struct mail_tree_node));
144 145
145 /* get index to last used record */ 146 /* get index to last used record */
146 last = (tree->mmap_used_length - sizeof(MailTreeHeader)) / 147 last = (tree->mmap_used_length - sizeof(struct mail_tree_header)) /
147 sizeof(MailTreeNode) - 1; 148 sizeof(struct mail_tree_node) - 1;
148 149
149 if (last != x) { 150 if (last != x) {
150 /* move it over the one we want free'd */ 151 /* move it over the one we want free'd */
151 rb_move(tree, last, x); 152 rb_move(tree, last, x);
152 } 153 }
153 154
154 /* mark the moved node unused */ 155 /* mark the moved node unused */
155 tree->mmap_used_length -= sizeof(MailTreeNode); 156 tree->mmap_used_length -= sizeof(struct mail_tree_node);
156 tree->header->used_file_size -= sizeof(MailTreeNode); 157 tree->header->used_file_size -= sizeof(struct mail_tree_node);
157 158
158 _mail_tree_truncate(tree); 159 _mail_tree_truncate(tree);
159 } 160 }
160 161
161 /* 162 /*
175 ** X += C+1 X -= C+1 176 ** X += C+1 X -= C+1
176 ** Y -= A+1 Y += A+1 177 ** Y -= A+1 Y += A+1
177 */ 178 */
178 179
179 static void 180 static void
180 rb_left_rotate(MailTree *tree, unsigned int x) 181 rb_left_rotate(struct mail_tree *tree, unsigned int x)
181 { 182 {
182 MailTreeNode *node = tree->node_base; 183 struct mail_tree_node *node = tree->node_base;
183 unsigned int y, a_nodes, c_nodes; 184 unsigned int y, a_nodes, c_nodes;
184 185
185 i_assert(x != RBNULL); 186 i_assert(x != RBNULL);
186 i_assert(node[x].right != RBNULL); 187 i_assert(node[x].right != RBNULL);
187 188
220 NODE_COUNT_ADD(node[x], -(c_nodes+1)); 221 NODE_COUNT_ADD(node[x], -(c_nodes+1));
221 NODE_COUNT_ADD(node[y], a_nodes+1); 222 NODE_COUNT_ADD(node[y], a_nodes+1);
222 } 223 }
223 224
224 static void 225 static void
225 rb_right_rotate(MailTree *tree, unsigned int y) 226 rb_right_rotate(struct mail_tree *tree, unsigned int y)
226 { 227 {
227 MailTreeNode *node = tree->node_base; 228 struct mail_tree_node *node = tree->node_base;
228 unsigned int x, a_nodes, c_nodes; 229 unsigned int x, a_nodes, c_nodes;
229 230
230 i_assert(y != RBNULL); 231 i_assert(y != RBNULL);
231 i_assert(node[y].left != RBNULL); 232 i_assert(node[y].left != RBNULL);
232 233
267 } 268 }
268 269
269 /* Return index to the smallest key greater than x 270 /* Return index to the smallest key greater than x
270 */ 271 */
271 static unsigned int 272 static unsigned int
272 rb_successor(MailTree *tree, unsigned int x) 273 rb_successor(struct mail_tree *tree, unsigned int x)
273 { 274 {
274 MailTreeNode *node = tree->node_base; 275 struct mail_tree_node *node = tree->node_base;
275 unsigned int y; 276 unsigned int y;
276 277
277 if (node[x].right != RBNULL) { 278 if (node[x].right != RBNULL) {
278 /* If right is not NULL then go right one and 279 /* If right is not NULL then go right one and
279 ** then keep going left until we find a node with 280 ** then keep going left until we find a node with
297 return y; 298 return y;
298 } 299 }
299 300
300 /* Restore the reb-black properties after insert */ 301 /* Restore the reb-black properties after insert */
301 static int 302 static int
302 rb_insert_fix(MailTree *tree, unsigned int z) 303 rb_insert_fix(struct mail_tree *tree, unsigned int z)
303 { 304 {
304 MailTreeNode *node = tree->node_base; 305 struct mail_tree_node *node = tree->node_base;
305 unsigned int x, y, x_up_up; 306 unsigned int x, y, x_up_up;
306 307
307 /* color this new node red */ 308 /* color this new node red */
308 NODE_SET_RED(node[z]); 309 NODE_SET_RED(node[z]);
309 310
378 return z; 379 return z;
379 } 380 }
380 381
381 /* Restore the reb-black properties after a delete */ 382 /* Restore the reb-black properties after a delete */
382 static void 383 static void
383 rb_delete_fix(MailTree *tree, unsigned int x) 384 rb_delete_fix(struct mail_tree *tree, unsigned int x)
384 { 385 {
385 MailTreeNode *node = tree->node_base; 386 struct mail_tree_node *node = tree->node_base;
386 unsigned int w; 387 unsigned int w;
387 388
388 while (x != tree->header->root && IS_NODE_BLACK(node[x])) { 389 while (x != tree->header->root && IS_NODE_BLACK(node[x])) {
389 if (x == node[node[x].up].left) { 390 if (x == node[node[x].up].left) {
390 w = node[node[x].up].right; 391 w = node[node[x].up].right;
488 */ 489 */
489 490
490 /* Delete the node z, and free up the space 491 /* Delete the node z, and free up the space
491 */ 492 */
492 static void 493 static void
493 rb_delete(MailTree *tree, unsigned int z) 494 rb_delete(struct mail_tree *tree, unsigned int z)
494 { 495 {
495 MailTreeNode *node = tree->node_base; 496 struct mail_tree_node *node = tree->node_base;
496 unsigned int x, y, b; 497 unsigned int x, y, b;
497 498
498 if (node[z].left == RBNULL || node[z].right == RBNULL) { 499 if (node[z].left == RBNULL || node[z].right == RBNULL) {
499 y = z; 500 y = z;
500 b = RBNULL; 501 b = RBNULL;
548 rb_free(tree, y); 549 rb_free(tree, y);
549 } 550 }
550 551
551 #ifdef DEBUG_TREE 552 #ifdef DEBUG_TREE
552 int 553 int
553 rb_check1(MailTree *tree, unsigned int x) 554 rb_check1(struct mail_tree *tree, unsigned int x)
554 { 555 {
555 MailTreeNode *node = tree->node_base; 556 struct mail_tree_node *node = tree->node_base;
556 557
557 if (IS_NODE_RED(node[x])) { 558 if (IS_NODE_RED(node[x])) {
558 if (!IS_NODE_BLACK(node[node[x].left]) || 559 if (!IS_NODE_BLACK(node[node[x].left]) ||
559 !IS_NODE_BLACK(node[node[x].right])) { 560 !IS_NODE_BLACK(node[node[x].right])) {
560 i_error("Children of red node not both black, x=%u", x); 561 i_error("Children of red node not both black, x=%u", x);
583 } 584 }
584 585
585 return 0; 586 return 0;
586 } 587 }
587 588
588 int count_black(MailTree *tree, unsigned int x) 589 int count_black(struct mail_tree *tree, unsigned int x)
589 { 590 {
590 MailTreeNode *node = tree->node_base; 591 struct mail_tree_node *node = tree->node_base;
591 int nleft, nright; 592 int nleft, nright;
592 593
593 if (x == RBNULL) 594 if (x == RBNULL)
594 return 1; 595 return 1;
595 596
608 nleft++; 609 nleft++;
609 610
610 return nleft; 611 return nleft;
611 } 612 }
612 613
613 int count_nodes(MailTree *tree, unsigned int x) 614 int count_nodes(struct mail_tree *tree, unsigned int x)
614 { 615 {
615 MailTreeNode *node = tree->node_base; 616 struct mail_tree_node *node = tree->node_base;
616 int nleft, nright; 617 int nleft, nright;
617 618
618 if (x == RBNULL) 619 if (x == RBNULL)
619 return 0; 620 return 0;
620 621
631 } 632 }
632 633
633 return nleft+nright+1; 634 return nleft+nright+1;
634 } 635 }
635 636
636 void dumptree(MailTree *tree, unsigned int x, int n) 637 void dumptree(struct mail_tree *tree, unsigned int x, int n)
637 { 638 {
638 MailTreeNode *node = tree->node_base; 639 struct mail_tree_node *node = tree->node_base;
639 640
640 if (x != RBNULL) { 641 if (x != RBNULL) {
641 n++; 642 n++;
642 i_error("Tree: %*s %u: left=%u, right=%u, color=%s, " 643 i_error("Tree: %*s %u: left=%u, right=%u, color=%s, "
643 "nodes=%u, key=%u", 644 "nodes=%u, key=%u",
649 dumptree(tree, node[x].right, n); 650 dumptree(tree, node[x].right, n);
650 } 651 }
651 } 652 }
652 653
653 int 654 int
654 rb_check(MailTree *tree) 655 rb_check(struct mail_tree *tree)
655 { 656 {
656 MailTreeNode *node = tree->node_base; 657 struct mail_tree_node *node = tree->node_base;
657 unsigned int root; 658 unsigned int root;
658 659
659 root = tree->header->root; 660 root = tree->header->root;
660 if (root == RBNULL) 661 if (root == RBNULL)
661 return 0; 662 return 0;
683 684
684 return 0; 685 return 0;
685 } 686 }
686 #endif 687 #endif
687 688
688 unsigned int mail_tree_lookup_uid_range(MailTree *tree, unsigned int *seq_r, 689 unsigned int mail_tree_lookup_uid_range(struct mail_tree *tree,
690 unsigned int *seq_r,
689 unsigned int first_uid, 691 unsigned int first_uid,
690 unsigned int last_uid) 692 unsigned int last_uid)
691 { 693 {
692 MailTreeNode *node; 694 struct mail_tree_node *node;
693 unsigned int x, y, seq; 695 unsigned int x, y, seq;
694 696
695 i_assert(first_uid > 0 && last_uid > 0); 697 i_assert(first_uid > 0 && last_uid > 0);
696 i_assert(first_uid <= last_uid); 698 i_assert(first_uid <= last_uid);
697 i_assert(tree->index->lock_type != MAIL_LOCK_UNLOCK); 699 i_assert(tree->index->lock_type != MAIL_LOCK_UNLOCK);
744 } 746 }
745 747
746 return x == RBNULL ? (unsigned int)-1 : node[x].value; 748 return x == RBNULL ? (unsigned int)-1 : node[x].value;
747 } 749 }
748 750
749 unsigned int mail_tree_lookup_sequence(MailTree *tree, unsigned int seq) 751 unsigned int mail_tree_lookup_sequence(struct mail_tree *tree, unsigned int seq)
750 { 752 {
751 MailTreeNode *node; 753 struct mail_tree_node *node;
752 unsigned int x, upleft_nodes, left_nodes; 754 unsigned int x, upleft_nodes, left_nodes;
753 755
754 i_assert(seq != 0); 756 i_assert(seq != 0);
755 i_assert(tree->index->lock_type != MAIL_LOCK_UNLOCK); 757 i_assert(tree->index->lock_type != MAIL_LOCK_UNLOCK);
756 758
780 } 782 }
781 783
782 return (unsigned int)-1; 784 return (unsigned int)-1;
783 } 785 }
784 786
785 int mail_tree_insert(MailTree *tree, unsigned int uid, unsigned int index) 787 int mail_tree_insert(struct mail_tree *tree,
786 { 788 unsigned int uid, unsigned int index)
787 MailTreeNode *node; 789 {
790 struct mail_tree_node *node;
788 unsigned int x, z; 791 unsigned int x, z;
789 792
790 i_assert(uid != 0); 793 i_assert(uid != 0);
791 i_assert(tree->index->lock_type == MAIL_LOCK_EXCLUSIVE); 794 i_assert(tree->index->lock_type == MAIL_LOCK_EXCLUSIVE);
792 795
839 842
840 tree->modified = TRUE; 843 tree->modified = TRUE;
841 return TRUE; 844 return TRUE;
842 } 845 }
843 846
844 int mail_tree_update(MailTree *tree, unsigned int uid, unsigned int index) 847 int mail_tree_update(struct mail_tree *tree,
845 { 848 unsigned int uid, unsigned int index)
846 MailTreeNode *node; 849 {
850 struct mail_tree_node *node;
847 unsigned int x; 851 unsigned int x;
848 852
849 i_assert(uid != 0); 853 i_assert(uid != 0);
850 i_assert(tree->index->lock_type == MAIL_LOCK_EXCLUSIVE); 854 i_assert(tree->index->lock_type == MAIL_LOCK_EXCLUSIVE);
851 855
873 _mail_tree_set_corrupted(tree, "Tried to update nonexisting UID %u", 877 _mail_tree_set_corrupted(tree, "Tried to update nonexisting UID %u",
874 uid); 878 uid);
875 return FALSE; 879 return FALSE;
876 } 880 }
877 881
878 void mail_tree_delete(MailTree *tree, unsigned int uid) 882 void mail_tree_delete(struct mail_tree *tree, unsigned int uid)
879 { 883 {
880 MailTreeNode *node; 884 struct mail_tree_node *node;
881 unsigned int x; 885 unsigned int x;
882 886
883 i_assert(uid != 0); 887 i_assert(uid != 0);
884 i_assert(tree->index->lock_type == MAIL_LOCK_EXCLUSIVE); 888 i_assert(tree->index->lock_type == MAIL_LOCK_EXCLUSIVE);
885 889