/src/serenity/AK/RedBlackTree.h
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org> |
3 | | * |
4 | | * SPDX-License-Identifier: BSD-2-Clause |
5 | | */ |
6 | | |
7 | | #pragma once |
8 | | |
9 | | #include <AK/Concepts.h> |
10 | | #include <AK/Error.h> |
11 | | #include <AK/Noncopyable.h> |
12 | | #include <AK/kmalloc.h> |
13 | | |
14 | | namespace AK { |
15 | | |
16 | | template<Integral K> |
17 | | class BaseRedBlackTree { |
18 | | AK_MAKE_NONCOPYABLE(BaseRedBlackTree); |
19 | | AK_MAKE_NONMOVABLE(BaseRedBlackTree); |
20 | | |
21 | | public: |
22 | 8.76M | [[nodiscard]] size_t size() const { return m_size; } |
23 | 1.58M | [[nodiscard]] bool is_empty() const { return m_size == 0; }AK::BaseRedBlackTree<unsigned long>::is_empty() const Line | Count | Source | 23 | 151k | [[nodiscard]] bool is_empty() const { return m_size == 0; } |
AK::BaseRedBlackTree<unsigned int>::is_empty() const Line | Count | Source | 23 | 1.43M | [[nodiscard]] bool is_empty() const { return m_size == 0; } |
|
24 | | |
25 | | enum class Color : bool { |
26 | | Red, |
27 | | Black |
28 | | }; |
29 | | struct Node { |
30 | | Node* left_child { nullptr }; |
31 | | Node* right_child { nullptr }; |
32 | | Node* parent { nullptr }; |
33 | | |
34 | | Color color { Color::Red }; |
35 | | |
36 | | K key; |
37 | | |
38 | | Node(K key) |
39 | 65.4M | : key(key) |
40 | 65.4M | { |
41 | 65.4M | } AK::BaseRedBlackTree<unsigned long>::Node::Node(unsigned long) Line | Count | Source | 39 | 53.9M | : key(key) | 40 | 53.9M | { | 41 | 53.9M | } |
AK::BaseRedBlackTree<unsigned int>::Node::Node(unsigned int) Line | Count | Source | 39 | 11.4M | : key(key) | 40 | 11.4M | { | 41 | 11.4M | } |
|
42 | | Node() |
43 | | { |
44 | | } |
45 | 65.4M | virtual ~Node() = default; AK::BaseRedBlackTree<unsigned long>::Node::~Node() Line | Count | Source | 45 | 53.9M | virtual ~Node() = default; |
AK::BaseRedBlackTree<unsigned int>::Node::~Node() Line | Count | Source | 45 | 11.4M | virtual ~Node() = default; |
|
46 | | }; |
47 | | |
48 | | protected: |
49 | 9.13M | BaseRedBlackTree() = default; // These are protected to ensure no one instantiates the leaky base red black tree directly AK::BaseRedBlackTree<unsigned long>::BaseRedBlackTree() Line | Count | Source | 49 | 4.04M | BaseRedBlackTree() = default; // These are protected to ensure no one instantiates the leaky base red black tree directly |
AK::BaseRedBlackTree<unsigned int>::BaseRedBlackTree() Line | Count | Source | 49 | 5.08M | BaseRedBlackTree() = default; // These are protected to ensure no one instantiates the leaky base red black tree directly |
|
50 | 9.13M | virtual ~BaseRedBlackTree() = default; AK::BaseRedBlackTree<unsigned long>::~BaseRedBlackTree() Line | Count | Source | 50 | 4.04M | virtual ~BaseRedBlackTree() = default; |
AK::BaseRedBlackTree<unsigned int>::~BaseRedBlackTree() Line | Count | Source | 50 | 5.08M | virtual ~BaseRedBlackTree() = default; |
|
51 | | |
52 | | void rotate_left(Node* subtree_root) |
53 | 57.5M | { |
54 | 57.5M | VERIFY(subtree_root); |
55 | 57.5M | auto* pivot = subtree_root->right_child; |
56 | 57.5M | VERIFY(pivot); |
57 | 57.5M | auto* parent = subtree_root->parent; |
58 | | |
59 | | // stage 1 - subtree_root's right child is now pivot's left child |
60 | 57.5M | subtree_root->right_child = pivot->left_child; |
61 | 57.5M | if (subtree_root->right_child) |
62 | 28.5M | subtree_root->right_child->parent = subtree_root; |
63 | | |
64 | | // stage 2 - pivot's left child is now subtree_root |
65 | 57.5M | pivot->left_child = subtree_root; |
66 | 57.5M | subtree_root->parent = pivot; |
67 | | |
68 | | // stage 3 - update pivot's parent |
69 | 57.5M | pivot->parent = parent; |
70 | 57.5M | if (!parent) { // new root |
71 | 201k | m_root = pivot; |
72 | 57.3M | } else if (parent->left_child == subtree_root) { // we are the left child |
73 | 12.1M | parent->left_child = pivot; |
74 | 45.2M | } else { // we are the right child |
75 | 45.2M | parent->right_child = pivot; |
76 | 45.2M | } |
77 | 57.5M | } AK::BaseRedBlackTree<unsigned long>::rotate_left(AK::BaseRedBlackTree<unsigned long>::Node*) Line | Count | Source | 53 | 49.4M | { | 54 | 49.4M | VERIFY(subtree_root); | 55 | 49.4M | auto* pivot = subtree_root->right_child; | 56 | 49.4M | VERIFY(pivot); | 57 | 49.4M | auto* parent = subtree_root->parent; | 58 | | | 59 | | // stage 1 - subtree_root's right child is now pivot's left child | 60 | 49.4M | subtree_root->right_child = pivot->left_child; | 61 | 49.4M | if (subtree_root->right_child) | 62 | 24.5M | subtree_root->right_child->parent = subtree_root; | 63 | | | 64 | | // stage 2 - pivot's left child is now subtree_root | 65 | 49.4M | pivot->left_child = subtree_root; | 66 | 49.4M | subtree_root->parent = pivot; | 67 | | | 68 | | // stage 3 - update pivot's parent | 69 | 49.4M | pivot->parent = parent; | 70 | 49.4M | if (!parent) { // new root | 71 | 124k | m_root = pivot; | 72 | 49.3M | } else if (parent->left_child == subtree_root) { // we are the left child | 73 | 11.3M | parent->left_child = pivot; | 74 | 37.9M | } else { // we are the right child | 75 | 37.9M | parent->right_child = pivot; | 76 | 37.9M | } | 77 | 49.4M | } |
AK::BaseRedBlackTree<unsigned int>::rotate_left(AK::BaseRedBlackTree<unsigned int>::Node*) Line | Count | Source | 53 | 8.15M | { | 54 | 8.15M | VERIFY(subtree_root); | 55 | 8.15M | auto* pivot = subtree_root->right_child; | 56 | 8.15M | VERIFY(pivot); | 57 | 8.15M | auto* parent = subtree_root->parent; | 58 | | | 59 | | // stage 1 - subtree_root's right child is now pivot's left child | 60 | 8.15M | subtree_root->right_child = pivot->left_child; | 61 | 8.15M | if (subtree_root->right_child) | 62 | 4.00M | subtree_root->right_child->parent = subtree_root; | 63 | | | 64 | | // stage 2 - pivot's left child is now subtree_root | 65 | 8.15M | pivot->left_child = subtree_root; | 66 | 8.15M | subtree_root->parent = pivot; | 67 | | | 68 | | // stage 3 - update pivot's parent | 69 | 8.15M | pivot->parent = parent; | 70 | 8.15M | if (!parent) { // new root | 71 | 76.9k | m_root = pivot; | 72 | 8.07M | } else if (parent->left_child == subtree_root) { // we are the left child | 73 | 774k | parent->left_child = pivot; | 74 | 7.29M | } else { // we are the right child | 75 | 7.29M | parent->right_child = pivot; | 76 | 7.29M | } | 77 | 8.15M | } |
|
78 | | |
79 | | void rotate_right(Node* subtree_root) |
80 | 9.15M | { |
81 | 9.15M | VERIFY(subtree_root); |
82 | 9.15M | auto* pivot = subtree_root->left_child; |
83 | 9.15M | VERIFY(pivot); |
84 | 9.15M | auto* parent = subtree_root->parent; |
85 | | |
86 | | // stage 1 - subtree_root's left child is now pivot's right child |
87 | 9.15M | subtree_root->left_child = pivot->right_child; |
88 | 9.15M | if (subtree_root->left_child) |
89 | 4.41M | subtree_root->left_child->parent = subtree_root; |
90 | | |
91 | | // stage 2 - pivot's right child is now subtree_root |
92 | 9.15M | pivot->right_child = subtree_root; |
93 | 9.15M | subtree_root->parent = pivot; |
94 | | |
95 | | // stage 3 - update pivot's parent |
96 | 9.15M | pivot->parent = parent; |
97 | 9.15M | if (!parent) { // new root |
98 | 269k | m_root = pivot; |
99 | 8.88M | } else if (parent->left_child == subtree_root) { // we are the left child |
100 | 1.18M | parent->left_child = pivot; |
101 | 7.70M | } else { // we are the right child |
102 | 7.70M | parent->right_child = pivot; |
103 | 7.70M | } |
104 | 9.15M | } AK::BaseRedBlackTree<unsigned long>::rotate_right(AK::BaseRedBlackTree<unsigned long>::Node*) Line | Count | Source | 80 | 8.42M | { | 81 | 8.42M | VERIFY(subtree_root); | 82 | 8.42M | auto* pivot = subtree_root->left_child; | 83 | 8.42M | VERIFY(pivot); | 84 | 8.42M | auto* parent = subtree_root->parent; | 85 | | | 86 | | // stage 1 - subtree_root's left child is now pivot's right child | 87 | 8.42M | subtree_root->left_child = pivot->right_child; | 88 | 8.42M | if (subtree_root->left_child) | 89 | 4.06M | subtree_root->left_child->parent = subtree_root; | 90 | | | 91 | | // stage 2 - pivot's right child is now subtree_root | 92 | 8.42M | pivot->right_child = subtree_root; | 93 | 8.42M | subtree_root->parent = pivot; | 94 | | | 95 | | // stage 3 - update pivot's parent | 96 | 8.42M | pivot->parent = parent; | 97 | 8.42M | if (!parent) { // new root | 98 | 3.92k | m_root = pivot; | 99 | 8.41M | } else if (parent->left_child == subtree_root) { // we are the left child | 100 | 1.14M | parent->left_child = pivot; | 101 | 7.26M | } else { // we are the right child | 102 | 7.26M | parent->right_child = pivot; | 103 | 7.26M | } | 104 | 8.42M | } |
AK::BaseRedBlackTree<unsigned int>::rotate_right(AK::BaseRedBlackTree<unsigned int>::Node*) Line | Count | Source | 80 | 735k | { | 81 | 735k | VERIFY(subtree_root); | 82 | 735k | auto* pivot = subtree_root->left_child; | 83 | 735k | VERIFY(pivot); | 84 | 735k | auto* parent = subtree_root->parent; | 85 | | | 86 | | // stage 1 - subtree_root's left child is now pivot's right child | 87 | 735k | subtree_root->left_child = pivot->right_child; | 88 | 735k | if (subtree_root->left_child) | 89 | 350k | subtree_root->left_child->parent = subtree_root; | 90 | | | 91 | | // stage 2 - pivot's right child is now subtree_root | 92 | 735k | pivot->right_child = subtree_root; | 93 | 735k | subtree_root->parent = pivot; | 94 | | | 95 | | // stage 3 - update pivot's parent | 96 | 735k | pivot->parent = parent; | 97 | 735k | if (!parent) { // new root | 98 | 265k | m_root = pivot; | 99 | 469k | } else if (parent->left_child == subtree_root) { // we are the left child | 100 | 37.1k | parent->left_child = pivot; | 101 | 432k | } else { // we are the right child | 102 | 432k | parent->right_child = pivot; | 103 | 432k | } | 104 | 735k | } |
|
105 | | |
106 | | static Node* find(Node* node, K key) |
107 | 16.4k | { |
108 | 59.5k | while (node && node->key != key) { |
109 | 43.0k | if (key < node->key) { |
110 | 7.49k | node = node->left_child; |
111 | 35.5k | } else { |
112 | 35.5k | node = node->right_child; |
113 | 35.5k | } |
114 | 43.0k | } |
115 | 16.4k | return node; |
116 | 16.4k | } AK::BaseRedBlackTree<unsigned long>::find(AK::BaseRedBlackTree<unsigned long>::Node*, unsigned long) Line | Count | Source | 107 | 16.4k | { | 108 | 59.5k | while (node && node->key != key) { | 109 | 43.0k | if (key < node->key) { | 110 | 7.49k | node = node->left_child; | 111 | 35.5k | } else { | 112 | 35.5k | node = node->right_child; | 113 | 35.5k | } | 114 | 43.0k | } | 115 | 16.4k | return node; | 116 | 16.4k | } |
Unexecuted instantiation: AK::BaseRedBlackTree<unsigned int>::find(AK::BaseRedBlackTree<unsigned int>::Node*, unsigned int) |
117 | | |
118 | | static Node* find_largest_not_above(Node* node, K key) |
119 | 40.5M | { |
120 | 40.5M | Node* candidate = nullptr; |
121 | 154M | while (node) { |
122 | 116M | if (key == node->key) |
123 | 1.85M | return node; |
124 | 114M | if (key < node->key) { |
125 | 42.2M | node = node->left_child; |
126 | 72.1M | } else { |
127 | 72.1M | candidate = node; |
128 | 72.1M | node = node->right_child; |
129 | 72.1M | } |
130 | 114M | } |
131 | 38.7M | return candidate; |
132 | 40.5M | } AK::BaseRedBlackTree<unsigned long>::find_largest_not_above(AK::BaseRedBlackTree<unsigned long>::Node*, unsigned long) Line | Count | Source | 119 | 40.5M | { | 120 | 40.5M | Node* candidate = nullptr; | 121 | 154M | while (node) { | 122 | 116M | if (key == node->key) | 123 | 1.85M | return node; | 124 | 114M | if (key < node->key) { | 125 | 42.2M | node = node->left_child; | 126 | 72.1M | } else { | 127 | 72.1M | candidate = node; | 128 | 72.1M | node = node->right_child; | 129 | 72.1M | } | 130 | 114M | } | 131 | 38.7M | return candidate; | 132 | 40.5M | } |
Unexecuted instantiation: AK::BaseRedBlackTree<unsigned int>::find_largest_not_above(AK::BaseRedBlackTree<unsigned int>::Node*, unsigned int) |
133 | | |
134 | | static Node* find_smallest_not_below(Node* node, K key) |
135 | 6.67M | { |
136 | 6.67M | Node* candidate = nullptr; |
137 | 17.8M | while (node) { |
138 | 11.4M | if (node->key == key) |
139 | 273k | return node; |
140 | | |
141 | 11.1M | if (node->key <= key) { |
142 | 1.60M | node = node->right_child; |
143 | 9.56M | } else { |
144 | 9.56M | candidate = node; |
145 | 9.56M | node = node->left_child; |
146 | 9.56M | } |
147 | 11.1M | } |
148 | 6.39M | return candidate; |
149 | 6.67M | } Unexecuted instantiation: AK::BaseRedBlackTree<unsigned long>::find_smallest_not_below(AK::BaseRedBlackTree<unsigned long>::Node*, unsigned long) AK::BaseRedBlackTree<unsigned int>::find_smallest_not_below(AK::BaseRedBlackTree<unsigned int>::Node*, unsigned int) Line | Count | Source | 135 | 6.67M | { | 136 | 6.67M | Node* candidate = nullptr; | 137 | 17.8M | while (node) { | 138 | 11.4M | if (node->key == key) | 139 | 273k | return node; | 140 | | | 141 | 11.1M | if (node->key <= key) { | 142 | 1.60M | node = node->right_child; | 143 | 9.56M | } else { | 144 | 9.56M | candidate = node; | 145 | 9.56M | node = node->left_child; | 146 | 9.56M | } | 147 | 11.1M | } | 148 | 6.39M | return candidate; | 149 | 6.67M | } |
|
150 | | |
151 | | void insert(Node* node) |
152 | 65.4M | { |
153 | 65.4M | VERIFY(node); |
154 | 65.4M | Node* parent = nullptr; |
155 | 65.4M | Node* temp = m_root; |
156 | 1.71G | while (temp) { |
157 | 1.65G | parent = temp; |
158 | 1.65G | if (node->key < temp->key) |
159 | 111M | temp = temp->left_child; |
160 | 1.54G | else |
161 | 1.54G | temp = temp->right_child; |
162 | 1.65G | } |
163 | 65.4M | if (!parent) { // new root |
164 | 6.51M | node->color = Color::Black; |
165 | 6.51M | m_root = node; |
166 | 6.51M | m_size = 1; |
167 | 6.51M | m_minimum = node; |
168 | 6.51M | return; |
169 | 6.51M | } |
170 | 58.8M | if (node->key < parent->key) // we are the left child |
171 | 5.06M | parent->left_child = node; |
172 | 53.8M | else // we are the right child |
173 | 53.8M | parent->right_child = node; |
174 | 58.8M | node->parent = parent; |
175 | | |
176 | 58.8M | if (node->parent->parent) // no fixups to be done for a height <= 2 tree |
177 | 58.3M | insert_fixups(node); |
178 | | |
179 | 58.8M | m_size++; |
180 | 58.8M | if (m_minimum->left_child == node) |
181 | 551k | m_minimum = node; |
182 | 58.8M | } AK::BaseRedBlackTree<unsigned long>::insert(AK::BaseRedBlackTree<unsigned long>::Node*) Line | Count | Source | 152 | 53.9M | { | 153 | 53.9M | VERIFY(node); | 154 | 53.9M | Node* parent = nullptr; | 155 | 53.9M | Node* temp = m_root; | 156 | 1.51G | while (temp) { | 157 | 1.46G | parent = temp; | 158 | 1.46G | if (node->key < temp->key) | 159 | 106M | temp = temp->left_child; | 160 | 1.35G | else | 161 | 1.35G | temp = temp->right_child; | 162 | 1.46G | } | 163 | 53.9M | if (!parent) { // new root | 164 | 3.97M | node->color = Color::Black; | 165 | 3.97M | m_root = node; | 166 | 3.97M | m_size = 1; | 167 | 3.97M | m_minimum = node; | 168 | 3.97M | return; | 169 | 3.97M | } | 170 | 50.0M | if (node->key < parent->key) // we are the left child | 171 | 4.39M | parent->left_child = node; | 172 | 45.6M | else // we are the right child | 173 | 45.6M | parent->right_child = node; | 174 | 50.0M | node->parent = parent; | 175 | | | 176 | 50.0M | if (node->parent->parent) // no fixups to be done for a height <= 2 tree | 177 | 49.7M | insert_fixups(node); | 178 | | | 179 | 50.0M | m_size++; | 180 | 50.0M | if (m_minimum->left_child == node) | 181 | 12.0k | m_minimum = node; | 182 | 50.0M | } |
AK::BaseRedBlackTree<unsigned int>::insert(AK::BaseRedBlackTree<unsigned int>::Node*) Line | Count | Source | 152 | 11.4M | { | 153 | 11.4M | VERIFY(node); | 154 | 11.4M | Node* parent = nullptr; | 155 | 11.4M | Node* temp = m_root; | 156 | 202M | while (temp) { | 157 | 191M | parent = temp; | 158 | 191M | if (node->key < temp->key) | 159 | 4.37M | temp = temp->left_child; | 160 | 186M | else | 161 | 186M | temp = temp->right_child; | 162 | 191M | } | 163 | 11.4M | if (!parent) { // new root | 164 | 2.53M | node->color = Color::Black; | 165 | 2.53M | m_root = node; | 166 | 2.53M | m_size = 1; | 167 | 2.53M | m_minimum = node; | 168 | 2.53M | return; | 169 | 2.53M | } | 170 | 8.87M | if (node->key < parent->key) // we are the left child | 171 | 667k | parent->left_child = node; | 172 | 8.20M | else // we are the right child | 173 | 8.20M | parent->right_child = node; | 174 | 8.87M | node->parent = parent; | 175 | | | 176 | 8.87M | if (node->parent->parent) // no fixups to be done for a height <= 2 tree | 177 | 8.58M | insert_fixups(node); | 178 | | | 179 | 8.87M | m_size++; | 180 | 8.87M | if (m_minimum->left_child == node) | 181 | 539k | m_minimum = node; | 182 | 8.87M | } |
|
183 | | |
184 | | void insert_fixups(Node* node) |
185 | 58.3M | { |
186 | 58.3M | VERIFY(node && node->color == Color::Red); |
187 | 173M | while (node->parent && node->parent->color == Color::Red) { |
188 | 115M | auto* grand_parent = node->parent->parent; |
189 | 115M | if (grand_parent->right_child == node->parent) { |
190 | 106M | auto* uncle = grand_parent->left_child; |
191 | 106M | if (uncle && uncle->color == Color::Red) { |
192 | 57.4M | node->parent->color = Color::Black; |
193 | 57.4M | uncle->color = Color::Black; |
194 | 57.4M | grand_parent->color = Color::Red; |
195 | 57.4M | node = grand_parent; |
196 | 57.4M | } else { |
197 | 48.7M | if (node->parent->left_child == node) { |
198 | 48.2k | node = node->parent; |
199 | 48.2k | rotate_right(node); |
200 | 48.2k | } |
201 | 48.7M | node->parent->color = Color::Black; |
202 | 48.7M | grand_parent->color = Color::Red; |
203 | 48.7M | rotate_left(grand_parent); |
204 | 48.7M | } |
205 | 106M | } else { |
206 | 9.19M | auto* uncle = grand_parent->right_child; |
207 | 9.19M | if (uncle && uncle->color == Color::Red) { |
208 | 87.1k | node->parent->color = Color::Black; |
209 | 87.1k | uncle->color = Color::Black; |
210 | 87.1k | grand_parent->color = Color::Red; |
211 | 87.1k | node = grand_parent; |
212 | 9.10M | } else { |
213 | 9.10M | if (node->parent->right_child == node) { |
214 | 8.82M | node = node->parent; |
215 | 8.82M | rotate_left(node); |
216 | 8.82M | } |
217 | 9.10M | node->parent->color = Color::Black; |
218 | 9.10M | grand_parent->color = Color::Red; |
219 | 9.10M | rotate_right(grand_parent); |
220 | 9.10M | } |
221 | 9.19M | } |
222 | 115M | } |
223 | 58.3M | m_root->color = Color::Black; // the root should always be black |
224 | 58.3M | } AK::BaseRedBlackTree<unsigned long>::insert_fixups(AK::BaseRedBlackTree<unsigned long>::Node*) Line | Count | Source | 185 | 49.7M | { | 186 | 49.7M | VERIFY(node && node->color == Color::Red); | 187 | 148M | while (node->parent && node->parent->color == Color::Red) { | 188 | 98.8M | auto* grand_parent = node->parent->parent; | 189 | 98.8M | if (grand_parent->right_child == node->parent) { | 190 | 90.3M | auto* uncle = grand_parent->left_child; | 191 | 90.3M | if (uncle && uncle->color == Color::Red) { | 192 | 49.3M | node->parent->color = Color::Black; | 193 | 49.3M | uncle->color = Color::Black; | 194 | 49.3M | grand_parent->color = Color::Red; | 195 | 49.3M | node = grand_parent; | 196 | 49.3M | } else { | 197 | 41.0M | if (node->parent->left_child == node) { | 198 | 30.6k | node = node->parent; | 199 | 30.6k | rotate_right(node); | 200 | 30.6k | } | 201 | 41.0M | node->parent->color = Color::Black; | 202 | 41.0M | grand_parent->color = Color::Red; | 203 | 41.0M | rotate_left(grand_parent); | 204 | 41.0M | } | 205 | 90.3M | } else { | 206 | 8.46M | auto* uncle = grand_parent->right_child; | 207 | 8.46M | if (uncle && uncle->color == Color::Red) { | 208 | 77.6k | node->parent->color = Color::Black; | 209 | 77.6k | uncle->color = Color::Black; | 210 | 77.6k | grand_parent->color = Color::Red; | 211 | 77.6k | node = grand_parent; | 212 | 8.38M | } else { | 213 | 8.38M | if (node->parent->right_child == node) { | 214 | 8.37M | node = node->parent; | 215 | 8.37M | rotate_left(node); | 216 | 8.37M | } | 217 | 8.38M | node->parent->color = Color::Black; | 218 | 8.38M | grand_parent->color = Color::Red; | 219 | 8.38M | rotate_right(grand_parent); | 220 | 8.38M | } | 221 | 8.46M | } | 222 | 98.8M | } | 223 | 49.7M | m_root->color = Color::Black; // the root should always be black | 224 | 49.7M | } |
AK::BaseRedBlackTree<unsigned int>::insert_fixups(AK::BaseRedBlackTree<unsigned int>::Node*) Line | Count | Source | 185 | 8.58M | { | 186 | 8.58M | VERIFY(node && node->color == Color::Red); | 187 | 25.1M | while (node->parent && node->parent->color == Color::Red) { | 188 | 16.5M | auto* grand_parent = node->parent->parent; | 189 | 16.5M | if (grand_parent->right_child == node->parent) { | 190 | 15.8M | auto* uncle = grand_parent->left_child; | 191 | 15.8M | if (uncle && uncle->color == Color::Red) { | 192 | 8.12M | node->parent->color = Color::Black; | 193 | 8.12M | uncle->color = Color::Black; | 194 | 8.12M | grand_parent->color = Color::Red; | 195 | 8.12M | node = grand_parent; | 196 | 8.12M | } else { | 197 | 7.69M | if (node->parent->left_child == node) { | 198 | 17.6k | node = node->parent; | 199 | 17.6k | rotate_right(node); | 200 | 17.6k | } | 201 | 7.69M | node->parent->color = Color::Black; | 202 | 7.69M | grand_parent->color = Color::Red; | 203 | 7.69M | rotate_left(grand_parent); | 204 | 7.69M | } | 205 | 15.8M | } else { | 206 | 726k | auto* uncle = grand_parent->right_child; | 207 | 726k | if (uncle && uncle->color == Color::Red) { | 208 | 9.46k | node->parent->color = Color::Black; | 209 | 9.46k | uncle->color = Color::Black; | 210 | 9.46k | grand_parent->color = Color::Red; | 211 | 9.46k | node = grand_parent; | 212 | 717k | } else { | 213 | 717k | if (node->parent->right_child == node) { | 214 | 451k | node = node->parent; | 215 | 451k | rotate_left(node); | 216 | 451k | } | 217 | 717k | node->parent->color = Color::Black; | 218 | 717k | grand_parent->color = Color::Red; | 219 | 717k | rotate_right(grand_parent); | 220 | 717k | } | 221 | 726k | } | 222 | 16.5M | } | 223 | 8.58M | m_root->color = Color::Black; // the root should always be black | 224 | 8.58M | } |
|
225 | | |
226 | | void remove(Node* node) |
227 | 0 | { |
228 | 0 | VERIFY(node); |
229 | | |
230 | | // special case: deleting the only node |
231 | 0 | if (m_size == 1) { |
232 | 0 | m_root = nullptr; |
233 | 0 | m_minimum = nullptr; |
234 | 0 | m_size = 0; |
235 | 0 | return; |
236 | 0 | } |
237 | | |
238 | 0 | if (m_minimum == node) |
239 | 0 | m_minimum = successor(node); |
240 | | |
241 | | // removal assumes the node has 0 or 1 child, so if we have 2, relink with the successor first (by definition the successor has no left child) |
242 | | // FIXME: since we dont know how a value is represented in the node, we can't simply swap the values and keys, and instead we relink the nodes |
243 | | // in place, this is quite a bit more expensive, as well as much less readable, is there a better way? |
244 | 0 | if (node->left_child && node->right_child) { |
245 | 0 | auto* successor_node = successor(node); // this is always non-null as all nodes besides the maximum node have a successor, and the maximum node has no right child |
246 | 0 | auto neighbor_swap = successor_node->parent == node; |
247 | 0 | node->left_child->parent = successor_node; |
248 | 0 | if (!neighbor_swap) |
249 | 0 | node->right_child->parent = successor_node; |
250 | 0 | if (node->parent) { |
251 | 0 | if (node->parent->left_child == node) { |
252 | 0 | node->parent->left_child = successor_node; |
253 | 0 | } else { |
254 | 0 | node->parent->right_child = successor_node; |
255 | 0 | } |
256 | 0 | } else { |
257 | 0 | m_root = successor_node; |
258 | 0 | } |
259 | 0 | if (successor_node->right_child) |
260 | 0 | successor_node->right_child->parent = node; |
261 | 0 | if (neighbor_swap) { |
262 | 0 | successor_node->parent = node->parent; |
263 | 0 | node->parent = successor_node; |
264 | 0 | } else { |
265 | 0 | if (successor_node->parent) { |
266 | 0 | if (successor_node->parent->left_child == successor_node) { |
267 | 0 | successor_node->parent->left_child = node; |
268 | 0 | } else { |
269 | 0 | successor_node->parent->right_child = node; |
270 | 0 | } |
271 | 0 | } else { |
272 | 0 | m_root = node; |
273 | 0 | } |
274 | 0 | swap(node->parent, successor_node->parent); |
275 | 0 | } |
276 | 0 | swap(node->left_child, successor_node->left_child); |
277 | 0 | if (neighbor_swap) { |
278 | 0 | node->right_child = successor_node->right_child; |
279 | 0 | successor_node->right_child = node; |
280 | 0 | } else { |
281 | 0 | swap(node->right_child, successor_node->right_child); |
282 | 0 | } |
283 | 0 | swap(node->color, successor_node->color); |
284 | 0 | } |
285 | |
|
286 | 0 | auto* child = node->left_child ?: node->right_child; |
287 | |
|
288 | 0 | if (child) |
289 | 0 | child->parent = node->parent; |
290 | 0 | if (node->parent) { |
291 | 0 | if (node->parent->left_child == node) |
292 | 0 | node->parent->left_child = child; |
293 | 0 | else |
294 | 0 | node->parent->right_child = child; |
295 | 0 | } else { |
296 | 0 | m_root = child; |
297 | 0 | } |
298 | | |
299 | | // if the node is red then child must be black, and just replacing the node with its child should result in a valid tree (no change to black height) |
300 | 0 | if (node->color != Color::Red) |
301 | 0 | remove_fixups(child, node->parent); |
302 | |
|
303 | 0 | m_size--; |
304 | 0 | } Unexecuted instantiation: AK::BaseRedBlackTree<unsigned long>::remove(AK::BaseRedBlackTree<unsigned long>::Node*) Unexecuted instantiation: AK::BaseRedBlackTree<unsigned int>::remove(AK::BaseRedBlackTree<unsigned int>::Node*) |
305 | | |
306 | | // We maintain parent as a separate argument since node might be null |
307 | | void remove_fixups(Node* node, Node* parent) |
308 | 0 | { |
309 | 0 | while (node != m_root && (!node || node->color == Color::Black)) { |
310 | 0 | if (parent->left_child == node) { |
311 | 0 | auto* sibling = parent->right_child; |
312 | 0 | if (sibling->color == Color::Red) { |
313 | 0 | sibling->color = Color::Black; |
314 | 0 | parent->color = Color::Red; |
315 | 0 | rotate_left(parent); |
316 | 0 | sibling = parent->right_child; |
317 | 0 | } |
318 | 0 | if ((!sibling->left_child || sibling->left_child->color == Color::Black) && (!sibling->right_child || sibling->right_child->color == Color::Black)) { |
319 | 0 | sibling->color = Color::Red; |
320 | 0 | node = parent; |
321 | 0 | } else { |
322 | 0 | if (!sibling->right_child || sibling->right_child->color == Color::Black) { |
323 | 0 | sibling->left_child->color = Color::Black; // null check? |
324 | 0 | sibling->color = Color::Red; |
325 | 0 | rotate_right(sibling); |
326 | 0 | sibling = parent->right_child; |
327 | 0 | } |
328 | 0 | sibling->color = parent->color; |
329 | 0 | parent->color = Color::Black; |
330 | 0 | sibling->right_child->color = Color::Black; // null check? |
331 | 0 | rotate_left(parent); |
332 | 0 | node = m_root; // fixed |
333 | 0 | } |
334 | 0 | } else { |
335 | 0 | auto* sibling = parent->left_child; |
336 | 0 | if (sibling->color == Color::Red) { |
337 | 0 | sibling->color = Color::Black; |
338 | 0 | parent->color = Color::Red; |
339 | 0 | rotate_right(parent); |
340 | 0 | sibling = parent->left_child; |
341 | 0 | } |
342 | 0 | if ((!sibling->left_child || sibling->left_child->color == Color::Black) && (!sibling->right_child || sibling->right_child->color == Color::Black)) { |
343 | 0 | sibling->color = Color::Red; |
344 | 0 | node = parent; |
345 | 0 | } else { |
346 | 0 | if (!sibling->left_child || sibling->left_child->color == Color::Black) { |
347 | 0 | sibling->right_child->color = Color::Black; // null check? |
348 | 0 | sibling->color = Color::Red; |
349 | 0 | rotate_left(sibling); |
350 | 0 | sibling = parent->left_child; |
351 | 0 | } |
352 | 0 | sibling->color = parent->color; |
353 | 0 | parent->color = Color::Black; |
354 | 0 | sibling->left_child->color = Color::Black; // null check? |
355 | 0 | rotate_right(parent); |
356 | 0 | node = m_root; // fixed |
357 | 0 | } |
358 | 0 | } |
359 | 0 | parent = node->parent; |
360 | 0 | } |
361 | 0 | node->color = Color::Black; // by this point node can't be null |
362 | 0 | } Unexecuted instantiation: AK::BaseRedBlackTree<unsigned long>::remove_fixups(AK::BaseRedBlackTree<unsigned long>::Node*, AK::BaseRedBlackTree<unsigned long>::Node*) Unexecuted instantiation: AK::BaseRedBlackTree<unsigned int>::remove_fixups(AK::BaseRedBlackTree<unsigned int>::Node*, AK::BaseRedBlackTree<unsigned int>::Node*) |
363 | | |
364 | | static Node* successor(Node* node) |
365 | 49.6M | { |
366 | 49.6M | VERIFY(node); |
367 | 49.6M | if (node->right_child) { |
368 | 24.1M | node = node->right_child; |
369 | 46.9M | while (node->left_child) |
370 | 22.7M | node = node->left_child; |
371 | 24.1M | return node; |
372 | 24.1M | } |
373 | 25.5M | auto temp = node->parent; |
374 | 48.3M | while (temp && node == temp->right_child) { |
375 | 22.8M | node = temp; |
376 | 22.8M | temp = temp->parent; |
377 | 22.8M | } |
378 | 25.5M | return temp; |
379 | 49.6M | } AK::BaseRedBlackTree<unsigned long>::successor(AK::BaseRedBlackTree<unsigned long>::Node*) Line | Count | Source | 365 | 40.6M | { | 366 | 40.6M | VERIFY(node); | 367 | 40.6M | if (node->right_child) { | 368 | 20.3M | node = node->right_child; | 369 | 40.5M | while (node->left_child) | 370 | 20.2M | node = node->left_child; | 371 | 20.3M | return node; | 372 | 20.3M | } | 373 | 20.3M | auto temp = node->parent; | 374 | 40.6M | while (temp && node == temp->right_child) { | 375 | 20.3M | node = temp; | 376 | 20.3M | temp = temp->parent; | 377 | 20.3M | } | 378 | 20.3M | return temp; | 379 | 40.6M | } |
AK::BaseRedBlackTree<unsigned int>::successor(AK::BaseRedBlackTree<unsigned int>::Node*) Line | Count | Source | 365 | 9.02M | { | 366 | 9.02M | VERIFY(node); | 367 | 9.02M | if (node->right_child) { | 368 | 3.80M | node = node->right_child; | 369 | 6.34M | while (node->left_child) | 370 | 2.53M | node = node->left_child; | 371 | 3.80M | return node; | 372 | 3.80M | } | 373 | 5.22M | auto temp = node->parent; | 374 | 7.75M | while (temp && node == temp->right_child) { | 375 | 2.53M | node = temp; | 376 | 2.53M | temp = temp->parent; | 377 | 2.53M | } | 378 | 5.22M | return temp; | 379 | 9.02M | } |
|
380 | | |
381 | | static Node* predecessor(Node* node) |
382 | 40.5M | { |
383 | 40.5M | VERIFY(node); |
384 | 40.5M | if (node->left_child) { |
385 | 13.6M | node = node->left_child; |
386 | 14.1M | while (node->right_child) |
387 | 478k | node = node->right_child; |
388 | 13.6M | return node; |
389 | 13.6M | } |
390 | 26.9M | auto temp = node->parent; |
391 | 27.8M | while (temp && node == temp->left_child) { |
392 | 914k | node = temp; |
393 | 914k | temp = temp->parent; |
394 | 914k | } |
395 | 26.9M | return temp; |
396 | 40.5M | } AK::BaseRedBlackTree<unsigned long>::predecessor(AK::BaseRedBlackTree<unsigned long>::Node*) Line | Count | Source | 382 | 40.5M | { | 383 | 40.5M | VERIFY(node); | 384 | 40.5M | if (node->left_child) { | 385 | 13.6M | node = node->left_child; | 386 | 14.1M | while (node->right_child) | 387 | 478k | node = node->right_child; | 388 | 13.6M | return node; | 389 | 13.6M | } | 390 | 26.9M | auto temp = node->parent; | 391 | 27.8M | while (temp && node == temp->left_child) { | 392 | 914k | node = temp; | 393 | 914k | temp = temp->parent; | 394 | 914k | } | 395 | 26.9M | return temp; | 396 | 40.5M | } |
Unexecuted instantiation: AK::BaseRedBlackTree<unsigned int>::predecessor(AK::BaseRedBlackTree<unsigned int>::Node*) |
397 | | |
398 | | Node* m_root { nullptr }; |
399 | | size_t m_size { 0 }; |
400 | | Node* m_minimum { nullptr }; // maintained for O(1) begin() |
401 | | }; |
402 | | |
403 | | template<typename TreeType, typename ElementType> |
404 | | class RedBlackTreeIterator { |
405 | | public: |
406 | 10.4M | RedBlackTreeIterator() = default; Unexecuted instantiation: AK::RedBlackTreeIterator<AK::RedBlackTree<unsigned long, unsigned long> const, unsigned long const>::RedBlackTreeIterator() Unexecuted instantiation: AK::RedBlackTreeIterator<AK::RedBlackTree<unsigned long, JS::Value> const, JS::Value const>::RedBlackTreeIterator() AK::RedBlackTreeIterator<AK::RedBlackTree<unsigned long, regex::CharRange>, regex::CharRange>::RedBlackTreeIterator() Line | Count | Source | 406 | 18.6k | RedBlackTreeIterator() = default; |
AK::RedBlackTreeIterator<AK::RedBlackTree<unsigned int, unsigned int>, unsigned int>::RedBlackTreeIterator() Line | Count | Source | 406 | 10.4M | RedBlackTreeIterator() = default; |
Unexecuted instantiation: AK::RedBlackTreeIterator<AK::RedBlackTree<unsigned int, AK::Optional<Line::Style::Mask> > const, AK::Optional<Line::Style::Mask> const>::RedBlackTreeIterator() Unexecuted instantiation: AK::RedBlackTreeIterator<AK::RedBlackTree<unsigned long, Web::Animations::KeyframeEffect::KeyFrameSet::ResolvedKeyFrame> const, Web::Animations::KeyframeEffect::KeyFrameSet::ResolvedKeyFrame const>::RedBlackTreeIterator() |
407 | 51.1M | bool operator!=(RedBlackTreeIterator const& other) const { return m_node != other.m_node; }AK::RedBlackTreeIterator<AK::RedBlackTree<unsigned long, regex::CharRange>, regex::CharRange>::operator!=(AK::RedBlackTreeIterator<AK::RedBlackTree<unsigned long, regex::CharRange>, regex::CharRange> const&) const Line | Count | Source | 407 | 40.6M | bool operator!=(RedBlackTreeIterator const& other) const { return m_node != other.m_node; } |
AK::RedBlackTreeIterator<AK::RedBlackTree<unsigned int, unsigned int>, unsigned int>::operator!=(AK::RedBlackTreeIterator<AK::RedBlackTree<unsigned int, unsigned int>, unsigned int> const&) const Line | Count | Source | 407 | 10.4M | bool operator!=(RedBlackTreeIterator const& other) const { return m_node != other.m_node; } |
|
408 | | RedBlackTreeIterator& operator++() |
409 | 49.6M | { |
410 | 49.6M | if (!m_node) |
411 | 0 | return *this; |
412 | 49.6M | m_prev = m_node; |
413 | | // the complexity is O(logn) for each successor call, but the total complexity for all elements comes out to O(n), meaning the amortized cost for a single call is O(1) |
414 | 49.6M | m_node = static_cast<typename TreeType::Node*>(TreeType::successor(m_node)); |
415 | 49.6M | return *this; |
416 | 49.6M | } Unexecuted instantiation: AK::RedBlackTreeIterator<AK::RedBlackTree<unsigned long, JS::Value>, JS::Value>::operator++() AK::RedBlackTreeIterator<AK::RedBlackTree<unsigned long, regex::CharRange>, regex::CharRange>::operator++() Line | Count | Source | 409 | 40.6M | { | 410 | 40.6M | if (!m_node) | 411 | 0 | return *this; | 412 | 40.6M | m_prev = m_node; | 413 | | // the complexity is O(logn) for each successor call, but the total complexity for all elements comes out to O(n), meaning the amortized cost for a single call is O(1) | 414 | 40.6M | m_node = static_cast<typename TreeType::Node*>(TreeType::successor(m_node)); | 415 | 40.6M | return *this; | 416 | 40.6M | } |
AK::RedBlackTreeIterator<AK::RedBlackTree<unsigned int, unsigned int>, unsigned int>::operator++() Line | Count | Source | 409 | 9.02M | { | 410 | 9.02M | if (!m_node) | 411 | 0 | return *this; | 412 | 9.02M | m_prev = m_node; | 413 | | // the complexity is O(logn) for each successor call, but the total complexity for all elements comes out to O(n), meaning the amortized cost for a single call is O(1) | 414 | 9.02M | m_node = static_cast<typename TreeType::Node*>(TreeType::successor(m_node)); | 415 | 9.02M | return *this; | 416 | 9.02M | } |
Unexecuted instantiation: AK::RedBlackTreeIterator<AK::RedBlackTree<unsigned int, AK::Optional<Line::Style::Mask> > const, AK::Optional<Line::Style::Mask> const>::operator++() Unexecuted instantiation: AK::RedBlackTreeIterator<AK::RedBlackTree<unsigned long, Web::Animations::KeyframeEffect::KeyFrameSet::ResolvedKeyFrame> const, Web::Animations::KeyframeEffect::KeyFrameSet::ResolvedKeyFrame const>::operator++() |
417 | | RedBlackTreeIterator& operator--() |
418 | | { |
419 | | if (!m_prev) |
420 | | return *this; |
421 | | m_node = m_prev; |
422 | | m_prev = static_cast<typename TreeType::Node*>(TreeType::predecessor(m_prev)); |
423 | | return *this; |
424 | | } |
425 | 91.6M | ElementType& operator*() { return m_node->value; }AK::RedBlackTreeIterator<AK::RedBlackTree<unsigned long, unsigned long> const, unsigned long const>::operator*() Line | Count | Source | 425 | 40.5M | ElementType& operator*() { return m_node->value; } |
Unexecuted instantiation: AK::RedBlackTreeIterator<AK::RedBlackTree<unsigned long, JS::Value> const, JS::Value const>::operator*() Unexecuted instantiation: AK::RedBlackTreeIterator<AK::RedBlackTree<unsigned long, JS::Value>, JS::Value>::operator*() AK::RedBlackTreeIterator<AK::RedBlackTree<unsigned long, regex::CharRange>, regex::CharRange>::operator*() Line | Count | Source | 425 | 40.6M | ElementType& operator*() { return m_node->value; } |
AK::RedBlackTreeIterator<AK::RedBlackTree<unsigned int, unsigned int>, unsigned int>::operator*() Line | Count | Source | 425 | 10.4M | ElementType& operator*() { return m_node->value; } |
Unexecuted instantiation: AK::RedBlackTreeIterator<AK::RedBlackTree<unsigned int, AK::Optional<Line::Style::Mask> > const, AK::Optional<Line::Style::Mask> const>::operator*() Unexecuted instantiation: AK::RedBlackTreeIterator<AK::RedBlackTree<unsigned long, Web::Animations::KeyframeEffect::KeyFrameSet::ResolvedKeyFrame> const, Web::Animations::KeyframeEffect::KeyFrameSet::ResolvedKeyFrame const>::operator*() |
426 | 0 | ElementType* operator->() { return &m_node->value; } |
427 | 0 | [[nodiscard]] bool is_end() const { return !m_node; }Unexecuted instantiation: AK::RedBlackTreeIterator<AK::RedBlackTree<unsigned long, JS::Value> const, JS::Value const>::is_end() const Unexecuted instantiation: AK::RedBlackTreeIterator<AK::RedBlackTree<unsigned long, JS::Value>, JS::Value>::is_end() const Unexecuted instantiation: AK::RedBlackTreeIterator<AK::RedBlackTree<unsigned long, unsigned long> const, unsigned long const>::is_end() const Unexecuted instantiation: AK::RedBlackTreeIterator<AK::RedBlackTree<unsigned int, AK::Optional<Line::Style::Mask> > const, AK::Optional<Line::Style::Mask> const>::is_end() const Unexecuted instantiation: AK::RedBlackTreeIterator<AK::RedBlackTree<unsigned long, Web::Animations::KeyframeEffect::KeyFrameSet::ResolvedKeyFrame> const, Web::Animations::KeyframeEffect::KeyFrameSet::ResolvedKeyFrame const>::is_end() const |
428 | | [[nodiscard]] bool is_begin() const { return !m_prev; } |
429 | | |
430 | 51.0M | [[nodiscard]] auto key() const { return m_node->key; }AK::RedBlackTreeIterator<AK::RedBlackTree<unsigned long, unsigned long> const, unsigned long const>::key() const Line | Count | Source | 430 | 40.5M | [[nodiscard]] auto key() const { return m_node->key; } |
Unexecuted instantiation: AK::RedBlackTreeIterator<AK::RedBlackTree<unsigned long, JS::Value> const, JS::Value const>::key() const Unexecuted instantiation: AK::RedBlackTreeIterator<AK::RedBlackTree<unsigned long, JS::Value>, JS::Value>::key() const AK::RedBlackTreeIterator<AK::RedBlackTree<unsigned int, unsigned int>, unsigned int>::key() const Line | Count | Source | 430 | 10.4M | [[nodiscard]] auto key() const { return m_node->key; } |
Unexecuted instantiation: AK::RedBlackTreeIterator<AK::RedBlackTree<unsigned int, AK::Optional<Line::Style::Mask> > const, AK::Optional<Line::Style::Mask> const>::key() const Unexecuted instantiation: AK::RedBlackTreeIterator<AK::RedBlackTree<unsigned long, Web::Animations::KeyframeEffect::KeyFrameSet::ResolvedKeyFrame> const, Web::Animations::KeyframeEffect::KeyFrameSet::ResolvedKeyFrame const>::key() const Unexecuted instantiation: AK::RedBlackTreeIterator<AK::RedBlackTree<unsigned long, Web::Animations::KeyframeEffect::KeyFrameSet::ResolvedKeyFrame>, Web::Animations::KeyframeEffect::KeyFrameSet::ResolvedKeyFrame>::key() const |
431 | | |
432 | | private: |
433 | | friend TreeType; |
434 | | explicit RedBlackTreeIterator(typename TreeType::Node* node, typename TreeType::Node* prev = nullptr) |
435 | 42.0M | : m_node(node) |
436 | 42.0M | , m_prev(prev) |
437 | 42.0M | { |
438 | 42.0M | } AK::RedBlackTreeIterator<AK::RedBlackTree<unsigned long, unsigned long> const, unsigned long const>::RedBlackTreeIterator(AK::RedBlackTree<unsigned long, unsigned long>::Node*, AK::RedBlackTree<unsigned long, unsigned long>::Node*) Line | Count | Source | 435 | 40.5M | : m_node(node) | 436 | 40.5M | , m_prev(prev) | 437 | 40.5M | { | 438 | 40.5M | } |
Unexecuted instantiation: AK::RedBlackTreeIterator<AK::RedBlackTree<unsigned long, JS::Value> const, JS::Value const>::RedBlackTreeIterator(AK::RedBlackTree<unsigned long, JS::Value>::Node*, AK::RedBlackTree<unsigned long, JS::Value>::Node*) Unexecuted instantiation: AK::RedBlackTreeIterator<AK::RedBlackTree<unsigned long, JS::Value>, JS::Value>::RedBlackTreeIterator(AK::RedBlackTree<unsigned long, JS::Value>::Node*, AK::RedBlackTree<unsigned long, JS::Value>::Node*) AK::RedBlackTreeIterator<AK::RedBlackTree<unsigned long, regex::CharRange>, regex::CharRange>::RedBlackTreeIterator(AK::RedBlackTree<unsigned long, regex::CharRange>::Node*, AK::RedBlackTree<unsigned long, regex::CharRange>::Node*) Line | Count | Source | 435 | 18.6k | : m_node(node) | 436 | 18.6k | , m_prev(prev) | 437 | 18.6k | { | 438 | 18.6k | } |
AK::RedBlackTreeIterator<AK::RedBlackTree<unsigned int, unsigned int>, unsigned int>::RedBlackTreeIterator(AK::RedBlackTree<unsigned int, unsigned int>::Node*, AK::RedBlackTree<unsigned int, unsigned int>::Node*) Line | Count | Source | 435 | 1.43M | : m_node(node) | 436 | 1.43M | , m_prev(prev) | 437 | 1.43M | { | 438 | 1.43M | } |
Unexecuted instantiation: AK::RedBlackTreeIterator<AK::RedBlackTree<unsigned int, AK::Optional<Line::Style::Mask> > const, AK::Optional<Line::Style::Mask> const>::RedBlackTreeIterator(AK::RedBlackTree<unsigned int, AK::Optional<Line::Style::Mask> >::Node*, AK::RedBlackTree<unsigned int, AK::Optional<Line::Style::Mask> >::Node*) Unexecuted instantiation: AK::RedBlackTreeIterator<AK::RedBlackTree<unsigned long, Web::Animations::KeyframeEffect::KeyFrameSet::ResolvedKeyFrame> const, Web::Animations::KeyframeEffect::KeyFrameSet::ResolvedKeyFrame const>::RedBlackTreeIterator(AK::RedBlackTree<unsigned long, Web::Animations::KeyframeEffect::KeyFrameSet::ResolvedKeyFrame>::Node*, AK::RedBlackTree<unsigned long, Web::Animations::KeyframeEffect::KeyFrameSet::ResolvedKeyFrame>::Node*) |
439 | | typename TreeType::Node* m_node { nullptr }; |
440 | | typename TreeType::Node* m_prev { nullptr }; |
441 | | }; |
442 | | |
443 | | template<Integral K, typename V> |
444 | | class RedBlackTree final : public BaseRedBlackTree<K> { |
445 | | public: |
446 | 9.13M | RedBlackTree() = default; AK::RedBlackTree<unsigned long, unsigned long>::RedBlackTree() Line | Count | Source | 446 | 3.95M | RedBlackTree() = default; |
Unexecuted instantiation: AK::RedBlackTree<unsigned long, JS::Value>::RedBlackTree() AK::RedBlackTree<unsigned long, regex::CharRange>::RedBlackTree() Line | Count | Source | 446 | 92.1k | RedBlackTree() = default; |
AK::RedBlackTree<unsigned int, unsigned int>::RedBlackTree() Line | Count | Source | 446 | 5.08M | RedBlackTree() = default; |
Unexecuted instantiation: AK::RedBlackTree<unsigned int, AK::Optional<Line::Style::Mask> >::RedBlackTree() Unexecuted instantiation: AK::RedBlackTree<unsigned long, Web::Animations::KeyframeEffect::KeyFrameSet::ResolvedKeyFrame>::RedBlackTree() Unexecuted instantiation: AK::RedBlackTree<unsigned long, AK::DistinctNumeric<unsigned long, Wasm::__FunctionIndex_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool> >::RedBlackTree() |
447 | | virtual ~RedBlackTree() override |
448 | 9.13M | { |
449 | 9.13M | clear(); |
450 | 9.13M | } AK::RedBlackTree<unsigned long, unsigned long>::~RedBlackTree() Line | Count | Source | 448 | 3.95M | { | 449 | 3.95M | clear(); | 450 | 3.95M | } |
Unexecuted instantiation: AK::RedBlackTree<unsigned long, JS::Value>::~RedBlackTree() AK::RedBlackTree<unsigned long, regex::CharRange>::~RedBlackTree() Line | Count | Source | 448 | 92.1k | { | 449 | 92.1k | clear(); | 450 | 92.1k | } |
AK::RedBlackTree<unsigned int, unsigned int>::~RedBlackTree() Line | Count | Source | 448 | 5.08M | { | 449 | 5.08M | clear(); | 450 | 5.08M | } |
Unexecuted instantiation: AK::RedBlackTree<unsigned int, AK::Optional<Line::Style::Mask> >::~RedBlackTree() Unexecuted instantiation: AK::RedBlackTree<unsigned long, Web::Animations::KeyframeEffect::KeyFrameSet::ResolvedKeyFrame>::~RedBlackTree() Unexecuted instantiation: AK::RedBlackTree<unsigned long, AK::DistinctNumeric<unsigned long, Wasm::__FunctionIndex_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool> >::~RedBlackTree() |
451 | | |
452 | | using BaseTree = BaseRedBlackTree<K>; |
453 | | |
454 | | [[nodiscard]] V* find(K key) |
455 | 16.4k | { |
456 | 16.4k | auto* node = static_cast<Node*>(BaseTree::find(this->m_root, key)); |
457 | 16.4k | if (!node) |
458 | 0 | return nullptr; |
459 | 16.4k | return &node->value; |
460 | 16.4k | } AK::RedBlackTree<unsigned long, unsigned long>::find(unsigned long) Line | Count | Source | 455 | 16.4k | { | 456 | 16.4k | auto* node = static_cast<Node*>(BaseTree::find(this->m_root, key)); | 457 | 16.4k | if (!node) | 458 | 0 | return nullptr; | 459 | 16.4k | return &node->value; | 460 | 16.4k | } |
Unexecuted instantiation: AK::RedBlackTree<unsigned long, Web::Animations::KeyframeEffect::KeyFrameSet::ResolvedKeyFrame>::find(unsigned long) Unexecuted instantiation: AK::RedBlackTree<unsigned long, AK::DistinctNumeric<unsigned long, Wasm::__FunctionIndex_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool> >::find(unsigned long) |
461 | | |
462 | | [[nodiscard]] V* find_largest_not_above(K key) |
463 | | { |
464 | | auto* node = static_cast<Node*>(BaseTree::find_largest_not_above(this->m_root, key)); |
465 | | if (!node) |
466 | | return nullptr; |
467 | | return &node->value; |
468 | | } |
469 | | |
470 | | [[nodiscard]] V* find_smallest_not_below(K key) |
471 | 6.67M | { |
472 | 6.67M | auto* node = static_cast<Node*>(BaseTree::find_smallest_not_below(this->m_root, key)); |
473 | 6.67M | if (!node) |
474 | 1.11M | return nullptr; |
475 | 5.55M | return &node->value; |
476 | 6.67M | } |
477 | | |
478 | | ErrorOr<void> try_insert(K key, V const& value) |
479 | 13.2M | { |
480 | 13.2M | return try_insert(key, V(value)); |
481 | 13.2M | } Unexecuted instantiation: AK::RedBlackTree<unsigned long, JS::Value>::try_insert(unsigned long, JS::Value const&) AK::RedBlackTree<unsigned long, regex::CharRange>::try_insert(unsigned long, regex::CharRange const&) Line | Count | Source | 479 | 4.63M | { | 480 | 4.63M | return try_insert(key, V(value)); | 481 | 4.63M | } |
AK::RedBlackTree<unsigned long, unsigned long>::try_insert(unsigned long, unsigned long const&) Line | Count | Source | 479 | 4.34M | { | 480 | 4.34M | return try_insert(key, V(value)); | 481 | 4.34M | } |
AK::RedBlackTree<unsigned int, unsigned int>::try_insert(unsigned int, unsigned int const&) Line | Count | Source | 479 | 4.31M | { | 480 | 4.31M | return try_insert(key, V(value)); | 481 | 4.31M | } |
Unexecuted instantiation: AK::RedBlackTree<unsigned long, Web::Animations::KeyframeEffect::KeyFrameSet::ResolvedKeyFrame>::try_insert(unsigned long, Web::Animations::KeyframeEffect::KeyFrameSet::ResolvedKeyFrame const&) Unexecuted instantiation: AK::RedBlackTree<unsigned long, AK::DistinctNumeric<unsigned long, Wasm::__FunctionIndex_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool> >::try_insert(unsigned long, AK::DistinctNumeric<unsigned long, Wasm::__FunctionIndex_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool> const&) |
482 | | |
483 | | void insert(K key, V const& value) |
484 | 13.2M | { |
485 | 13.2M | MUST(try_insert(key, value)); |
486 | 13.2M | } Unexecuted instantiation: AK::RedBlackTree<unsigned long, JS::Value>::insert(unsigned long, JS::Value const&) AK::RedBlackTree<unsigned long, regex::CharRange>::insert(unsigned long, regex::CharRange const&) Line | Count | Source | 484 | 4.63M | { | 485 | 4.63M | MUST(try_insert(key, value)); | 486 | 4.63M | } |
AK::RedBlackTree<unsigned long, unsigned long>::insert(unsigned long, unsigned long const&) Line | Count | Source | 484 | 4.34M | { | 485 | 4.34M | MUST(try_insert(key, value)); | 486 | 4.34M | } |
AK::RedBlackTree<unsigned int, unsigned int>::insert(unsigned int, unsigned int const&) Line | Count | Source | 484 | 4.31M | { | 485 | 4.31M | MUST(try_insert(key, value)); | 486 | 4.31M | } |
Unexecuted instantiation: AK::RedBlackTree<unsigned long, Web::Animations::KeyframeEffect::KeyFrameSet::ResolvedKeyFrame>::insert(unsigned long, Web::Animations::KeyframeEffect::KeyFrameSet::ResolvedKeyFrame const&) Unexecuted instantiation: AK::RedBlackTree<unsigned long, AK::DistinctNumeric<unsigned long, Wasm::__FunctionIndex_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool> >::insert(unsigned long, AK::DistinctNumeric<unsigned long, Wasm::__FunctionIndex_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool> const&) |
487 | | |
488 | | ErrorOr<void> try_insert(K key, V&& value) |
489 | 65.4M | { |
490 | 65.4M | auto* node = new (nothrow) Node(key, move(value)); |
491 | 65.4M | if (!node) |
492 | 0 | return Error::from_errno(ENOMEM); |
493 | 65.4M | BaseTree::insert(node); |
494 | 65.4M | return {}; |
495 | 65.4M | } AK::RedBlackTree<unsigned long, unsigned long>::try_insert(unsigned long, unsigned long&&) Line | Count | Source | 489 | 13.3M | { | 490 | 13.3M | auto* node = new (nothrow) Node(key, move(value)); | 491 | 13.3M | if (!node) | 492 | 0 | return Error::from_errno(ENOMEM); | 493 | 13.3M | BaseTree::insert(node); | 494 | 13.3M | return {}; | 495 | 13.3M | } |
Unexecuted instantiation: AK::RedBlackTree<unsigned long, JS::Value>::try_insert(unsigned long, JS::Value&&) AK::RedBlackTree<unsigned long, regex::CharRange>::try_insert(unsigned long, regex::CharRange&&) Line | Count | Source | 489 | 40.6M | { | 490 | 40.6M | auto* node = new (nothrow) Node(key, move(value)); | 491 | 40.6M | if (!node) | 492 | 0 | return Error::from_errno(ENOMEM); | 493 | 40.6M | BaseTree::insert(node); | 494 | 40.6M | return {}; | 495 | 40.6M | } |
AK::RedBlackTree<unsigned int, unsigned int>::try_insert(unsigned int, unsigned int&&) Line | Count | Source | 489 | 11.4M | { | 490 | 11.4M | auto* node = new (nothrow) Node(key, move(value)); | 491 | 11.4M | if (!node) | 492 | 0 | return Error::from_errno(ENOMEM); | 493 | 11.4M | BaseTree::insert(node); | 494 | 11.4M | return {}; | 495 | 11.4M | } |
Unexecuted instantiation: AK::RedBlackTree<unsigned int, AK::Optional<Line::Style::Mask> >::try_insert(unsigned int, AK::Optional<Line::Style::Mask>&&) Unexecuted instantiation: AK::RedBlackTree<unsigned long, Web::Animations::KeyframeEffect::KeyFrameSet::ResolvedKeyFrame>::try_insert(unsigned long, Web::Animations::KeyframeEffect::KeyFrameSet::ResolvedKeyFrame&&) Unexecuted instantiation: AK::RedBlackTree<unsigned long, AK::DistinctNumeric<unsigned long, Wasm::__FunctionIndex_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool> >::try_insert(unsigned long, AK::DistinctNumeric<unsigned long, Wasm::__FunctionIndex_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool>&&) |
496 | | |
497 | | void insert(K key, V&& value) |
498 | 52.1M | { |
499 | 52.1M | MUST(try_insert(key, move(value))); |
500 | 52.1M | } AK::RedBlackTree<unsigned long, unsigned long>::insert(unsigned long, unsigned long&&) Line | Count | Source | 498 | 9.02M | { | 499 | 9.02M | MUST(try_insert(key, move(value))); | 500 | 9.02M | } |
AK::RedBlackTree<unsigned long, regex::CharRange>::insert(unsigned long, regex::CharRange&&) Line | Count | Source | 498 | 35.9M | { | 499 | 35.9M | MUST(try_insert(key, move(value))); | 500 | 35.9M | } |
AK::RedBlackTree<unsigned int, unsigned int>::insert(unsigned int, unsigned int&&) Line | Count | Source | 498 | 7.09M | { | 499 | 7.09M | MUST(try_insert(key, move(value))); | 500 | 7.09M | } |
Unexecuted instantiation: AK::RedBlackTree<unsigned int, AK::Optional<Line::Style::Mask> >::insert(unsigned int, AK::Optional<Line::Style::Mask>&&) Unexecuted instantiation: AK::RedBlackTree<unsigned long, Web::Animations::KeyframeEffect::KeyFrameSet::ResolvedKeyFrame>::insert(unsigned long, Web::Animations::KeyframeEffect::KeyFrameSet::ResolvedKeyFrame&&) |
501 | | |
502 | | using Iterator = RedBlackTreeIterator<RedBlackTree, V>; |
503 | | friend Iterator; |
504 | 1.45M | Iterator begin() { return Iterator(static_cast<Node*>(this->m_minimum)); }Unexecuted instantiation: AK::RedBlackTree<unsigned long, JS::Value>::begin() AK::RedBlackTree<unsigned long, regex::CharRange>::begin() Line | Count | Source | 504 | 18.6k | Iterator begin() { return Iterator(static_cast<Node*>(this->m_minimum)); } |
AK::RedBlackTree<unsigned int, unsigned int>::begin() Line | Count | Source | 504 | 1.43M | Iterator begin() { return Iterator(static_cast<Node*>(this->m_minimum)); } |
|
505 | 10.4M | Iterator end() { return {}; }AK::RedBlackTree<unsigned long, regex::CharRange>::end() Line | Count | Source | 505 | 18.6k | Iterator end() { return {}; } |
AK::RedBlackTree<unsigned int, unsigned int>::end() Line | Count | Source | 505 | 10.4M | Iterator end() { return {}; } |
|
506 | 0 | Iterator begin_from(K key) { return Iterator(static_cast<Node*>(BaseTree::find(this->m_root, key))); } |
507 | | |
508 | | using ConstIterator = RedBlackTreeIterator<RedBlackTree const, V const>; |
509 | | friend ConstIterator; |
510 | 0 | ConstIterator begin() const { return ConstIterator(static_cast<Node*>(this->m_minimum)); }Unexecuted instantiation: AK::RedBlackTree<unsigned long, JS::Value>::begin() const Unexecuted instantiation: AK::RedBlackTree<unsigned int, AK::Optional<Line::Style::Mask> >::begin() const |
511 | 0 | ConstIterator end() const { return {}; }Unexecuted instantiation: AK::RedBlackTree<unsigned long, unsigned long>::end() const Unexecuted instantiation: AK::RedBlackTree<unsigned long, JS::Value>::end() const Unexecuted instantiation: AK::RedBlackTree<unsigned int, AK::Optional<Line::Style::Mask> >::end() const Unexecuted instantiation: AK::RedBlackTree<unsigned long, Web::Animations::KeyframeEffect::KeyFrameSet::ResolvedKeyFrame>::end() const |
512 | 0 | ConstIterator begin_from(K key) const { return ConstIterator(static_cast<Node*>(BaseTree::find(this->m_root, key))); } |
513 | | |
514 | | ConstIterator find_largest_not_above_iterator(K key) const |
515 | 40.5M | { |
516 | 40.5M | auto node = static_cast<Node*>(BaseTree::find_largest_not_above(this->m_root, key)); |
517 | 40.5M | if (!node) |
518 | 0 | return end(); |
519 | 40.5M | return ConstIterator(node, static_cast<Node*>(BaseTree::predecessor(node))); |
520 | 40.5M | } AK::RedBlackTree<unsigned long, unsigned long>::find_largest_not_above_iterator(unsigned long) const Line | Count | Source | 515 | 40.5M | { | 516 | 40.5M | auto node = static_cast<Node*>(BaseTree::find_largest_not_above(this->m_root, key)); | 517 | 40.5M | if (!node) | 518 | 0 | return end(); | 519 | 40.5M | return ConstIterator(node, static_cast<Node*>(BaseTree::predecessor(node))); | 520 | 40.5M | } |
Unexecuted instantiation: AK::RedBlackTree<unsigned int, AK::Optional<Line::Style::Mask> >::find_largest_not_above_iterator(unsigned int) const Unexecuted instantiation: AK::RedBlackTree<unsigned long, Web::Animations::KeyframeEffect::KeyFrameSet::ResolvedKeyFrame>::find_largest_not_above_iterator(unsigned long) const |
521 | | |
522 | | ConstIterator find_smallest_not_below_iterator(K key) const |
523 | 0 | { |
524 | 0 | auto node = static_cast<Node*>(BaseTree::find_smallest_not_below(this->m_root, key)); |
525 | 0 | if (!node) |
526 | 0 | return end(); |
527 | 0 | return ConstIterator(node, static_cast<Node*>(BaseTree::predecessor(node))); |
528 | 0 | } Unexecuted instantiation: AK::RedBlackTree<unsigned long, JS::Value>::find_smallest_not_below_iterator(unsigned long) const Unexecuted instantiation: AK::RedBlackTree<unsigned int, AK::Optional<Line::Style::Mask> >::find_smallest_not_below_iterator(unsigned int) const |
529 | | |
530 | | V unsafe_remove(K key) |
531 | | { |
532 | | auto* node = BaseTree::find(this->m_root, key); |
533 | | VERIFY(node); |
534 | | |
535 | | BaseTree::remove(node); |
536 | | |
537 | | V temp = move(static_cast<Node*>(node)->value); |
538 | | |
539 | | node->right_child = nullptr; |
540 | | node->left_child = nullptr; |
541 | | delete node; |
542 | | |
543 | | return temp; |
544 | | } |
545 | | |
546 | | bool remove(K key) |
547 | 0 | { |
548 | 0 | auto* node = BaseTree::find(this->m_root, key); |
549 | 0 | if (!node) |
550 | 0 | return false; |
551 | | |
552 | 0 | BaseTree::remove(node); |
553 | |
|
554 | 0 | node->right_child = nullptr; |
555 | 0 | node->left_child = nullptr; |
556 | 0 | delete node; |
557 | |
|
558 | 0 | return true; |
559 | 0 | } Unexecuted instantiation: AK::RedBlackTree<unsigned long, JS::Value>::remove(unsigned long) Unexecuted instantiation: AK::RedBlackTree<unsigned int, AK::Optional<Line::Style::Mask> >::remove(unsigned int) |
560 | | |
561 | | void clear() |
562 | 9.28M | { |
563 | 9.28M | delete this->m_root; |
564 | 9.28M | this->m_root = nullptr; |
565 | 9.28M | this->m_minimum = nullptr; |
566 | 9.28M | this->m_size = 0; |
567 | 9.28M | } AK::RedBlackTree<unsigned long, unsigned long>::clear() Line | Count | Source | 562 | 3.95M | { | 563 | 3.95M | delete this->m_root; | 564 | 3.95M | this->m_root = nullptr; | 565 | 3.95M | this->m_minimum = nullptr; | 566 | 3.95M | this->m_size = 0; | 567 | 3.95M | } |
Unexecuted instantiation: AK::RedBlackTree<unsigned long, JS::Value>::clear() AK::RedBlackTree<unsigned long, regex::CharRange>::clear() Line | Count | Source | 562 | 241k | { | 563 | 241k | delete this->m_root; | 564 | 241k | this->m_root = nullptr; | 565 | 241k | this->m_minimum = nullptr; | 566 | 241k | this->m_size = 0; | 567 | 241k | } |
AK::RedBlackTree<unsigned int, unsigned int>::clear() Line | Count | Source | 562 | 5.08M | { | 563 | 5.08M | delete this->m_root; | 564 | 5.08M | this->m_root = nullptr; | 565 | 5.08M | this->m_minimum = nullptr; | 566 | 5.08M | this->m_size = 0; | 567 | 5.08M | } |
Unexecuted instantiation: AK::RedBlackTree<unsigned int, AK::Optional<Line::Style::Mask> >::clear() Unexecuted instantiation: AK::RedBlackTree<unsigned long, Web::Animations::KeyframeEffect::KeyFrameSet::ResolvedKeyFrame>::clear() Unexecuted instantiation: AK::RedBlackTree<unsigned long, AK::DistinctNumeric<unsigned long, Wasm::__FunctionIndex_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool> >::clear() |
568 | | |
569 | | private: |
570 | | struct Node : BaseRedBlackTree<K>::Node { |
571 | | |
572 | | V value; |
573 | | |
574 | | Node(K key, V value) |
575 | 65.4M | : BaseRedBlackTree<K>::Node(key) |
576 | 40.6M | , value(move(value)) |
577 | 65.4M | { |
578 | 65.4M | } AK::RedBlackTree<unsigned long, unsigned long>::Node::Node(unsigned long, unsigned long) Line | Count | Source | 575 | 13.3M | : BaseRedBlackTree<K>::Node(key) | 576 | 13.3M | , value(move(value)) | 577 | 13.3M | { | 578 | 13.3M | } |
Unexecuted instantiation: AK::RedBlackTree<unsigned long, JS::Value>::Node::Node(unsigned long, JS::Value) AK::RedBlackTree<unsigned long, regex::CharRange>::Node::Node(unsigned long, regex::CharRange) Line | Count | Source | 575 | 40.6M | : BaseRedBlackTree<K>::Node(key) | 576 | 40.6M | , value(move(value)) | 577 | 40.6M | { | 578 | 40.6M | } |
AK::RedBlackTree<unsigned int, unsigned int>::Node::Node(unsigned int, unsigned int) Line | Count | Source | 575 | 11.4M | : BaseRedBlackTree<K>::Node(key) | 576 | 11.4M | , value(move(value)) | 577 | 11.4M | { | 578 | 11.4M | } |
Unexecuted instantiation: AK::RedBlackTree<unsigned int, AK::Optional<Line::Style::Mask> >::Node::Node(unsigned int, AK::Optional<Line::Style::Mask>) Unexecuted instantiation: AK::RedBlackTree<unsigned long, Web::Animations::KeyframeEffect::KeyFrameSet::ResolvedKeyFrame>::Node::Node(unsigned long, Web::Animations::KeyframeEffect::KeyFrameSet::ResolvedKeyFrame) Unexecuted instantiation: AK::RedBlackTree<unsigned long, AK::DistinctNumeric<unsigned long, Wasm::__FunctionIndex_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool> >::Node::Node(unsigned long, AK::DistinctNumeric<unsigned long, Wasm::__FunctionIndex_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool>) |
579 | | |
580 | | ~Node() |
581 | 65.4M | { |
582 | 65.4M | delete this->left_child; |
583 | 65.4M | delete this->right_child; |
584 | 65.4M | } AK::RedBlackTree<unsigned long, unsigned long>::Node::~Node() Line | Count | Source | 581 | 13.3M | { | 582 | 13.3M | delete this->left_child; | 583 | 13.3M | delete this->right_child; | 584 | 13.3M | } |
Unexecuted instantiation: AK::RedBlackTree<unsigned long, JS::Value>::Node::~Node() AK::RedBlackTree<unsigned long, regex::CharRange>::Node::~Node() Line | Count | Source | 581 | 40.6M | { | 582 | 40.6M | delete this->left_child; | 583 | 40.6M | delete this->right_child; | 584 | 40.6M | } |
AK::RedBlackTree<unsigned int, unsigned int>::Node::~Node() Line | Count | Source | 581 | 11.4M | { | 582 | 11.4M | delete this->left_child; | 583 | 11.4M | delete this->right_child; | 584 | 11.4M | } |
Unexecuted instantiation: AK::RedBlackTree<unsigned int, AK::Optional<Line::Style::Mask> >::Node::~Node() Unexecuted instantiation: AK::RedBlackTree<unsigned long, Web::Animations::KeyframeEffect::KeyFrameSet::ResolvedKeyFrame>::Node::~Node() Unexecuted instantiation: AK::RedBlackTree<unsigned long, AK::DistinctNumeric<unsigned long, Wasm::__FunctionIndex_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool> >::Node::~Node() |
585 | | }; |
586 | | }; |
587 | | |
588 | | } |
589 | | |
590 | | #if USING_AK_GLOBALLY |
591 | | using AK::RedBlackTree; |
592 | | #endif |