diff options
| author | Stefan Monnier | 2022-09-28 19:05:16 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2022-09-28 19:05:16 -0400 |
| commit | ea8daec9bb8ebf3cbca35edec4e4ef7b6edac3de (patch) | |
| tree | 1a34f44adca5fbf08033829dab643db6340bf296 /src | |
| parent | 800ecd4767df48beeefabccdacd089b8c4286529 (diff) | |
| download | emacs-ea8daec9bb8ebf3cbca35edec4e4ef7b6edac3de.tar.gz emacs-ea8daec9bb8ebf3cbca35edec4e4ef7b6edac3de.zip | |
itree.[ch]: Add sanity checks, comments, and minor tweaks
* src/alloc.c (mark_overlay): Add sanity check.
* src/buffer.c (next_overlay_change, previous_overlay_change):
Tweak code to keep the same vars for the bounds.
* src/itree.c (interval_tree_clear, interval_tree_insert)
(interval_tree_remove, interval_tree_insert_fix, interval_tree_remove_fix):
Adjust to the `color` -> `red` change.
(interval_tree_clear): Prefer `true/false` for booleans.
(interval_generator_create): Use an actual `interval_tree_order` value
rather than 0.
(interval_generator_next): Simplify a tiny bit. Add comment.
(interval_generator_narrow): Add sanity check.
* src/itree.h (struct interval_node): Replace `color` field with
boolean `red` field.
(enum interval_tree_order): Remove unused `ITREE_DEFLT_ORDER` value.
* src/pdumper.c (dump_interval_node): Adjust to the
`color` -> `red` change.
Diffstat (limited to 'src')
| -rw-r--r-- | src/alloc.c | 3 | ||||
| -rw-r--r-- | src/buffer.c | 4 | ||||
| -rw-r--r-- | src/itree.c | 134 | ||||
| -rw-r--r-- | src/itree.h | 7 | ||||
| -rw-r--r-- | src/pdumper.c | 2 |
5 files changed, 89 insertions, 61 deletions
diff --git a/src/alloc.c b/src/alloc.c index 20b8981bd66..be55dcf8dfd 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -6505,6 +6505,9 @@ mark_char_table (struct Lisp_Vector *ptr, enum pvec_type pvectype) | |||
| 6505 | static void | 6505 | static void |
| 6506 | mark_overlay (struct Lisp_Overlay *ov) | 6506 | mark_overlay (struct Lisp_Overlay *ov) |
| 6507 | { | 6507 | { |
| 6508 | /* We don't mark the `interval_node` object, because it is managed manually | ||
| 6509 | rather than by the GC. */ | ||
| 6510 | eassert (BASE_EQ (ov->interval->data, make_lisp_ptr (ov, Lisp_Vectorlike))); | ||
| 6508 | set_vectorlike_marked (&ov->header); | 6511 | set_vectorlike_marked (&ov->header); |
| 6509 | mark_object (ov->plist); | 6512 | mark_object (ov->plist); |
| 6510 | } | 6513 | } |
diff --git a/src/buffer.c b/src/buffer.c index 2b1997fc8be..879e14be960 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
| @@ -2992,7 +2992,7 @@ next_overlay_change (ptrdiff_t pos) | |||
| 2992 | ptrdiff_t next = ZV; | 2992 | ptrdiff_t next = ZV; |
| 2993 | struct interval_node *node; | 2993 | struct interval_node *node; |
| 2994 | 2994 | ||
| 2995 | buffer_overlay_iter_start (current_buffer, pos, ZV, ITREE_ASCENDING); | 2995 | buffer_overlay_iter_start (current_buffer, pos, next, ITREE_ASCENDING); |
| 2996 | while ((node = buffer_overlay_iter_next (current_buffer))) | 2996 | while ((node = buffer_overlay_iter_next (current_buffer))) |
| 2997 | { | 2997 | { |
| 2998 | if (node->begin > pos) | 2998 | if (node->begin > pos) |
| @@ -3020,7 +3020,7 @@ previous_overlay_change (ptrdiff_t pos) | |||
| 3020 | struct interval_node *node; | 3020 | struct interval_node *node; |
| 3021 | ptrdiff_t prev = BEGV; | 3021 | ptrdiff_t prev = BEGV; |
| 3022 | 3022 | ||
| 3023 | buffer_overlay_iter_start (current_buffer, BEGV, pos, ITREE_DESCENDING); | 3023 | buffer_overlay_iter_start (current_buffer, prev, pos, ITREE_DESCENDING); |
| 3024 | while ((node = buffer_overlay_iter_next (current_buffer))) | 3024 | while ((node = buffer_overlay_iter_next (current_buffer))) |
| 3025 | { | 3025 | { |
| 3026 | if (node->end < pos) | 3026 | if (node->end < pos) |
diff --git a/src/itree.c b/src/itree.c index e31ce39ba11..aa6fcc1bea0 100644 --- a/src/itree.c +++ b/src/itree.c | |||
| @@ -233,11 +233,11 @@ interval_tree_clear (struct interval_tree *tree) | |||
| 233 | null->begin = PTRDIFF_MIN; | 233 | null->begin = PTRDIFF_MIN; |
| 234 | null->end = PTRDIFF_MIN; | 234 | null->end = PTRDIFF_MIN; |
| 235 | null->limit = PTRDIFF_MIN; /* => max(x, null.limit) = x */ | 235 | null->limit = PTRDIFF_MIN; /* => max(x, null.limit) = x */ |
| 236 | null->color = ITREE_BLACK; | 236 | null->red = false; |
| 237 | tree->root = null; | 237 | tree->root = null; |
| 238 | tree->otick = 1; | 238 | tree->otick = 1; |
| 239 | tree->size = 0; | 239 | tree->size = 0; |
| 240 | tree->iter_running = 0; | 240 | tree->iter_running = false; |
| 241 | } | 241 | } |
| 242 | 242 | ||
| 243 | #ifdef ITREE_TESTING | 243 | #ifdef ITREE_TESTING |
| @@ -308,7 +308,7 @@ interval_tree_insert (struct interval_tree *tree, struct interval_node *node) | |||
| 308 | node->parent = parent; | 308 | node->parent = parent; |
| 309 | node->left = &tree->null; | 309 | node->left = &tree->null; |
| 310 | node->right = &tree->null; | 310 | node->right = &tree->null; |
| 311 | node->color = ITREE_RED; | 311 | node->red = true; |
| 312 | node->offset = 0; | 312 | node->offset = 0; |
| 313 | node->begin -= offset; | 313 | node->begin -= offset; |
| 314 | node->end -= offset; | 314 | node->end -= offset; |
| @@ -351,7 +351,7 @@ interval_tree_remove (struct interval_tree *tree, struct interval_node *node) | |||
| 351 | { | 351 | { |
| 352 | struct interval_node *subst = | 352 | struct interval_node *subst = |
| 353 | (node->right == &tree->null) ? node->left : node->right; | 353 | (node->right == &tree->null) ? node->left : node->right; |
| 354 | if (node->color == ITREE_BLACK) | 354 | if (!node->red) |
| 355 | broken = subst; | 355 | broken = subst; |
| 356 | interval_tree_transplant (tree, subst, node); | 356 | interval_tree_transplant (tree, subst, node); |
| 357 | interval_tree_propagate_limit (tree, subst); | 357 | interval_tree_propagate_limit (tree, subst); |
| @@ -361,7 +361,7 @@ interval_tree_remove (struct interval_tree *tree, struct interval_node *node) | |||
| 361 | struct interval_node *min = interval_tree_subtree_min (tree, node->right); | 361 | struct interval_node *min = interval_tree_subtree_min (tree, node->right); |
| 362 | struct interval_node *min_right = min->right; | 362 | struct interval_node *min_right = min->right; |
| 363 | 363 | ||
| 364 | if (min->color == ITREE_BLACK) | 364 | if (!min->red) |
| 365 | broken = min->right; | 365 | broken = min->right; |
| 366 | if (min->parent == node) | 366 | if (min->parent == node) |
| 367 | min_right->parent = min; /* set parent, if min_right = null */ | 367 | min_right->parent = min; /* set parent, if min_right = null */ |
| @@ -375,7 +375,7 @@ interval_tree_remove (struct interval_tree *tree, struct interval_node *node) | |||
| 375 | interval_tree_transplant (tree, min, node); | 375 | interval_tree_transplant (tree, min, node); |
| 376 | min->left = node->left; | 376 | min->left = node->left; |
| 377 | min->left->parent = min; | 377 | min->left->parent = min; |
| 378 | min->color = node->color; | 378 | min->red = node->red; |
| 379 | interval_tree_propagate_limit (tree, min_right); | 379 | interval_tree_propagate_limit (tree, min_right); |
| 380 | interval_tree_propagate_limit (tree, min); | 380 | interval_tree_propagate_limit (tree, min); |
| 381 | } | 381 | } |
| @@ -440,7 +440,7 @@ interval_tree_iter_start (struct interval_tree *tree, | |||
| 440 | if (tree->iter_running) | 440 | if (tree->iter_running) |
| 441 | emacs_abort (); | 441 | emacs_abort (); |
| 442 | interval_generator_reset (tree->iter, begin, end, order); | 442 | interval_generator_reset (tree->iter, begin, end, order); |
| 443 | tree->iter_running = 1; | 443 | tree->iter_running = true; |
| 444 | tree->file = file; | 444 | tree->file = file; |
| 445 | tree->line = line; | 445 | tree->line = line; |
| 446 | } | 446 | } |
| @@ -464,7 +464,7 @@ interval_tree_iter_finish (struct interval_tree *tree) | |||
| 464 | { | 464 | { |
| 465 | if (! tree->iter_running) | 465 | if (! tree->iter_running) |
| 466 | emacs_abort (); | 466 | emacs_abort (); |
| 467 | tree->iter_running = 0; | 467 | tree->iter_running = false; |
| 468 | } | 468 | } |
| 469 | 469 | ||
| 470 | /* Return the next node of the iterator in the order given when it was | 470 | /* Return the next node of the iterator in the order given when it was |
| @@ -637,7 +637,7 @@ interval_generator_create (struct interval_tree *tree) | |||
| 637 | 637 | ||
| 638 | g->stack = interval_stack_create (size); | 638 | g->stack = interval_stack_create (size); |
| 639 | g->tree = tree; | 639 | g->tree = tree; |
| 640 | interval_generator_reset (g, 1, 0, 0); | 640 | interval_generator_reset (g, 1, 0, ITREE_ASCENDING); |
| 641 | return g; | 641 | return g; |
| 642 | } | 642 | } |
| 643 | 643 | ||
| @@ -667,7 +667,13 @@ interval_generator_ensure_space (struct interval_generator *g) | |||
| 667 | interval_stack_ensure_space (g->stack, interval_tree_max_height (g->tree) + 1); | 667 | interval_stack_ensure_space (g->stack, interval_tree_max_height (g->tree) + 1); |
| 668 | } | 668 | } |
| 669 | 669 | ||
| 670 | /* Return true, if NODE's interval intersects with [BEGIN, END). */ | 670 | /* Return true, if NODE's interval intersects with [BEGIN, END). |
| 671 | Note: We always include empty nodes at BEGIN (and not at END), | ||
| 672 | but if BEGIN==END, then we don't include non-empty nodes starting | ||
| 673 | at BEGIN or ending at END. This seems to match the behavior of the | ||
| 674 | old overlays code but it's not clear if it's The Right Thing | ||
| 675 | (e.g. it breaks the expectation that if NODE1 is included, then | ||
| 676 | a NODE2 strictly bigger than NODE1 should also be included). */ | ||
| 671 | 677 | ||
| 672 | static inline bool | 678 | static inline bool |
| 673 | interval_node_intersects (const struct interval_node *node, | 679 | interval_node_intersects (const struct interval_node *node, |
| @@ -687,10 +693,29 @@ interval_generator_next (struct interval_generator *g) | |||
| 687 | struct interval_node * const null = &g->tree->null; | 693 | struct interval_node * const null = &g->tree->null; |
| 688 | struct interval_node *node; | 694 | struct interval_node *node; |
| 689 | 695 | ||
| 690 | do { | 696 | /* The `visited` flag stored in each node is used here (and only here): |
| 691 | node = interval_stack_pop (g->stack); | 697 | We keep a "workstack" of nodes we need to consider. This stack |
| 698 | consist of nodes of two types: nodes that we have decided | ||
| 699 | should be returned by the generator, and nodes which we may | ||
| 700 | need to consider (including checking their children). | ||
| 701 | We start an iteration with a stack containing just the root | ||
| 702 | node marked as "not visited" which means that it (and its children) | ||
| 703 | needs to be considered but we haven't yet decided whether it's included | ||
| 704 | in the generator's output. */ | ||
| 705 | |||
| 706 | /* FIXME: We should move the `visited` flag to the stack: each entry | ||
| 707 | there should simply consist of a node and a bool (the `visited` status) | ||
| 708 | so this internal implementation detail doesn't leak into the | ||
| 709 | `interval_node` structure. | ||
| 710 | [ In theory it would also allow multiple iterations to be active | ||
| 711 | at the same time, tho that does not seem particularly useful at | ||
| 712 | this time and would require further changes anyway. ] | ||
| 713 | To save space on the stack, we could hijack the LSB bit of the `node*` | ||
| 714 | word to hold the `visited` bit. */ | ||
| 692 | 715 | ||
| 693 | while (node && ! node->visited) | 716 | do { |
| 717 | while ((node = interval_stack_pop (g->stack)) | ||
| 718 | && ! node->visited) | ||
| 694 | { | 719 | { |
| 695 | struct interval_node * const left = node->left; | 720 | struct interval_node * const left = node->left; |
| 696 | struct interval_node * const right = node->right; | 721 | struct interval_node * const right = node->right; |
| @@ -724,7 +749,6 @@ interval_generator_next (struct interval_generator *g) | |||
| 724 | interval_stack_push_flagged (g->stack, node, true); | 749 | interval_stack_push_flagged (g->stack, node, true); |
| 725 | break; | 750 | break; |
| 726 | } | 751 | } |
| 727 | node = interval_stack_pop (g->stack); | ||
| 728 | } | 752 | } |
| 729 | /* Node may have been invalidated by interval_generator_narrow | 753 | /* Node may have been invalidated by interval_generator_narrow |
| 730 | after it was pushed: Check if it still intersects. */ | 754 | after it was pushed: Check if it still intersects. */ |
| @@ -740,6 +764,8 @@ static inline void | |||
| 740 | interval_generator_narrow (struct interval_generator *g, | 764 | interval_generator_narrow (struct interval_generator *g, |
| 741 | ptrdiff_t begin, ptrdiff_t end) | 765 | ptrdiff_t begin, ptrdiff_t end) |
| 742 | { | 766 | { |
| 767 | eassert (begin >= g->begin); | ||
| 768 | eassert (end <= g->end); | ||
| 743 | g->begin = max (begin, g->begin); | 769 | g->begin = max (begin, g->begin); |
| 744 | g->end = min (end, g->end); | 770 | g->end = min (end, g->end); |
| 745 | } | 771 | } |
| @@ -980,7 +1006,7 @@ interval_tree_rotate_right (struct interval_tree *tree, struct interval_node *no | |||
| 980 | static void | 1006 | static void |
| 981 | interval_tree_insert_fix (struct interval_tree *tree, struct interval_node *node) | 1007 | interval_tree_insert_fix (struct interval_tree *tree, struct interval_node *node) |
| 982 | { | 1008 | { |
| 983 | while (node->parent->color == ITREE_RED) | 1009 | while (node->parent->red) |
| 984 | { | 1010 | { |
| 985 | /* NODE is red and its parent is red. This is a violation of | 1011 | /* NODE is red and its parent is red. This is a violation of |
| 986 | red-black tree property #3. */ | 1012 | red-black tree property #3. */ |
| @@ -991,14 +1017,14 @@ interval_tree_insert_fix (struct interval_tree *tree, struct interval_node *node | |||
| 991 | our "uncle". */ | 1017 | our "uncle". */ |
| 992 | struct interval_node *uncle = node->parent->parent->right; | 1018 | struct interval_node *uncle = node->parent->parent->right; |
| 993 | 1019 | ||
| 994 | if (uncle->color == ITREE_RED) /* case 1.a */ | 1020 | if (uncle->red) /* case 1.a */ |
| 995 | { | 1021 | { |
| 996 | /* Uncle and parent are red but should be black because | 1022 | /* Uncle and parent are red but should be black because |
| 997 | NODE is red. Change the colors accordingly and | 1023 | NODE is red. Change the colors accordingly and |
| 998 | proceed with the grandparent. */ | 1024 | proceed with the grandparent. */ |
| 999 | node->parent->color = ITREE_BLACK; | 1025 | node->parent->red = false; |
| 1000 | uncle->color = ITREE_BLACK; | 1026 | uncle->red = false; |
| 1001 | node->parent->parent->color = ITREE_RED; | 1027 | node->parent->parent->red = true; |
| 1002 | node = node->parent->parent; | 1028 | node = node->parent->parent; |
| 1003 | } | 1029 | } |
| 1004 | else | 1030 | else |
| @@ -1011,8 +1037,8 @@ interval_tree_insert_fix (struct interval_tree *tree, struct interval_node *node | |||
| 1011 | interval_tree_rotate_left (tree, node); | 1037 | interval_tree_rotate_left (tree, node); |
| 1012 | } | 1038 | } |
| 1013 | /* case 3.a */ | 1039 | /* case 3.a */ |
| 1014 | node->parent->color = ITREE_BLACK; | 1040 | node->parent->red = false; |
| 1015 | node->parent->parent->color = ITREE_RED; | 1041 | node->parent->parent->red = true; |
| 1016 | interval_tree_rotate_right (tree, node->parent->parent); | 1042 | interval_tree_rotate_right (tree, node->parent->parent); |
| 1017 | } | 1043 | } |
| 1018 | } | 1044 | } |
| @@ -1021,11 +1047,11 @@ interval_tree_insert_fix (struct interval_tree *tree, struct interval_node *node | |||
| 1021 | /* This is the symmetrical case of above. */ | 1047 | /* This is the symmetrical case of above. */ |
| 1022 | struct interval_node *uncle = node->parent->parent->left; | 1048 | struct interval_node *uncle = node->parent->parent->left; |
| 1023 | 1049 | ||
| 1024 | if (uncle->color == ITREE_RED) /* case 1.b */ | 1050 | if (uncle->red) /* case 1.b */ |
| 1025 | { | 1051 | { |
| 1026 | node->parent->color = ITREE_BLACK; | 1052 | node->parent->red = false; |
| 1027 | uncle->color = ITREE_BLACK; | 1053 | uncle->red = false; |
| 1028 | node->parent->parent->color = ITREE_RED; | 1054 | node->parent->parent->red = true; |
| 1029 | node = node->parent->parent; | 1055 | node = node->parent->parent; |
| 1030 | } | 1056 | } |
| 1031 | else | 1057 | else |
| @@ -1036,8 +1062,8 @@ interval_tree_insert_fix (struct interval_tree *tree, struct interval_node *node | |||
| 1036 | interval_tree_rotate_right (tree, node); | 1062 | interval_tree_rotate_right (tree, node); |
| 1037 | } | 1063 | } |
| 1038 | /* case 3.b */ | 1064 | /* case 3.b */ |
| 1039 | node->parent->color = ITREE_BLACK; | 1065 | node->parent->red = false; |
| 1040 | node->parent->parent->color = ITREE_RED; | 1066 | node->parent->parent->red = true; |
| 1041 | interval_tree_rotate_left (tree, node->parent->parent); | 1067 | interval_tree_rotate_left (tree, node->parent->parent); |
| 1042 | } | 1068 | } |
| 1043 | } | 1069 | } |
| @@ -1045,7 +1071,7 @@ interval_tree_insert_fix (struct interval_tree *tree, struct interval_node *node | |||
| 1045 | 1071 | ||
| 1046 | /* The root may have been changed to red due to the algorithm. Set | 1072 | /* The root may have been changed to red due to the algorithm. Set |
| 1047 | it to black so that property #5 is satisfied. */ | 1073 | it to black so that property #5 is satisfied. */ |
| 1048 | tree->root->color = ITREE_BLACK; | 1074 | tree->root->red = false; |
| 1049 | } | 1075 | } |
| 1050 | 1076 | ||
| 1051 | /* Repair the tree after a deletion. Part of the RB-Tree | 1077 | /* Repair the tree after a deletion. Part of the RB-Tree |
| @@ -1054,38 +1080,38 @@ interval_tree_insert_fix (struct interval_tree *tree, struct interval_node *node | |||
| 1054 | static void | 1080 | static void |
| 1055 | interval_tree_remove_fix (struct interval_tree *tree, struct interval_node *node) | 1081 | interval_tree_remove_fix (struct interval_tree *tree, struct interval_node *node) |
| 1056 | { | 1082 | { |
| 1057 | while (node != tree->root && node->color == ITREE_BLACK) | 1083 | while (node != tree->root && !node->red) |
| 1058 | { | 1084 | { |
| 1059 | if (node == node->parent->left) | 1085 | if (node == node->parent->left) |
| 1060 | { | 1086 | { |
| 1061 | struct interval_node *other = node->parent->right; | 1087 | struct interval_node *other = node->parent->right; |
| 1062 | 1088 | ||
| 1063 | if (other->color == ITREE_RED) /* case 1.a */ | 1089 | if (other->red) /* case 1.a */ |
| 1064 | { | 1090 | { |
| 1065 | other->color = ITREE_BLACK; | 1091 | other->red = false; |
| 1066 | node->parent->color = ITREE_RED; | 1092 | node->parent->red = true; |
| 1067 | interval_tree_rotate_left (tree, node->parent); | 1093 | interval_tree_rotate_left (tree, node->parent); |
| 1068 | other = node->parent->right; | 1094 | other = node->parent->right; |
| 1069 | } | 1095 | } |
| 1070 | 1096 | ||
| 1071 | if (other->left->color == ITREE_BLACK /* 2.a */ | 1097 | if (!other->left->red /* 2.a */ |
| 1072 | && other->right->color == ITREE_BLACK) | 1098 | && !other->right->red) |
| 1073 | { | 1099 | { |
| 1074 | other->color = ITREE_RED; | 1100 | other->red = true; |
| 1075 | node = node->parent; | 1101 | node = node->parent; |
| 1076 | } | 1102 | } |
| 1077 | else | 1103 | else |
| 1078 | { | 1104 | { |
| 1079 | if (other->right->color == ITREE_BLACK) /* 3.a */ | 1105 | if (!other->right->red) /* 3.a */ |
| 1080 | { | 1106 | { |
| 1081 | other->left->color = ITREE_BLACK; | 1107 | other->left->red = false; |
| 1082 | other->color = ITREE_RED; | 1108 | other->red = true; |
| 1083 | interval_tree_rotate_right (tree, other); | 1109 | interval_tree_rotate_right (tree, other); |
| 1084 | other = node->parent->right; | 1110 | other = node->parent->right; |
| 1085 | } | 1111 | } |
| 1086 | other->color = node->parent->color; /* 4.a */ | 1112 | other->red = node->parent->red; /* 4.a */ |
| 1087 | node->parent->color = ITREE_BLACK; | 1113 | node->parent->red = false; |
| 1088 | other->right->color = ITREE_BLACK; | 1114 | other->right->red = false; |
| 1089 | interval_tree_rotate_left (tree, node->parent); | 1115 | interval_tree_rotate_left (tree, node->parent); |
| 1090 | node = tree->root; | 1116 | node = tree->root; |
| 1091 | } | 1117 | } |
| @@ -1094,40 +1120,40 @@ interval_tree_remove_fix (struct interval_tree *tree, struct interval_node *node | |||
| 1094 | { | 1120 | { |
| 1095 | struct interval_node *other = node->parent->left; | 1121 | struct interval_node *other = node->parent->left; |
| 1096 | 1122 | ||
| 1097 | if (other->color == ITREE_RED) /* 1.b */ | 1123 | if (other->red) /* 1.b */ |
| 1098 | { | 1124 | { |
| 1099 | other->color = ITREE_BLACK; | 1125 | other->red = false; |
| 1100 | node->parent->color = ITREE_RED; | 1126 | node->parent->red = true; |
| 1101 | interval_tree_rotate_right (tree, node->parent); | 1127 | interval_tree_rotate_right (tree, node->parent); |
| 1102 | other = node->parent->left; | 1128 | other = node->parent->left; |
| 1103 | } | 1129 | } |
| 1104 | 1130 | ||
| 1105 | if (other->right->color == ITREE_BLACK /* 2.b */ | 1131 | if (!other->right->red /* 2.b */ |
| 1106 | && other->left->color == ITREE_BLACK) | 1132 | && !other->left->red) |
| 1107 | { | 1133 | { |
| 1108 | other->color = ITREE_RED; | 1134 | other->red = true; |
| 1109 | node = node->parent; | 1135 | node = node->parent; |
| 1110 | } | 1136 | } |
| 1111 | else | 1137 | else |
| 1112 | { | 1138 | { |
| 1113 | if (other->left->color == ITREE_BLACK) /* 3.b */ | 1139 | if (!other->left->red) /* 3.b */ |
| 1114 | { | 1140 | { |
| 1115 | other->right->color = ITREE_BLACK; | 1141 | other->right->red = false; |
| 1116 | other->color = ITREE_RED; | 1142 | other->red = true; |
| 1117 | interval_tree_rotate_left (tree, other); | 1143 | interval_tree_rotate_left (tree, other); |
| 1118 | other = node->parent->left; | 1144 | other = node->parent->left; |
| 1119 | } | 1145 | } |
| 1120 | 1146 | ||
| 1121 | other->color = node->parent->color; /* 4.b */ | 1147 | other->red = node->parent->red; /* 4.b */ |
| 1122 | node->parent->color = ITREE_BLACK; | 1148 | node->parent->red = false; |
| 1123 | other->left->color = ITREE_BLACK; | 1149 | other->left->red = false; |
| 1124 | interval_tree_rotate_right (tree, node->parent); | 1150 | interval_tree_rotate_right (tree, node->parent); |
| 1125 | node = tree->root; | 1151 | node = tree->root; |
| 1126 | } | 1152 | } |
| 1127 | } | 1153 | } |
| 1128 | } | 1154 | } |
| 1129 | 1155 | ||
| 1130 | node->color = ITREE_BLACK; | 1156 | node->red = false; |
| 1131 | } | 1157 | } |
| 1132 | 1158 | ||
| 1133 | /* Link node SOURCE in DEST's place. */ | 1159 | /* Link node SOURCE in DEST's place. */ |
diff --git a/src/itree.h b/src/itree.h index e5d68fbfabb..8f0454dc7a4 100644 --- a/src/itree.h +++ b/src/itree.h | |||
| @@ -45,8 +45,8 @@ struct interval_node | |||
| 45 | ptrdiff_t offset; /* The amount of shift to apply to this subtree. */ | 45 | ptrdiff_t offset; /* The amount of shift to apply to this subtree. */ |
| 46 | uintmax_t otick; /* offset modified tick */ | 46 | uintmax_t otick; /* offset modified tick */ |
| 47 | Lisp_Object data; /* Exclusively used by the client. */ | 47 | Lisp_Object data; /* Exclusively used by the client. */ |
| 48 | enum { ITREE_RED, ITREE_BLACK } color; | 48 | bool_bf red : 1; |
| 49 | bool_bf visited : 1; /* For traversal via generator. */ | 49 | bool_bf visited : 1; /* Internal to `interval_generator_next`. */ |
| 50 | bool_bf rear_advance : 1; /* Same as for marker and overlays. */ | 50 | bool_bf rear_advance : 1; /* Same as for marker and overlays. */ |
| 51 | bool_bf front_advance : 1; /* Same as for marker and overlays. */ | 51 | bool_bf front_advance : 1; /* Same as for marker and overlays. */ |
| 52 | }; | 52 | }; |
| @@ -64,8 +64,7 @@ struct interval_tree | |||
| 64 | }; | 64 | }; |
| 65 | 65 | ||
| 66 | enum interval_tree_order { | 66 | enum interval_tree_order { |
| 67 | ITREE_ASCENDING = 0, | 67 | ITREE_ASCENDING, |
| 68 | ITREE_DEFLT_ORDER = 0, | ||
| 69 | ITREE_DESCENDING, | 68 | ITREE_DESCENDING, |
| 70 | ITREE_PRE_ORDER, | 69 | ITREE_PRE_ORDER, |
| 71 | }; | 70 | }; |
diff --git a/src/pdumper.c b/src/pdumper.c index 79644c01517..44486015f05 100644 --- a/src/pdumper.c +++ b/src/pdumper.c | |||
| @@ -2154,7 +2154,7 @@ dump_interval_node (struct dump_context *ctx, struct interval_node *node, | |||
| 2154 | DUMP_FIELD_COPY (&out, node, offset); | 2154 | DUMP_FIELD_COPY (&out, node, offset); |
| 2155 | DUMP_FIELD_COPY (&out, node, otick); | 2155 | DUMP_FIELD_COPY (&out, node, otick); |
| 2156 | dump_field_lv (ctx, &out, node, &node->data, WEIGHT_STRONG); | 2156 | dump_field_lv (ctx, &out, node, &node->data, WEIGHT_STRONG); |
| 2157 | DUMP_FIELD_COPY (&out, node, color); | 2157 | DUMP_FIELD_COPY (&out, node, red); |
| 2158 | DUMP_FIELD_COPY (&out, node, visited); | 2158 | DUMP_FIELD_COPY (&out, node, visited); |
| 2159 | DUMP_FIELD_COPY (&out, node, rear_advance); | 2159 | DUMP_FIELD_COPY (&out, node, rear_advance); |
| 2160 | DUMP_FIELD_COPY (&out, node, front_advance); | 2160 | DUMP_FIELD_COPY (&out, node, front_advance); |