1e358b4fbSSasha Levin #include <kvm/rbtree-interval.h> 2e358b4fbSSasha Levin #include <stddef.h> 3495fbd4eSSasha Levin #include <errno.h> 4e358b4fbSSasha Levin 5e358b4fbSSasha Levin struct rb_int_node *rb_int_search_single(struct rb_root *root, u64 point) 6e358b4fbSSasha Levin { 7e358b4fbSSasha Levin struct rb_node *node = root->rb_node; 8e358b4fbSSasha Levin struct rb_node *lowest = NULL; 9e358b4fbSSasha Levin 10e358b4fbSSasha Levin while (node) { 11e358b4fbSSasha Levin struct rb_int_node *cur = rb_int(node); 12e358b4fbSSasha Levin 13e358b4fbSSasha Levin if (node->rb_left && (rb_int(node->rb_left)->max_high > point)) { 14e358b4fbSSasha Levin node = node->rb_left; 15e358b4fbSSasha Levin } else if (cur->low <= point && cur->high > point) { 16e358b4fbSSasha Levin lowest = node; 17e358b4fbSSasha Levin break; 18e358b4fbSSasha Levin } else if (point > cur->low) { 19e358b4fbSSasha Levin node = node->rb_right; 20e358b4fbSSasha Levin } else { 21e358b4fbSSasha Levin break; 22e358b4fbSSasha Levin } 23e358b4fbSSasha Levin } 24e358b4fbSSasha Levin 25e358b4fbSSasha Levin if (lowest == NULL) 26e358b4fbSSasha Levin return NULL; 27e358b4fbSSasha Levin 28e358b4fbSSasha Levin return rb_int(lowest); 29e358b4fbSSasha Levin } 30e358b4fbSSasha Levin 31e358b4fbSSasha Levin struct rb_int_node *rb_int_search_range(struct rb_root *root, u64 low, u64 high) 32e358b4fbSSasha Levin { 33e358b4fbSSasha Levin struct rb_int_node *range; 34e358b4fbSSasha Levin 35e358b4fbSSasha Levin range = rb_int_search_single(root, low); 36e358b4fbSSasha Levin if (range == NULL) 37e358b4fbSSasha Levin return NULL; 38e358b4fbSSasha Levin 39e358b4fbSSasha Levin /* We simply verify that 'high' is smaller than the end of the range where 'low' is located */ 40e358b4fbSSasha Levin if (range->high < high) 41e358b4fbSSasha Levin return NULL; 42e358b4fbSSasha Levin 43e358b4fbSSasha Levin return range; 44e358b4fbSSasha Levin } 45e358b4fbSSasha Levin 4686824900SIngo Molnar /* 4786824900SIngo Molnar * Update a node after it has been linked into the tree: 4886824900SIngo Molnar */ 4986824900SIngo Molnar static void propagate_callback(struct rb_node *node, struct rb_node *stop) 50e358b4fbSSasha Levin { 51*c59e43aaSKirill A. Shutemov struct rb_int_node *i_node; 52e358b4fbSSasha Levin 53*c59e43aaSKirill A. Shutemov if (node == stop) 54*c59e43aaSKirill A. Shutemov return; 55*c59e43aaSKirill A. Shutemov 56*c59e43aaSKirill A. Shutemov i_node = rb_int(node); 57e358b4fbSSasha Levin i_node->max_high = i_node->high; 58e358b4fbSSasha Levin 59e358b4fbSSasha Levin if (node->rb_left) 609f112becSSasha Levin i_node->max_high = max(i_node->max_high, rb_int(node->rb_left)->max_high); 61e358b4fbSSasha Levin if (node->rb_right) 629f112becSSasha Levin i_node->max_high = max(i_node->max_high, rb_int(node->rb_right)->max_high); 63e358b4fbSSasha Levin } 64e358b4fbSSasha Levin 6586824900SIngo Molnar /* 6686824900SIngo Molnar * Copy the extra data to a new node: 6786824900SIngo Molnar */ 6886824900SIngo Molnar static void copy_callback(struct rb_node *node_old, struct rb_node *node_new) 6986824900SIngo Molnar { 7086824900SIngo Molnar struct rb_int_node *i_node_old = rb_int(node_old); 7186824900SIngo Molnar struct rb_int_node *i_node_new = rb_int(node_new); 7286824900SIngo Molnar 7386824900SIngo Molnar i_node_new->low = i_node_old->low; 7486824900SIngo Molnar i_node_new->high = i_node_old->high; 7586824900SIngo Molnar 7686824900SIngo Molnar i_node_new->max_high = i_node_old->max_high; 7786824900SIngo Molnar } 7886824900SIngo Molnar 7986824900SIngo Molnar /* 8086824900SIngo Molnar * Update after tree rotation: 8186824900SIngo Molnar */ 8286824900SIngo Molnar static void rotate_callback(struct rb_node *node_old, struct rb_node *node_new) 8386824900SIngo Molnar { 8486824900SIngo Molnar propagate_callback(node_old, NULL); 8586824900SIngo Molnar propagate_callback(node_new, NULL); 8686824900SIngo Molnar } 8786824900SIngo Molnar 8886824900SIngo Molnar /* 8986824900SIngo Molnar * All augmented rbtree callbacks: 9086824900SIngo Molnar */ 9186824900SIngo Molnar struct rb_augment_callbacks callbacks = { 9286824900SIngo Molnar .propagate = propagate_callback, 9386824900SIngo Molnar .copy = copy_callback, 9486824900SIngo Molnar .rotate = rotate_callback, 9586824900SIngo Molnar }; 9686824900SIngo Molnar 97e358b4fbSSasha Levin int rb_int_insert(struct rb_root *root, struct rb_int_node *i_node) 98e358b4fbSSasha Levin { 9986824900SIngo Molnar struct rb_node **node = &root->rb_node, *parent = NULL; 100e358b4fbSSasha Levin 101e358b4fbSSasha Levin while (*node) { 102e358b4fbSSasha Levin int result = i_node->low - rb_int(*node)->low; 103e358b4fbSSasha Levin 104e358b4fbSSasha Levin parent = *node; 105e358b4fbSSasha Levin if (result < 0) 106e358b4fbSSasha Levin node = &((*node)->rb_left); 107e358b4fbSSasha Levin else if (result > 0) 108e358b4fbSSasha Levin node = &((*node)->rb_right); 109e358b4fbSSasha Levin else 110495fbd4eSSasha Levin return -EEXIST; 111e358b4fbSSasha Levin } 112e358b4fbSSasha Levin 113e358b4fbSSasha Levin rb_link_node(&i_node->node, parent, node); 11486824900SIngo Molnar rb_insert_augmented(&i_node->node, root, &callbacks); 115e358b4fbSSasha Levin 116495fbd4eSSasha Levin return 0; 117e358b4fbSSasha Levin } 118e358b4fbSSasha Levin 119e358b4fbSSasha Levin void rb_int_erase(struct rb_root *root, struct rb_int_node *node) 120e358b4fbSSasha Levin { 12186824900SIngo Molnar rb_erase_augmented(&node->node, root, &callbacks); 122e358b4fbSSasha Levin } 123