aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/prio_tree.c47
1 files changed, 22 insertions, 25 deletions
diff --git a/lib/prio_tree.c b/lib/prio_tree.c
index 928482bb8385..8d443af03b4c 100644
--- a/lib/prio_tree.c
+++ b/lib/prio_tree.c
@@ -85,6 +85,17 @@ static inline unsigned long prio_tree_maxindex(unsigned int bits)
85 return index_bits_to_maxindex[bits - 1]; 85 return index_bits_to_maxindex[bits - 1];
86} 86}
87 87
88static void prio_set_parent(struct prio_tree_node *parent,
89 struct prio_tree_node *child, bool left)
90{
91 if (left)
92 parent->left = child;
93 else
94 parent->right = child;
95
96 child->parent = parent;
97}
98
88/* 99/*
89 * Extend a priority search tree so that it can store a node with heap_index 100 * Extend a priority search tree so that it can store a node with heap_index
90 * max_heap_index. In the worst case, this algorithm takes O((log n)^2). 101 * max_heap_index. In the worst case, this algorithm takes O((log n)^2).
@@ -113,15 +124,12 @@ static struct prio_tree_node *prio_tree_expand(struct prio_tree_root *root,
113 prio_tree_remove(root, root->prio_tree_node); 124 prio_tree_remove(root, root->prio_tree_node);
114 INIT_PRIO_TREE_NODE(tmp); 125 INIT_PRIO_TREE_NODE(tmp);
115 126
116 prev->left = tmp; 127 prio_set_parent(prev, tmp, true);
117 tmp->parent = prev;
118 prev = tmp; 128 prev = tmp;
119 } 129 }
120 130
121 if (!prio_tree_empty(root)) { 131 if (!prio_tree_empty(root))
122 prev->left = root->prio_tree_node; 132 prio_set_parent(prev, root->prio_tree_node, true);
123 prev->left->parent = prev;
124 }
125 133
126 root->prio_tree_node = node; 134 root->prio_tree_node = node;
127 return node; 135 return node;
@@ -142,23 +150,14 @@ struct prio_tree_node *prio_tree_replace(struct prio_tree_root *root,
142 * and does not help much to improve performance (IMO). 150 * and does not help much to improve performance (IMO).
143 */ 151 */
144 root->prio_tree_node = node; 152 root->prio_tree_node = node;
145 } else { 153 } else
146 node->parent = old->parent; 154 prio_set_parent(old->parent, node, old->parent->left == old);
147 if (old->parent->left == old)
148 old->parent->left = node;
149 else
150 old->parent->right = node;
151 }
152 155
153 if (!prio_tree_left_empty(old)) { 156 if (!prio_tree_left_empty(old))
154 node->left = old->left; 157 prio_set_parent(node, old->left, true);
155 old->left->parent = node;
156 }
157 158
158 if (!prio_tree_right_empty(old)) { 159 if (!prio_tree_right_empty(old))
159 node->right = old->right; 160 prio_set_parent(node, old->right, false);
160 old->right->parent = node;
161 }
162 161
163 return old; 162 return old;
164} 163}
@@ -218,16 +217,14 @@ struct prio_tree_node *prio_tree_insert(struct prio_tree_root *root,
218 if (index & mask) { 217 if (index & mask) {
219 if (prio_tree_right_empty(cur)) { 218 if (prio_tree_right_empty(cur)) {
220 INIT_PRIO_TREE_NODE(node); 219 INIT_PRIO_TREE_NODE(node);
221 cur->right = node; 220 prio_set_parent(cur, node, false);
222 node->parent = cur;
223 return res; 221 return res;
224 } else 222 } else
225 cur = cur->right; 223 cur = cur->right;
226 } else { 224 } else {
227 if (prio_tree_left_empty(cur)) { 225 if (prio_tree_left_empty(cur)) {
228 INIT_PRIO_TREE_NODE(node); 226 INIT_PRIO_TREE_NODE(node);
229 cur->left = node; 227 prio_set_parent(cur, node, true);
230 node->parent = cur;
231 return res; 228 return res;
232 } else 229 } else
233 cur = cur->left; 230 cur = cur->left;