/** * Split a range into two halves by deleting a middle portion * @param r the range to split-delete * @param q the range to delete from r * @return NULL if it aligned at either end else the second half */ range *range_split_delete( range *r, range *q ) { if ( q->start == r->start ) { r->len -= q->len; r->start += q->len; return NULL; } else if ( range_end(q) == range_end(r) ) { r->len -= q->len; return NULL; } else { range *q2 = range_create( r->name, r->html_name, r->start, r->len ); if ( q2 != NULL ) { q2->start = range_end(q); q2->len = range_end(r) - q->start; r->len = q->start-r->start; } return q2; } }
static int tree_insert(struct rb_root *root, struct extent_map *em) { struct rb_node **p = &root->rb_node; struct rb_node *parent = NULL; struct extent_map *entry = NULL; struct rb_node *orig_parent = NULL; u64 end = range_end(em->start, em->len); while (*p) { parent = *p; entry = rb_entry(parent, struct extent_map, rb_node); WARN_ON(!entry->in_tree); if (em->start < entry->start) p = &(*p)->rb_left; else if (em->start >= extent_map_end(entry)) p = &(*p)->rb_right; else return -EEXIST; } orig_parent = parent; while (parent && em->start >= extent_map_end(entry)) { parent = rb_next(parent); entry = rb_entry(parent, struct extent_map, rb_node); } if (parent) if (end > entry->start && em->start < extent_map_end(entry)) return -EEXIST; parent = orig_parent; entry = rb_entry(parent, struct extent_map, rb_node); while (parent && em->start < entry->start) { parent = rb_prev(parent); entry = rb_entry(parent, struct extent_map, rb_node); } if (parent) if (end > entry->start && em->start < extent_map_end(entry)) return -EEXIST; em->in_tree = 1; rb_link_node(&em->rb_node, orig_parent, p); rb_insert_color(&em->rb_node, root); return 0; }
rint size() const { return range_end() - range_begin(); }
/** * Does a range overlap this range on the right? * @param q the range that might overlap on the right * @param r the range to compare it to * @return 1 if it is true */ int range_overlaps_right( range *q, range *r ) { return range_end(r)>q->start && range_end(r)<range_end(q); }
/** * Does a range overlap this range on the left? * @param q the range that might overlap on the left * @param r the range to compare it to * @return 1 if it is true */ int range_overlaps_left( range *q, range *r ) { return range_end(q)>r->start && range_end(q)<range_end(r); }
/** * Is a range inside another. Inside can be equal * @param r1 the first range (is it inside r2?) * @param r2 the second range being the outside one * @return 1 if r1 is inside r2, else 0 */ int range_inside( range *r1, range *r2 ) { return range_start(r1)>=range_start(r2)&&range_end(r1)<=range_end(r2); }