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