Branch data Line data Source code
1 : : // Splay tree utilities -*- C++ -*-
2 : : // Copyright (C) 2020-2025 Free Software Foundation, Inc.
3 : : //
4 : : // This file is part of GCC.
5 : : //
6 : : // GCC is free software; you can redistribute it and/or modify it under
7 : : // the terms of the GNU General Public License as published by the Free
8 : : // Software Foundation; either version 3, or (at your option) any later
9 : : // version.
10 : : //
11 : : // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 : : // WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 : : // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 : : // for more details.
15 : : //
16 : : // You should have received a copy of the GNU General Public License
17 : : // along with GCC; see the file COPYING3. If not see
18 : : // <http://www.gnu.org/licenses/>.
19 : :
20 : : // INDEX is either 0 or 1. If it is 0, return NODE's left child,
21 : : // otherwise return NODE's right child.
22 : : template<typename Accessors>
23 : : inline typename base_splay_tree<Accessors>::node_type
24 : 166126517 : base_splay_tree<Accessors>::get_child (node_type node, unsigned int index)
25 : : {
26 : 174337429 : return Accessors::child (node, index);
27 : : }
28 : :
29 : : // INDEX is either 0 or 1. If it is 0, change NODE's left child to CHILD,
30 : : // otherwise change NODE's right child to CHILD. If CHILD has a parent
31 : : // field, record that its parent is now NODE.
32 : : template<typename Accessors>
33 : : inline void
34 : 2155593 : base_splay_tree<Accessors>::set_child (node_type node, unsigned int index,
35 : : node_type child)
36 : : {
37 : 71204097 : Accessors::child (node, index) = child;
38 : 331446 : if (child)
39 : 321928 : set_parent (child, node);
40 : 30845298 : }
41 : :
42 : : // Rotate the tree to promote child number INDEX of NODE, so that that
43 : : // child becomes a parent of NODE. Return the promoted node.
44 : : //
45 : : // The caller has the responsibility of assigning a correct parent
46 : : // to the returned node.
47 : : template<typename Accessors>
48 : : inline typename base_splay_tree<Accessors>::node_type
49 : 828409 : base_splay_tree<Accessors>::promote_child (node_type node, unsigned int index)
50 : : {
51 : 828409 : node_type promoted = get_child (node, index);
52 : 376051 : set_child (node, index, get_child (promoted, 1 - index));
53 : 376051 : set_child (promoted, 1 - index, node);
54 : : return promoted;
55 : : }
56 : :
57 : : // Treat child number INDEX of NODE as being CHILD and rotate the tree
58 : : // so that CHILD becomes a parent of NODE.
59 : : //
60 : : // The caller has the responsibility of assigning a correct parent to CHILD.
61 : : template<typename Accessors>
62 : : inline void
63 : 44672260 : base_splay_tree<Accessors>::promote_child (node_type node, unsigned int index,
64 : : node_type child)
65 : : {
66 : 44668381 : set_child (node, index, get_child (child, 1 - index));
67 : 13257748 : set_child (child, 1 - index, node);
68 : 12695142 : }
69 : :
70 : : // Print NODE to PP, using PRINTER (PP, N) to print the contents of node N.
71 : : // Prefix each new line with INDENT_STRING. CODE is 'T' if NODE is the root
72 : : // node, 'L' if NODE is the left child of its parent, or 'R' if NODE is the
73 : : // right child of its parent.
74 : : template<typename Accessors>
75 : : template<typename Printer>
76 : : void
77 : 800 : base_splay_tree<Accessors>::print (pretty_printer *pp, node_type node,
78 : : Printer printer, char code,
79 : : vec<char> &indent_string)
80 : : {
81 : : // In the comments below, PREFIX refers to the incoming contents
82 : : // of INDENT_STRING.
83 : 800 : node_type left = get_child (node, 0);
84 : 800 : node_type right = get_child (node, 1);
85 : :
86 : 800 : auto orig_indent_len = indent_string.length ();
87 : 800 : indent_string.safe_grow (orig_indent_len + 3);
88 : 800 : char *extra_indent = indent_string.address () + orig_indent_len;
89 : :
90 : : // Print [T], [L], or [R].
91 : 800 : extra_indent[0] = '[';
92 : 800 : extra_indent[1] = code;
93 : 800 : extra_indent[2] = ']';
94 : 800 : pp_append_text (pp, extra_indent, indent_string.end ());
95 : 800 : pp_space (pp);
96 : :
97 : : // Print the node itself, using PREFIX + " | " or PREFIX + " " to indent
98 : : // new lines under the "[_]" that we just printed.
99 : 800 : extra_indent[0] = ' ';
100 : 800 : extra_indent[1] = (left || right ? '|' : ' ');
101 : 800 : extra_indent[2] = ' ';
102 : : {
103 : 800 : pretty_printer sub_pp;
104 : 800 : printer (&sub_pp, node);
105 : 800 : const char *text = pp_formatted_text (&sub_pp);
106 : 800 : while (const char *end = strchr (text, '\n'))
107 : : {
108 : 0 : pp_append_text (pp, text, end);
109 : 0 : pp_newline_and_indent (pp, 0);
110 : 0 : pp_append_text (pp, indent_string.begin (), indent_string.end ());
111 : 0 : text = end + 1;
112 : : }
113 : 800 : pp_string (pp, text);
114 : 800 : }
115 : :
116 : 800 : if (left)
117 : : {
118 : : // Print PREFIX + " +-" for the first line of the left subtree,
119 : : // to be followed by "[L]".
120 : 412 : extra_indent[1] = '+';
121 : 412 : extra_indent[2] = '-';
122 : 412 : pp_newline_and_indent (pp, 0);
123 : 412 : pp_append_text (pp, indent_string.begin (), indent_string.end ());
124 : :
125 : : // Print the left subtree, using PREFIX + " | " or PREFIX + " "
126 : : // to indent under the PREFIX + " +-" that we just printed.
127 : 412 : extra_indent[1] = right ? '|' : ' ';
128 : 412 : extra_indent[2] = ' ';
129 : 412 : print (pp, left, printer, 'L', indent_string);
130 : 412 : extra_indent = indent_string.address () + orig_indent_len;
131 : :
132 : : // If LEFT is not a leaf and we also have a right subtree, use a
133 : : // PREFIX + " |" line to separate them.
134 : 412 : if (right && (get_child (left, 0) || get_child (left, 1)))
135 : : {
136 : 192 : pp_newline_and_indent (pp, 0);
137 : 384 : pp_append_text (pp, indent_string.begin (), &extra_indent[2]);
138 : : }
139 : : }
140 : 800 : if (right)
141 : : {
142 : : // Print PREFIX + " +-" for the first line of the right subtree,
143 : : // to be followed by "[R]".
144 : 384 : extra_indent[1] = '+';
145 : 384 : extra_indent[2] = '-';
146 : 384 : pp_newline_and_indent (pp, 0);
147 : 384 : pp_append_text (pp, indent_string.begin (), indent_string.end ());
148 : :
149 : : // Print the right subtree, using PREFIX + " " to indent under the
150 : : // PREFIX + " +-" that we just printed.
151 : 384 : extra_indent[1] = ' ';
152 : 384 : extra_indent[2] = ' ';
153 : 384 : print (pp, right, printer, 'R', indent_string);
154 : : }
155 : 800 : indent_string.truncate (orig_indent_len);
156 : 800 : }
157 : :
158 : : // See the comment above the declaration.
159 : : template<typename Accessors>
160 : : template<typename Printer>
161 : : void
162 : 4 : base_splay_tree<Accessors>::print (pretty_printer *pp, node_type node,
163 : : Printer printer)
164 : : {
165 : 4 : if (!node)
166 : : {
167 : 0 : pp_string (pp, "null");
168 : 0 : return;
169 : : }
170 : 4 : auto_vec<char, 64> indent_string;
171 : 4 : print (pp, node, printer, 'T', indent_string);
172 : 4 : }
173 : :
174 : : // If N is 1, splay the last (rightmost) node reachable from START
175 : : // to the position that START current holds and return the splayed node.
176 : : // START is not itself the last node.
177 : : //
178 : : // If N is 0, splay the first (leftmost) node reachable from START
179 : : // to the position that START current holds and return the splayed node.
180 : : // START is not itself the first node.
181 : : //
182 : : // The caller has the responsibility of updating the parent of the
183 : : // returned node.
184 : : template<typename Accessors>
185 : : template<unsigned int N>
186 : : typename base_splay_tree<Accessors>::node_type
187 : 828409 : base_splay_tree<Accessors>::splay_limit (node_type start)
188 : : {
189 : : // This essentially follows the simpilfied top-down method described
190 : : // in Sleator and Tarjan's "Self-adjusting Binary Search Trees", but
191 : : // specialized for the case in which the comparison result is fixed.
192 : : // The first iteration is peeled to avoid the need for stack temporaries.
193 : : //
194 : : // The comments and names reflect the behavior for N == 1, but the
195 : : // N == 0 case behaves analogously.
196 : :
197 : : // Rotate the tree to promote the right child of START to the root.
198 : 828409 : node_type node = promote_child (start, N);
199 : 828409 : if (node_type right = get_child (node, N))
200 : : {
201 : : // Perform the link left step, which for this first iteration
202 : : // means making NODE the root of the left tree.
203 : : //
204 : : // NODE will become left child of the final node. For a right
205 : : // spine starting at NODE of the form:
206 : : //
207 : : // 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> ... -> N
208 : : // | | | | | | | |
209 : : // V V V V V V V V
210 : : // A B C D E F G NL
211 : : //
212 : : // the next step is to create a subtree of N whose right spine contains
213 : : // the odd-numbered nodes, as follows:
214 : : //
215 : : // N
216 : : // |
217 : : // V
218 : : // 1 ------> 3 ------> 5 ------> 7 -> .... -> NL
219 : : // | | | |
220 : : // V V V V
221 : : // A 2 -> C 4 -> E 6 -> G
222 : : // | | |
223 : : // V V V
224 : : // B D F
225 : : //
226 : : // First record 1 as the left child of the final root (N) and move
227 : : // on to node 2.
228 : : node_type final_child = node;
229 : : node_type new_spine_end = node;
230 : : node = right;
231 : 770851 : while (node_type right = get_child (node, N))
232 : : {
233 : : // Perform another rotate left step.
234 : : //
235 : : // We've built the tree rooted at 1 in the diagram above up to,
236 : : // but not including, an even-numbered node NODE on the original
237 : : // right spine. Rotate the tree at NODE to promote the following
238 : : // odd-numbered node.
239 : 376786 : promote_child (node, N, right);
240 : 376786 : node = right;
241 : 376786 : if (node_type right = get_child (node, N))
242 : : {
243 : : // Perform another link left step.
244 : : //
245 : : // Add the promoted odd-numbered node to the right spine of the
246 : : // tree rooted at 1 and move on to the next even-numbered node.
247 : 258201 : set_child (new_spine_end, N, node);
248 : 258201 : new_spine_end = node;
249 : 258201 : node = right;
250 : : }
251 : : }
252 : : // Perform the assembly step.
253 : : //
254 : : // Add NL to the new spine and make N the new root.
255 : 394256 : set_child (new_spine_end, N, get_child (node, 1 - N));
256 : 394065 : set_child (node, 1 - N, final_child);
257 : : }
258 : 828409 : return node;
259 : : }
260 : :
261 : : // Remove NODE from its position in the splay tree. If NODE has at least
262 : : // one child node, return the node that should now hold NODE's position in
263 : : // the splay tree. If NODE has no children, return null.
264 : : //
265 : : // The caller has the responsibility of updating the parent of the
266 : : // returned node.
267 : : template<typename Accessors>
268 : : inline typename base_splay_tree<Accessors>::node_type
269 : 2385377 : base_splay_tree<Accessors>::remove_node_internal (node_type node)
270 : : {
271 : 2385377 : node_type left = get_child (node, 0);
272 : 2385377 : node_type right = get_child (node, 1);
273 : 2385377 : if (!left)
274 : : return right;
275 : :
276 : 1428673 : if (!right)
277 : : return left;
278 : :
279 : 1184850 : if (get_child (left, 1))
280 : : {
281 : 434653 : left = splay_limit<1> (left);
282 : 434653 : gcc_checking_assert (!get_child (left, 1));
283 : : }
284 : 1184850 : set_child (left, 1, right);
285 : 1184850 : return left;
286 : : }
287 : :
288 : : // See the comment above the declaration.
289 : : template<typename Accessors>
290 : : inline void
291 : 74729394 : base_splay_tree<Accessors>::insert_child (node_type node, unsigned int index,
292 : : node_type child)
293 : : {
294 : 74729394 : gcc_checking_assert (!get_child (child, 0) && !get_child (child, 1));
295 : 74729394 : set_child (child, index, get_child (node, index));
296 : 74729394 : set_child (node, index, child);
297 : 74729394 : }
298 : :
299 : : // Implement splay_next_node if N == 1 and splay_prev_node if N == 0.
300 : : template<typename Accessors>
301 : : template<unsigned int N>
302 : : bool
303 : 30635762 : rooted_splay_tree<Accessors>::splay_neighbor ()
304 : : {
305 : 30635762 : node_type node = m_root;
306 : 30635762 : node_type new_root = get_child (node, N);
307 : 30635762 : if (!new_root)
308 : : return false;
309 : :
310 : 13064849 : if (get_child (new_root, 1 - N))
311 : : {
312 : : // NEW_ROOT is not itself the required node, so splay the required
313 : : // node into its place.
314 : 374055 : new_root = parent::template splay_limit<1 - N> (new_root);
315 : 374055 : gcc_checking_assert (!get_child (new_root, 1 - N));
316 : 374055 : set_child (node, N, node_type ());
317 : 374055 : set_child (new_root, 1 - N, node);
318 : : }
319 : : else
320 : 12690794 : promote_child (node, N, new_root);
321 : : set_parent (new_root, node_type ());
322 : 13064849 : m_root = new_root;
323 : 13064849 : return true;
324 : : }
325 : :
326 : : // See the comment above the declaration.
327 : : template<typename Accessors>
328 : : template<typename Comparator>
329 : : bool
330 : 800 : rooted_splay_tree<Accessors>::insert (node_type new_node, Comparator compare)
331 : : {
332 : 800 : gcc_checking_assert (!get_child (new_node, 0) && !get_child (new_node, 1));
333 : 800 : if (!m_root)
334 : : {
335 : 4 : m_root = new_node;
336 : 4 : return true;
337 : : }
338 : :
339 : 796 : int comparison = lookup (compare);
340 : 796 : if (comparison == 0)
341 : : return false;
342 : :
343 : 796 : insert_relative (comparison, new_node);
344 : 796 : return true;
345 : : }
346 : :
347 : : // See the comment above the declaration.
348 : : template<typename Accessors>
349 : : inline void
350 : 3949638 : rooted_splay_tree<Accessors>::insert_relative (int comparison,
351 : : node_type new_node)
352 : : {
353 : 3949638 : gcc_checking_assert (!get_child (new_node, 0)
354 : : && !get_child (new_node, 1)
355 : : && (!m_root || comparison != 0));
356 : 3949638 : if (m_root)
357 : : {
358 : : // Insert NEW_NODE before M_ROOT if COMPARISON < 0 and after M_ROOT
359 : : // otherwise.
360 : 3949638 : set_child (new_node, comparison < 0, m_root);
361 : 3949638 : set_child (new_node, comparison > 0, get_child (m_root, comparison > 0));
362 : 3949638 : set_child (m_root, comparison > 0, node_type ());
363 : : }
364 : 3949638 : m_root = new_node;
365 : 3949638 : }
366 : :
367 : : // See the comment above the declaration.
368 : : template<typename Accessors>
369 : : inline void
370 : 46279164 : rooted_splay_tree<Accessors>::insert_max_node (node_type new_node)
371 : : {
372 : 46279164 : gcc_checking_assert (!get_child (new_node, 0) && !get_child (new_node, 1));
373 : 46279164 : set_child (new_node, 0, m_root);
374 : 46279164 : m_root = new_node;
375 : 46279164 : }
376 : :
377 : : // See the comment above the declaration.
378 : : template<typename Accessors>
379 : : inline void
380 : 543 : rooted_splay_tree<Accessors>::splice_next_tree (rooted_splay_tree next_tree)
381 : : {
382 : 543 : splay_max_node ();
383 : 543 : set_child (m_root, 1, next_tree.m_root);
384 : 543 : }
385 : :
386 : : // See the comment above the declaration.
387 : : template<typename Accessors>
388 : : inline void
389 : : rooted_splay_tree<Accessors>::replace_max_node_at_root (node_type new_node)
390 : : {
391 : : node_type old_node = m_root;
392 : : gcc_checking_assert (!get_child (new_node, 0)
393 : : && !get_child (new_node, 1)
394 : : && !get_child (old_node, 1));
395 : : set_child (new_node, 0, get_child (old_node, 0));
396 : : // Clear the links from OLD_NODE. Its parent and right child are
397 : : // already node_type ().
398 : : set_child (old_node, 0, node_type ());
399 : : m_root = new_node;
400 : : }
401 : :
402 : : // See the comment above the declaration.
403 : : template<typename Accessors>
404 : : inline void
405 : 1598410 : rooted_splay_tree<Accessors>::remove_root ()
406 : : {
407 : 1598410 : node_type node = m_root;
408 : 1598410 : m_root = parent::remove_node_internal (node);
409 : : if (m_root)
410 : 1598410 : set_parent (m_root, node_type ());
411 : : // Clear the links from NODE. Its parent is already node_type ().
412 : 1598410 : set_child (node, 0, node_type ());
413 : 1598410 : set_child (node, 1, node_type ());
414 : 1598410 : }
415 : :
416 : : // See the comment above the declaration.
417 : : template<typename Accessors>
418 : : inline bool
419 : 19172 : rooted_splay_tree<Accessors>::remove_root_and_splay_next ()
420 : : {
421 : 19172 : node_type node = m_root;
422 : 19172 : node_type right = get_child (node, 1);
423 : 19172 : if (right)
424 : : {
425 : : // Bring the minimum right-hand node to the root.
426 : 163 : if (get_child (right, 0))
427 : : {
428 : 7 : right = parent::template splay_limit<0> (right);
429 : 7 : gcc_checking_assert (!get_child (right, 0));
430 : : }
431 : 163 : set_child (right, 0, get_child (node, 0));
432 : 163 : m_root = right;
433 : : }
434 : : else
435 : 19009 : m_root = get_child (node, 0);
436 : : if (m_root)
437 : 19172 : set_parent (m_root, node_type ());
438 : :
439 : : // Clear the links from NODE. Its parent is already node_type ().
440 : 19172 : set_child (node, 0, node_type ());
441 : 19172 : set_child (node, 1, node_type ());
442 : 19172 : return right;
443 : : }
444 : :
445 : : // See the comment above the declaration.
446 : : template<typename Accessors>
447 : : inline rooted_splay_tree<Accessors>
448 : 7 : rooted_splay_tree<Accessors>::split_before_root ()
449 : : {
450 : 7 : node_type new_root = get_child (m_root, 0);
451 : 7 : set_child (m_root, 0, node_type ());
452 : 3 : set_parent (new_root, node_type ());
453 : 7 : return new_root;
454 : : }
455 : :
456 : : // See the comment above the declaration.
457 : : template<typename Accessors>
458 : : inline rooted_splay_tree<Accessors>
459 : 4 : rooted_splay_tree<Accessors>::split_after_root ()
460 : : {
461 : 4 : node_type new_root = get_child (m_root, 1);
462 : 4 : set_child (m_root, 1, node_type ());
463 : 0 : set_parent (new_root, node_type ());
464 : 4 : return new_root;
465 : : }
466 : :
467 : : // See the comment above the declaration.
468 : : template<typename Accessors>
469 : : inline bool
470 : 8614397 : rooted_splay_tree<Accessors>::splay_prev_node ()
471 : : {
472 : 8614397 : return splay_neighbor<0> ();
473 : : }
474 : :
475 : : // See the comment above the declaration.
476 : : template<typename Accessors>
477 : : inline bool
478 : 22021365 : rooted_splay_tree<Accessors>::splay_next_node ()
479 : : {
480 : 22021365 : return splay_neighbor<1> ();
481 : : }
482 : :
483 : : // See the comment above the declaration.
484 : : template<typename Accessors>
485 : : inline void
486 : 13110 : rooted_splay_tree<Accessors>::splay_min_node ()
487 : : {
488 : 13110 : if (m_root && get_child (m_root, 0))
489 : : {
490 : 8973 : m_root = parent::template splay_limit<0> (m_root);
491 : 8973 : set_parent (m_root, node_type ());
492 : : }
493 : 13110 : }
494 : :
495 : : // See the comment above the declaration.
496 : : template<typename Accessors>
497 : : inline void
498 : 15505 : rooted_splay_tree<Accessors>::splay_max_node ()
499 : : {
500 : 15505 : if (m_root && get_child (m_root, 1))
501 : : {
502 : 10721 : m_root = parent::template splay_limit<1> (m_root);
503 : 10721 : set_parent (m_root, node_type ());
504 : : }
505 : 15505 : }
506 : :
507 : : // See the comment above the declaration.
508 : : template<typename Accessors>
509 : : inline typename rooted_splay_tree<Accessors>::node_type
510 : 4 : rooted_splay_tree<Accessors>::min_node ()
511 : : {
512 : 4 : splay_min_node ();
513 : 4 : return m_root;
514 : : }
515 : :
516 : : // See the comment above the declaration.
517 : : template<typename Accessors>
518 : : inline typename rooted_splay_tree<Accessors>::node_type
519 : 4 : rooted_splay_tree<Accessors>::max_node ()
520 : : {
521 : 4 : splay_max_node ();
522 : 4 : return m_root;
523 : : }
524 : :
525 : : // See the comment above the declaration.
526 : : template<typename Accessors>
527 : : template<typename Comparator>
528 : : auto
529 : 48224360 : rooted_splay_tree<Accessors>::lookup (Comparator compare)
530 : : -> decltype (compare (m_root))
531 : : {
532 : : // This essentially follows the simpilfied top-down method described
533 : : // in Sleator and Tarjan's "Self-adjusting Binary Search Trees", but
534 : : // with the complication that the comparisons are done only once.
535 : : using result_type = decltype (compare (m_root));
536 : :
537 : : // The roots of the left and right trees.
538 : 48224360 : node_type link_left_root = node_type ();
539 : 48224360 : node_type link_right_root = node_type ();
540 : :
541 : : // Where to add new nodes to the left and right trees.
542 : 48224360 : node_type *link_left_ptr = &link_left_root;
543 : 48224360 : node_type *link_right_ptr = &link_right_root;
544 : :
545 : : // The nodes that contain *LINK_LEFT_PTR and *LINK_RIGHT_PTR,
546 : : // once they no longer point to the roots above.
547 : 48224360 : node_type link_left_parent = node_type ();
548 : 48224360 : node_type link_right_parent = node_type ();
549 : :
550 : 57688016 : auto link_left = [&](node_type node)
551 : : {
552 : 9463656 : *link_left_ptr = node;
553 : 9463656 : link_left_ptr = &Accessors::child (node, 1);
554 : 533945 : set_parent (node, link_left_parent);
555 : 9463656 : link_left_parent = node;
556 : : };
557 : :
558 : 79637119 : auto link_right = [&](node_type node)
559 : : {
560 : 31412759 : *link_right_ptr = node;
561 : 31412759 : link_right_ptr = &Accessors::child (node, 0);
562 : 34889 : set_parent (node, link_right_parent);
563 : 31412759 : link_right_parent = node;
564 : : };
565 : :
566 : 48224360 : node_type node = m_root;
567 : 48224360 : node_type parent = node_type ();
568 : : result_type result;
569 : 48224360 : result_type old_result = 0;
570 : : while (1)
571 : : {
572 : : // OLD_RESULT is 0 if NODE is the root of the middle tree.
573 : : // Otherwise, PARENT is the root of the middle tree and OLD_RESULT
574 : : // is how it compared.
575 : : //
576 : : // Results are:
577 : : // < 0 if we want something smaller.
578 : : // = 0 if we found the right node.
579 : : // > 0 if we want something bigger.
580 : 110237438 : result = compare (node);
581 : 110237438 : if (old_result < 0)
582 : : {
583 : 32757298 : if (result < 0)
584 : : {
585 : : // SEARCH < NODE < PARENT
586 : : //
587 : : // Promote NODE (rotate right).
588 : 19685858 : promote_child (parent, 0, node);
589 : 19685858 : node_type next = get_child (node, 0);
590 : 19685858 : if (!next)
591 : : break;
592 : :
593 : 18341319 : link_right (node);
594 : :
595 : : // NEXT is now the root of the middle tree.
596 : 18341319 : node = next;
597 : 18341319 : old_result = 0;
598 : 18341319 : continue;
599 : 18341319 : }
600 : :
601 : : // SEARCH >= NODE, NODE < PARENT
602 : 13071440 : link_right (parent);
603 : : }
604 : 77480140 : else if (old_result > 0)
605 : : {
606 : 9611377 : if (result > 0)
607 : : {
608 : : // SEARCH > NODE > PARENT
609 : : //
610 : : // Promote NODE (rotate left).
611 : 1450805 : promote_child (parent, 1, node);
612 : 1450805 : node_type next = get_child (node, 1);
613 : 1450805 : if (!next)
614 : : break;
615 : :
616 : 1303084 : link_left (node);
617 : :
618 : : // NEXT is now the root of the middle tree.
619 : 1303084 : node = next;
620 : 1303084 : old_result = 0;
621 : 1303084 : continue;
622 : 1303084 : }
623 : :
624 : : // SEARCH <= NODE, NODE > PARENT
625 : 8160572 : link_left (parent);
626 : : }
627 : :
628 : : // Microoptimization to allow NODE to be read even if RESULT == 0.
629 : 89100775 : node_type next = get_child (node, result >= 0);
630 : 89100775 : if (result == 0 || !next)
631 : : break;
632 : :
633 : : // NODE is now the root of the tree.
634 : : parent = node;
635 : : node = next;
636 : : old_result = result;
637 : : }
638 : :
639 : 48224360 : node_type new_left = link_left_root;
640 : 48224360 : node_type new_right = link_right_root;
641 : :
642 : 48224360 : if (new_left)
643 : : {
644 : 8514758 : node_type old_left = get_child (node, 0);
645 : 8514758 : *link_left_ptr = old_left;
646 : 309556 : if (old_left)
647 : 1112 : set_parent (old_left, link_left_parent);
648 : 8514758 : set_child (node, 0, new_left);
649 : : }
650 : :
651 : 48224360 : if (new_right)
652 : : {
653 : 14785289 : node_type old_right = get_child (node, 1);
654 : 14785289 : *link_right_ptr = old_right;
655 : 28931 : if (old_right)
656 : 950 : set_parent (old_right, link_right_parent);
657 : 14785289 : set_child (node, 1, new_right);
658 : : }
659 : :
660 : 334217 : set_parent (node, node_type ());
661 : 48224360 : m_root = node;
662 : 48224360 : return result;
663 : : }
664 : :
665 : : // See the comment above the declaration.
666 : : template<typename Accessors>
667 : : template<typename LeftPredicate, typename RightPredicate>
668 : : int
669 : 2663472 : rooted_splay_tree<Accessors>::lookup (LeftPredicate want_something_smaller,
670 : : RightPredicate want_something_bigger)
671 : : {
672 : : // This essentially follows the simpilfied top-down method described
673 : : // in Sleator and Tarjan's "Self-adjusting Binary Search Trees"
674 : : // (and follows it more closely than the single-comparator version above).
675 : :
676 : : // The roots of the left and right trees.
677 : 2663472 : node_type link_left_root = node_type ();
678 : 2663472 : node_type link_right_root = node_type ();
679 : :
680 : : // Where to add new nodes to the left and right trees.
681 : 2663472 : node_type *link_left_ptr = &link_left_root;
682 : 2663472 : node_type *link_right_ptr = &link_right_root;
683 : :
684 : : // The nodes that contain *LINK_LEFT_PTR and *LINK_RIGHT_PTR,
685 : : // once they no longer point to the roots above.
686 : 2663472 : node_type link_left_parent = node_type ();
687 : 2663472 : node_type link_right_parent = node_type ();
688 : :
689 : 2663472 : node_type node = m_root;
690 : : int result;
691 : : for (;;)
692 : : {
693 : : // NODE is the root of the middle tree.
694 : 15137926 : if (want_something_smaller (node))
695 : : {
696 : 11241760 : result = -1;
697 : 11241760 : node_type next = get_child (node, 0);
698 : 11241760 : if (!next)
699 : : break;
700 : :
701 : 10862476 : if (want_something_smaller (next))
702 : : {
703 : : // Promote NODE (rotate right).
704 : 9871683 : promote_child (node, 0, next);
705 : 9871683 : node = next;
706 : 9871683 : next = get_child (node, 0);
707 : 9871683 : if (!next)
708 : : break;
709 : : }
710 : :
711 : : // Add NODE to the right tree (link right).
712 : 10674895 : *link_right_ptr = node;
713 : 10674895 : link_right_ptr = &Accessors::child (node, 0);
714 : : set_parent (node, link_right_parent);
715 : 10674895 : link_right_parent = node;
716 : :
717 : 10674895 : node = next;
718 : : }
719 : 3896166 : else if (want_something_bigger (node))
720 : : {
721 : 2662412 : result = 1;
722 : 2662412 : node_type next = get_child (node, 1);
723 : 2662412 : if (!next)
724 : : break;
725 : :
726 : 1908373 : if (want_something_bigger (next))
727 : : {
728 : : // Promote NODE (rotate left).
729 : 588107 : promote_child (node, 1, next);
730 : 588107 : node = next;
731 : 588107 : next = get_child (node, 1);
732 : 588107 : if (!next)
733 : : break;
734 : : }
735 : :
736 : : // Add NODE to the left tree (link left).
737 : 1799559 : *link_left_ptr = node;
738 : 1799559 : link_left_ptr = &Accessors::child (node, 1);
739 : : set_parent (node, link_left_parent);
740 : 1799559 : link_left_parent = node;
741 : :
742 : 1799559 : node = next;
743 : : }
744 : : else
745 : : {
746 : : result = 0;
747 : : break;
748 : : }
749 : : }
750 : :
751 : 2663472 : node_type new_left = link_left_root;
752 : 2663472 : node_type new_right = link_right_root;
753 : :
754 : 2663472 : if (new_left)
755 : : {
756 : 1258718 : node_type old_left = get_child (node, 0);
757 : 1258718 : *link_left_ptr = old_left;
758 : : if (old_left)
759 : : set_parent (old_left, link_left_parent);
760 : 1258718 : set_child (node, 0, new_left);
761 : : }
762 : :
763 : 2663472 : if (new_right)
764 : : {
765 : 1568775 : node_type old_right = get_child (node, 1);
766 : 1568775 : *link_right_ptr = old_right;
767 : : if (old_right)
768 : : set_parent (old_right, link_right_parent);
769 : 1568775 : set_child (node, 1, new_right);
770 : : }
771 : :
772 : : set_parent (node, node_type ());
773 : 2663472 : m_root = node;
774 : 2663472 : return result;
775 : : }
776 : :
777 : : // See the comment above the declaration.
778 : : template<typename Accessors>
779 : : template<typename LeftPredicate, typename RightPredicate>
780 : : int
781 : 226467 : rooted_splay_tree<Accessors>::lookup_le (LeftPredicate want_something_smaller,
782 : : RightPredicate want_something_bigger)
783 : : {
784 : 226467 : int comparison = lookup (want_something_smaller, want_something_bigger);
785 : 244201 : if (comparison < 0 && splay_prev_node ())
786 : : comparison = 1;
787 : 226467 : return comparison;
788 : : }
789 : :
790 : : // See the comment above the declaration.
791 : : template<typename Accessors>
792 : : template<typename Printer>
793 : : inline void
794 : 4 : rooted_splay_tree<Accessors>::print (pretty_printer *pp, Printer printer) const
795 : : {
796 : 4 : print (pp, m_root, printer);
797 : : }
798 : :
799 : : // Return NODE's current parent.
800 : : template<typename Accessors>
801 : : inline typename rootless_splay_tree<Accessors>::node_type
802 : 800756 : rootless_splay_tree<Accessors>::get_parent (node_type node)
803 : : {
804 : 800756 : return Accessors::parent (node);
805 : : }
806 : :
807 : : // CHILD is known to be a child of PARENT. Return which index it has.
808 : : template<typename Accessors>
809 : : inline unsigned int
810 : 458623 : rootless_splay_tree<Accessors>::child_index (node_type parent, node_type child)
811 : : {
812 : 463215 : return get_child (parent, 1) == child;
813 : : }
814 : :
815 : : // If N == 1, implement splay_known_max_node, otherwise implement
816 : : // splay_known_min_node.
817 : : template<typename Accessors>
818 : : template<unsigned int N>
819 : : inline void
820 : : rootless_splay_tree<Accessors>::splay_known_limit (node_type node)
821 : : {
822 : : node_type child = node;
823 : : node_type parent = get_parent (child);
824 : : if (!parent)
825 : : return;
826 : :
827 : : do
828 : : // At this point, NODE conceptually replaces CHILD as a child of
829 : : // PARENT, but we haven't yet updated PARENT accordingly.
830 : : if (node_type grandparent = get_parent (parent))
831 : : {
832 : : node_type greatgrandparent = get_parent (grandparent);
833 : : promote_child (grandparent, N, parent);
834 : : promote_child (parent, N, node);
835 : : child = grandparent;
836 : : parent = greatgrandparent;
837 : : }
838 : : else
839 : : {
840 : : promote_child (parent, N, node);
841 : : break;
842 : : }
843 : : while (parent);
844 : : set_parent (node, node_type ());
845 : : }
846 : :
847 : : // See the comment above the declaration.
848 : : template<typename Accessors>
849 : : typename rootless_splay_tree<Accessors>::node_type
850 : 786967 : rootless_splay_tree<Accessors>::remove_node (node_type node)
851 : : {
852 : 786967 : node_type replacement = parent::remove_node_internal (node);
853 : 786967 : if (node_type parent = get_parent (node))
854 : 451161 : set_child (parent, child_index (parent, node), replacement);
855 : 335806 : else if (replacement)
856 : 335806 : set_parent (replacement, node_type ());
857 : : // Clear the links from NODE.
858 : 786967 : set_parent (node, node_type ());
859 : 786967 : set_child (node, 0, node_type ());
860 : 786967 : set_child (node, 1, node_type ());
861 : 786967 : return replacement;
862 : : }
863 : :
864 : : // See the comment above the declaration.
865 : : template<typename Accessors>
866 : : void
867 : : rootless_splay_tree<Accessors>::splay (node_type node)
868 : : {
869 : : node_type child = node;
870 : : node_type parent = get_parent (child);
871 : : if (!parent)
872 : : return;
873 : :
874 : : do
875 : : {
876 : : // At this point, NODE conceptually replaces CHILD as a child of
877 : : // PARENT, but we haven't yet updated PARENT accordingly.
878 : : unsigned int index = child_index (parent, child);
879 : : if (node_type grandparent = get_parent (parent))
880 : : {
881 : : node_type greatgrandparent = get_parent (grandparent);
882 : : unsigned int parent_index = child_index (grandparent, parent);
883 : : if (index == parent_index)
884 : : {
885 : : promote_child (grandparent, parent_index, parent);
886 : : promote_child (parent, index, node);
887 : : }
888 : : else
889 : : {
890 : : promote_child (parent, index, node);
891 : : promote_child (grandparent, parent_index, node);
892 : : }
893 : : child = grandparent;
894 : : parent = greatgrandparent;
895 : : }
896 : : else
897 : : {
898 : : promote_child (parent, index, node);
899 : : break;
900 : : }
901 : : }
902 : : while (parent);
903 : : set_parent (node, node_type ());
904 : : }
905 : :
906 : : // See the comment above the declaration.
907 : : template<typename Accessors>
908 : : inline void
909 : : rootless_splay_tree<Accessors>::splay_known_min_node (node_type node)
910 : : {
911 : : splay_known_limit<0> (node);
912 : : }
913 : :
914 : : // See the comment above the declaration.
915 : : template<typename Accessors>
916 : : inline void
917 : : rootless_splay_tree<Accessors>::splay_known_max_node (node_type node)
918 : : {
919 : : splay_known_limit<1> (node);
920 : : }
921 : :
922 : : // See the comment above the declaration.
923 : : template<typename Accessors>
924 : : template<typename DefaultResult, typename Predicate>
925 : : auto
926 : 4136 : rootless_splay_tree<Accessors>::
927 : : splay_and_search (node_type node, DefaultResult default_result,
928 : : Predicate predicate)
929 : : -> decltype (predicate (node, 0))
930 : : {
931 : : using Result = decltype (predicate (node, 0));
932 : :
933 : 4136 : node_type child = node;
934 : 4136 : node_type parent = get_parent (child);
935 : 4136 : if (!parent)
936 : : return default_result;
937 : :
938 : : do
939 : : {
940 : : // At this point, NODE conceptually replaces CHILD as a child of
941 : : // PARENT, but we haven't yet updated PARENT accordingly.
942 : 7462 : unsigned int index = child_index (parent, child);
943 : 2401 : if (Result result = predicate (parent, index))
944 : : {
945 : 2401 : set_child (parent, index, node);
946 : 2401 : return result;
947 : : }
948 : 5061 : if (node_type grandparent = get_parent (parent))
949 : : {
950 : 4592 : node_type greatgrandparent = get_parent (grandparent);
951 : 4592 : unsigned int parent_index = child_index (grandparent, parent);
952 : 713 : if (Result result = predicate (grandparent, parent_index))
953 : : {
954 : 713 : set_child (parent, index, node);
955 : 713 : return result;
956 : : }
957 : 3879 : if (index == parent_index)
958 : : {
959 : 2225 : promote_child (grandparent, parent_index, parent);
960 : 2225 : promote_child (parent, index, node);
961 : : }
962 : : else
963 : : {
964 : 1654 : promote_child (parent, index, node);
965 : 1654 : promote_child (grandparent, parent_index, node);
966 : : }
967 : 3879 : child = grandparent;
968 : 3879 : parent = greatgrandparent;
969 : : }
970 : : else
971 : : {
972 : 469 : promote_child (parent, index, node);
973 : : break;
974 : : }
975 : : }
976 : 3879 : while (parent);
977 : 815 : set_parent (node, node_type ());
978 : 815 : return default_result;
979 : : }
980 : :
981 : : // Splay NODE1 looking to see if one of its ancestors is NODE2. If it is,
982 : : // return -1 if NODE1 comes before NODE2 or 1 if NODE1 comes after NODE2.
983 : : // Return 0 if NODE2 is not an ancestor of NODE1.
984 : : template<typename Accessors>
985 : : int
986 : 3039 : rootless_splay_tree<Accessors>::compare_nodes_one_way (node_type node1,
987 : : node_type node2)
988 : : {
989 : 13707 : auto compare = [&](node_type parent, unsigned int index) -> int
990 : : {
991 : 10668 : if (parent == node2)
992 : 2017 : return index ? 1 : -1;
993 : : return 0;
994 : : };
995 : 3039 : return splay_and_search (node1, 0, compare);
996 : : }
997 : :
998 : : // See the comment above the declaration.
999 : : template<typename Accessors>
1000 : : int
1001 : 2017 : rootless_splay_tree<Accessors>::compare_nodes (node_type node1,
1002 : : node_type node2)
1003 : : {
1004 : 2017 : if (node1 == node2)
1005 : : return 0;
1006 : :
1007 : : // Splay NODE1 looking for NODE2.
1008 : 2017 : int cmp = compare_nodes_one_way (node1, node2);
1009 : 2017 : if (cmp)
1010 : : return cmp;
1011 : :
1012 : : // That failed, but NODE1 is now the root of the tree. Splay NODE2
1013 : : // to see on which side of NODE1 it falls.
1014 : 1022 : cmp = compare_nodes_one_way (node2, node1);
1015 : 1022 : gcc_checking_assert (cmp);
1016 : 1022 : return -cmp;
1017 : : }
|