diff options
Diffstat (limited to 'lib/prio_tree.c')
-rw-r--r-- | lib/prio_tree.c | 78 |
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 | ||
307 | static 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 | |||
327 | static 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, | |||
388 | static struct prio_tree_node *prio_tree_parent(struct prio_tree_iter *iter) | 393 | static 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 | ||