aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/prio_tree.c78
1 files changed, 37 insertions, 41 deletions
diff --git a/lib/prio_tree.c b/lib/prio_tree.c
index 423eba80478b..888e8b3a97ea 100644
--- a/lib/prio_tree.c
+++ b/lib/prio_tree.c
@@ -304,6 +304,40 @@ void prio_tree_remove(struct prio_tree_root *root, struct prio_tree_node *node)
304 cur = prio_tree_replace(root, cur->parent, cur); 304 cur = prio_tree_replace(root, cur->parent, cur);
305} 305}
306 306
307static void iter_walk_down(struct prio_tree_iter *iter)
308{
309 iter->mask >>= 1;
310 if (iter->mask) {
311 if (iter->size_level)
312 iter->size_level++;
313 return;
314 }
315
316 if (iter->size_level) {
317 BUG_ON(!prio_tree_left_empty(iter->cur));
318 BUG_ON(!prio_tree_right_empty(iter->cur));
319 iter->size_level++;
320 iter->mask = ULONG_MAX;
321 } else {
322 iter->size_level = 1;
323 iter->mask = 1UL << (BITS_PER_LONG - 1);
324 }
325}
326
327static void iter_walk_up(struct prio_tree_iter *iter)
328{
329 if (iter->mask == ULONG_MAX)
330 iter->mask = 1UL;
331 else if (iter->size_level == 1)
332 iter->mask = 1UL;
333 else
334 iter->mask <<= 1;
335 if (iter->size_level)
336 iter->size_level--;
337 if (!iter->size_level && (iter->value & iter->mask))
338 iter->value ^= iter->mask;
339}
340
307/* 341/*
308 * Following functions help to enumerate all prio_tree_nodes in the tree that 342 * Following functions help to enumerate all prio_tree_nodes in the tree that
309 * overlap with the input interval X [radix_index, heap_index]. The enumeration 343 * overlap with the input interval X [radix_index, heap_index]. The enumeration
@@ -322,21 +356,7 @@ static struct prio_tree_node *prio_tree_left(struct prio_tree_iter *iter,
322 356
323 if (iter->r_index <= *h_index) { 357 if (iter->r_index <= *h_index) {
324 iter->cur = iter->cur->left; 358 iter->cur = iter->cur->left;
325 iter->mask >>= 1; 359 iter_walk_down(iter);
326 if (iter->mask) {
327 if (iter->size_level)
328 iter->size_level++;
329 } else {
330 if (iter->size_level) {
331 BUG_ON(!prio_tree_left_empty(iter->cur));
332 BUG_ON(!prio_tree_right_empty(iter->cur));
333 iter->size_level++;
334 iter->mask = ULONG_MAX;
335 } else {
336 iter->size_level = 1;
337 iter->mask = 1UL << (BITS_PER_LONG - 1);
338 }
339 }
340 return iter->cur; 360 return iter->cur;
341 } 361 }
342 362
@@ -363,22 +383,7 @@ static struct prio_tree_node *prio_tree_right(struct prio_tree_iter *iter,
363 383
364 if (iter->r_index <= *h_index) { 384 if (iter->r_index <= *h_index) {
365 iter->cur = iter->cur->right; 385 iter->cur = iter->cur->right;
366 iter->mask >>= 1; 386 iter_walk_down(iter);
367 iter->value = value;
368 if (iter->mask) {
369 if (iter->size_level)
370 iter->size_level++;
371 } else {
372 if (iter->size_level) {
373 BUG_ON(!prio_tree_left_empty(iter->cur));
374 BUG_ON(!prio_tree_right_empty(iter->cur));
375 iter->size_level++;
376 iter->mask = ULONG_MAX;
377 } else {
378 iter->size_level = 1;
379 iter->mask = 1UL << (BITS_PER_LONG - 1);
380 }
381 }
382 return iter->cur; 387 return iter->cur;
383 } 388 }
384 389
@@ -388,16 +393,7 @@ static struct prio_tree_node *prio_tree_right(struct prio_tree_iter *iter,
388static struct prio_tree_node *prio_tree_parent(struct prio_tree_iter *iter) 393static struct prio_tree_node *prio_tree_parent(struct prio_tree_iter *iter)
389{ 394{
390 iter->cur = iter->cur->parent; 395 iter->cur = iter->cur->parent;
391 if (iter->mask == ULONG_MAX) 396 iter_walk_up(iter);
392 iter->mask = 1UL;
393 else if (iter->size_level == 1)
394 iter->mask = 1UL;
395 else
396 iter->mask <<= 1;
397 if (iter->size_level)
398 iter->size_level--;
399 if (!iter->size_level && (iter->value & iter->mask))
400 iter->value ^= iter->mask;
401 return iter->cur; 397 return iter->cur;
402} 398}
403 399