1e358b4fbSSasha Levin #include <kvm/rbtree-interval.h> 2e358b4fbSSasha Levin #include <stddef.h> 3e358b4fbSSasha Levin 4e358b4fbSSasha Levin #define rb_int(n) rb_entry(n, struct rb_int_node, node) 5e358b4fbSSasha Levin 6e358b4fbSSasha Levin struct rb_int_node *rb_int_search_single(struct rb_root *root, u64 point) 7e358b4fbSSasha Levin { 8e358b4fbSSasha Levin struct rb_node *node = root->rb_node; 9e358b4fbSSasha Levin struct rb_node *lowest = NULL; 10e358b4fbSSasha Levin 11e358b4fbSSasha Levin while (node) { 12e358b4fbSSasha Levin struct rb_int_node *cur = rb_int(node); 13e358b4fbSSasha Levin 14e358b4fbSSasha Levin if (node->rb_left && (rb_int(node->rb_left)->max_high > point)) { 15e358b4fbSSasha Levin node = node->rb_left; 16e358b4fbSSasha Levin } else if (cur->low <= point && cur->high > point) { 17e358b4fbSSasha Levin lowest = node; 18e358b4fbSSasha Levin break; 19e358b4fbSSasha Levin } else if (point > cur->low) { 20e358b4fbSSasha Levin node = node->rb_right; 21e358b4fbSSasha Levin } else { 22e358b4fbSSasha Levin break; 23e358b4fbSSasha Levin } 24e358b4fbSSasha Levin } 25e358b4fbSSasha Levin 26e358b4fbSSasha Levin if (lowest == NULL) 27e358b4fbSSasha Levin return NULL; 28e358b4fbSSasha Levin 29e358b4fbSSasha Levin return rb_int(lowest); 30e358b4fbSSasha Levin } 31e358b4fbSSasha Levin 32e358b4fbSSasha Levin struct rb_int_node *rb_int_search_range(struct rb_root *root, u64 low, u64 high) 33e358b4fbSSasha Levin { 34e358b4fbSSasha Levin struct rb_int_node *range; 35e358b4fbSSasha Levin 36e358b4fbSSasha Levin range = rb_int_search_single(root, low); 37e358b4fbSSasha Levin if (range == NULL) 38e358b4fbSSasha Levin return NULL; 39e358b4fbSSasha Levin 40e358b4fbSSasha Levin /* We simply verify that 'high' is smaller than the end of the range where 'low' is located */ 41e358b4fbSSasha Levin if (range->high < high) 42e358b4fbSSasha Levin return NULL; 43e358b4fbSSasha Levin 44e358b4fbSSasha Levin return range; 45e358b4fbSSasha Levin } 46e358b4fbSSasha Levin 47e358b4fbSSasha Levin static void update_node_max_high(struct rb_node *node, void *arg) 48e358b4fbSSasha Levin { 49e358b4fbSSasha Levin struct rb_int_node *i_node = rb_int(node); 50e358b4fbSSasha Levin 51e358b4fbSSasha Levin i_node->max_high = i_node->high; 52e358b4fbSSasha Levin 53e358b4fbSSasha Levin if (node->rb_left) 54*9f112becSSasha Levin i_node->max_high = max(i_node->max_high, rb_int(node->rb_left)->max_high); 55e358b4fbSSasha Levin if (node->rb_right) 56*9f112becSSasha Levin i_node->max_high = max(i_node->max_high, rb_int(node->rb_right)->max_high); 57e358b4fbSSasha Levin } 58e358b4fbSSasha Levin 59e358b4fbSSasha Levin int rb_int_insert(struct rb_root *root, struct rb_int_node *i_node) 60e358b4fbSSasha Levin { 61e358b4fbSSasha Levin struct rb_node **node = &(root->rb_node), *parent = NULL; 62e358b4fbSSasha Levin 63e358b4fbSSasha Levin while (*node) { 64e358b4fbSSasha Levin int result = i_node->low - rb_int(*node)->low; 65e358b4fbSSasha Levin 66e358b4fbSSasha Levin parent = *node; 67e358b4fbSSasha Levin if (result < 0) 68e358b4fbSSasha Levin node = &((*node)->rb_left); 69e358b4fbSSasha Levin else if (result > 0) 70e358b4fbSSasha Levin node = &((*node)->rb_right); 71e358b4fbSSasha Levin else 72e358b4fbSSasha Levin return 0; 73e358b4fbSSasha Levin } 74e358b4fbSSasha Levin 75e358b4fbSSasha Levin rb_link_node(&i_node->node, parent, node); 76e358b4fbSSasha Levin rb_insert_color(&i_node->node, root); 77e358b4fbSSasha Levin 78*9f112becSSasha Levin rb_augment_insert(&i_node->node, update_node_max_high, NULL); 79e358b4fbSSasha Levin return 1; 80e358b4fbSSasha Levin } 81e358b4fbSSasha Levin 82e358b4fbSSasha Levin void rb_int_erase(struct rb_root *root, struct rb_int_node *node) 83e358b4fbSSasha Levin { 84e358b4fbSSasha Levin struct rb_node *deepest; 85e358b4fbSSasha Levin 86e358b4fbSSasha Levin deepest = rb_augment_erase_begin(&node->node); 87e358b4fbSSasha Levin rb_erase(&node->node, root); 88e358b4fbSSasha Levin rb_augment_erase_end(deepest, update_node_max_high, NULL); 89e358b4fbSSasha Levin 90e358b4fbSSasha Levin } 91