1 /* This file implements an efficient interval data-structure. 2 3 Copyright (C) 2017-2023 Free Software Foundation, Inc. 4 5 This file is part of GNU Emacs. 6 7 GNU Emacs is free software: you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation, either version 3 of the License, or (at 10 your option) any later version. 11 12 GNU Emacs is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ 19 20 #ifndef ITREE_H 21 #define ITREE_H 22 #include <config.h> 23 #include <stddef.h> 24 #include <inttypes.h> 25 26 #include "lisp.h" 27 28 /* The tree and node structs are mainly here, so they can be 29 allocated. 30 31 NOTE: The only time where it is safe to modify node.begin and 32 node.end directly, is while the node is not part of any tree. 33 34 NOTE: It is safe to read node.begin and node.end directly, if the 35 node came from an iterator, because it validates the nodes it 36 returns as a side-effect. See ITREE_FOREACH. 37 */ 38 39 struct itree_node 40 { 41 /* The normal parent, left and right links found in binary trees. 42 See also `red`, below, which completes the Red-Black tree 43 representation. */ 44 struct itree_node *parent; 45 struct itree_node *left; 46 struct itree_node *right; 47 48 /* The following five fields comprise the interval abstraction. 49 50 BEGIN, END are buffer positions describing the range. When a 51 node is in a tree these fields are read only, written only by 52 itree functions. 53 54 The LIMIT, OFFSET and OTICK fields should be considered internal 55 to itree.c and used only by itree functions. 56 57 LIMIT is a buffer position, the maximum of END of this node and 58 its children. See itree.c for its use. 59 60 OFFSET is in buffer position units, and will be non-zero only 61 when the node is dirty. 62 63 OTICK determines whether BEGIN, END, LIMIT and OFFSET are 64 considered dirty. A node is clean when its OTICK is equal to the 65 OTICK of its tree (see struct itree_tree). Otherwise, it is 66 dirty. 67 68 In a clean node, BEGIN, END and LIMIT are correct buffer 69 positions, and OFFSET is zero. The parent of a clean node is 70 also clean, recursively. 71 72 In a dirty node, the node's OTICK won't equal its tree's OTICK, 73 and its OFFSET may be non-zero. At all times the descendents of 74 a dirty node are also dirty. BEGIN, END and LIMIT require 75 adjustment before use as buffer positions. 76 77 NOTE: BEGIN and END must not be modified while the node is part 78 of a tree. Use itree_insert_gap and itree_delete_gap instead. 79 80 NOTE: The interval iterators ensure nodes are clean before 81 yielding them, so BEGIN and END may be safely used as buffer 82 positions then. */ 83 84 ptrdiff_t begin; /* The beginning of this interval. */ 85 ptrdiff_t end; /* The end of the interval. */ 86 ptrdiff_t limit; /* The maximum end in this subtree. */ 87 ptrdiff_t offset; /* The amount of shift to apply to this subtree. */ 88 uintmax_t otick; /* offset modified tick */ 89 Lisp_Object data; /* Exclusively used by the client. */ 90 bool_bf red : 1; 91 bool_bf rear_advance : 1; /* Same as for marker and overlays. */ 92 bool_bf front_advance : 1; /* Same as for marker and overlays. */ 93 }; 94 95 struct itree_tree 96 { 97 struct itree_node *root; 98 uintmax_t otick; /* offset tick, compared with node's otick. */ 99 intmax_t size; /* Number of nodes in the tree. */ 100 }; 101 102 enum itree_order 103 { 104 ITREE_ASCENDING, 105 ITREE_DESCENDING, 106 ITREE_PRE_ORDER, 107 ITREE_POST_ORDER, 108 }; 109 110 extern void itree_node_init (struct itree_node *, bool, bool, Lisp_Object); 111 extern ptrdiff_t itree_node_begin (struct itree_tree *, struct itree_node *); 112 extern ptrdiff_t itree_node_end (struct itree_tree *, struct itree_node *); 113 extern void itree_node_set_region (struct itree_tree *, struct itree_node *, 114 ptrdiff_t, ptrdiff_t); 115 extern struct itree_tree *itree_create (void); 116 extern void itree_destroy (struct itree_tree *); 117 extern intmax_t itree_size (struct itree_tree *); 118 extern void itree_clear (struct itree_tree *); 119 extern void itree_insert (struct itree_tree *, struct itree_node *, 120 ptrdiff_t, ptrdiff_t); 121 extern struct itree_node *itree_remove (struct itree_tree *, 122 struct itree_node *); 123 extern void itree_insert_gap (struct itree_tree *, ptrdiff_t, ptrdiff_t, bool); 124 extern void itree_delete_gap (struct itree_tree *, ptrdiff_t, ptrdiff_t); 125 126 /* Iteration functions. Almost all code should use ITREE_FOREACH 127 instead. */ 128 extern struct itree_iterator *itree_iterator_start (struct itree_iterator *, 129 struct itree_tree *, 130 ptrdiff_t, 131 ptrdiff_t, 132 enum itree_order); 133 extern void itree_iterator_narrow (struct itree_iterator *, ptrdiff_t, 134 ptrdiff_t); 135 extern struct itree_node *itree_iterator_next (struct itree_iterator *); 136 137 /* State used when iterating interval. */ 138 struct itree_iterator 139 { 140 struct itree_node *node; 141 ptrdiff_t begin; 142 ptrdiff_t end; 143 uintmax_t otick; /* A copy of the tree's `otick`. */ 144 enum itree_order order; 145 }; 146 147 /* Iterate over the intervals between BEG and END in the tree T. 148 N will hold successive nodes. ORDER can be one of : `ASCENDING`, 149 `DESCENDING`, `POST_ORDER`, or `PRE_ORDER`. 150 It should be used as: 151 152 ITREE_FOREACH (n, t, beg, end, order) 153 { 154 .. do the thing with n .. 155 } 156 157 BEWARE: 158 - The expression T may be evaluated more than once, so make sure 159 it is cheap and pure. 160 - Don't modify the tree during the iteration. 161 */ 162 #define ITREE_FOREACH(n, t, beg, end, order) \ 163 /* FIXME: We'd want to declare `n` right here, but I can't figure out 164 how to make that work here: the `for` syntax only allows a single 165 clause for the var declarations where we need 2 different types. 166 We could use the `struct {foo x; bar y; } p;` trick to declare two 167 vars `p.x` and `p.y` of unrelated types, but then none of the names 168 of the vars matches the `n` we receive :-(. */ \ 169 if (!t) \ 170 { } \ 171 else \ 172 for (struct itree_iterator itree_local_iter_, \ 173 *itree_iter_ \ 174 = itree_iterator_start (&itree_local_iter_, \ 175 t, beg, end, ITREE_##order); \ 176 ((n = itree_iterator_next (itree_iter_)));) 177 178 #define ITREE_FOREACH_NARROW(beg, end) \ 179 itree_iterator_narrow (itree_iter_, beg, end) 180 181 #endif