blob: 47dbadd139d0d9637ae4d0f57ff6527c69ea0a2f [file] [log] [blame]
// Copyright 2025 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use arrayvec::ArrayVec;
use std::borrow::Borrow;
use std::cmp::{Eq, PartialEq};
use std::fmt;
use std::fmt::{Debug, Formatter};
use std::ops::{Bound, Range, RangeBounds};
use std::sync::Arc;
/// The `B` constant for the btree.
///
/// Controls the size of the nodes inside the tree.
const B: usize = 6;
/// The capacity of nodes in the btree.
const NODE_CAPACITY: usize = 2 * B;
/// A location inside the btree.
#[derive(Debug, Default, Clone, Copy)]
struct Cursor {
/// The number of valid indices in the `indices` array.
depth: u8,
/// The indices of the entry, ordered from leaf to root.
indices: [u8; 7],
}
impl Cursor {
/// Create a cursor with a single index.
fn with_index(index: usize) -> Self {
let mut cursor = Self::default();
cursor.push(index);
cursor
}
/// Whether the cursor is empty.
///
/// A cursor is empty if it contains no more indices. This happens when a traversal has reached
/// a leaf node.
fn is_empty(&self) -> bool {
self.depth == 0
}
/// Push an index onto the front of the cursor.
///
/// The front of the cursor is towards the root of the tree.
fn push(&mut self, index: usize) {
self.indices[self.depth as usize] = index as u8;
self.depth += 1;
}
/// Push an index onto the back of the cursor.
///
/// The back of the cursor is towards the leaves of the tree.
fn push_back(&mut self, index: usize) {
self.indices.rotate_right(1);
self.indices[0] = index as u8;
self.depth += 1;
}
/// Pop an index off the front of the cursor.
///
/// The front of the cursor is towards the root of the tree.
fn pop(&mut self) -> Option<usize> {
if self.depth == 0 {
None
} else {
self.depth -= 1;
Some(self.indices[self.depth as usize] as usize)
}
}
/// Pop an index off the back of the cursor.
///
/// The back of the cursor is towards the leaves of the tree.
fn pop_back(&mut self) -> Option<usize> {
if self.depth == 0 {
None
} else {
self.depth -= 1;
let index = self.indices[0] as usize;
self.indices.rotate_left(1);
Some(index)
}
}
/// The backmost index in the cursor.
///
/// The back of the cursor is towards the leaves of the tree.
///
/// Assumes the cursor is non-empty.
fn back(&self) -> usize {
self.indices[0] as usize
}
/// Increment the backmost index in the cursor.
///
/// The back of the cursor is towards the leaves of the tree.
///
/// Assumes the cursor is non-empty.
fn increment_back(&mut self) {
self.indices[0] += 1;
}
/// Decrement the backmost index in the cursor.
///
/// The back of the cursor is towards the leaves of the tree.
///
/// Assumes the cursor is non-empty.
fn decrement_back(&mut self) {
self.indices[0] -= 1;
}
}
impl PartialEq for Cursor {
fn eq(&self, other: &Self) -> bool {
if self.depth != other.depth {
return false;
}
for i in 0..self.depth {
if self.indices[i as usize] != other.indices[i as usize] {
return false;
}
}
true
}
}
impl Eq for Cursor {}
/// Where to place the cursor relative to the given key.
enum CursorPosition {
/// The given key represents a left edge of a range.
///
/// Place the cursor to the left of a range containing the cursor.
Left,
/// The given key represents a right edge of a range.
///
/// Place the cursor to the right of a range containing the cursor.
Right,
}
/// Search of the given key in the given array of ranges.
///
/// If the array contains a range that contains the key, returns the index of that range.
/// Otherwise, returns the index at which the given key could be inserted into the array to
/// maintain the ordering.
fn binary_search<K: Ord>(key: &K, keys: &ArrayVec<Range<K>, NODE_CAPACITY>) -> usize {
let mut left = 0usize;
let mut right = keys.len();
while left < right {
let mid = left + (right - left) / 2;
// TODO: Consider `get_unchecked`.
let range = &keys[mid];
if key < &range.start {
// This range is too large.
right = mid;
} else if key < &range.end {
// We found the range that contains this key.
return mid;
} else {
// The key might be found in the next range.
left = mid + 1;
}
}
// The key falls between two ranges. Return the index at which this key could be inserted to
// maintain the ordering.
left
}
/// A leaf node in the btree.
///
/// Stores a flat map of keys to values, with the `i`th entry in the keys array corresponding to
/// the `i`th entry in the values array. The balancing rules of the btree ensure that every
/// non-root leaf has between N and N/2 entries populated.
#[derive(Clone)]
struct NodeLeaf<K: Ord + Copy, V: Clone> {
/// The keys stored in this leaf node.
///
/// We store the key in a dense array to improve cache performance during lookups. We often
/// need to binary-search the keys in a given leaf node, which means having those keys close
/// together improves cache performance.
keys: ArrayVec<Range<K>, NODE_CAPACITY>,
/// The value stored in this leaf node.
values: ArrayVec<V, NODE_CAPACITY>,
}
/// Shows the map structure of the leaf node.
impl<K, V> Debug for NodeLeaf<K, V>
where
K: Debug + Ord + Copy,
V: Debug + Clone,
{
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.debug_map().entries(self.keys.iter().zip(self.values.iter())).finish()
}
}
/// The result of performing an insertion into a btree node.
enum InsertResult<K: Ord + Copy, V: Clone> {
/// The value was successfully inserted into an empty slot.
Inserted,
/// The value was inserted into an empty slot in a leaf node but that insertion caused the
/// leaf node to exceed its capacity and split into two leaf nodes. The existing leaf node
/// now holds the entries to the left of the split and the entries to the right of the split
/// are returned. The split occurred at the returned key.
SplitLeaf(K, Arc<NodeLeaf<K, V>>),
/// The value was inserted into an empty slot in a subtree but that insertion caused the
/// internal node to exceed its capacity and split into two internal nodes. The internal node
/// now holds the entries to the left of the split and the entries to the right of the split
/// are returned. The split occurred at the returned key.
SplitInternal(K, Arc<NodeInternal<K, V>>),
}
/// The intermediate result of a remove operation.
///
/// The root of the CowTree converts this result value into `Option<T>`, per the usual map
/// interface.
enum RemoveResult<V: Clone> {
/// The key the client asked to remove was not found in the map.
NotFound,
/// The key was successfully removed from the map.
///
/// Returns the value previously stored at this key. No further processing is required.
Removed(V),
/// The key was removed from the map but the node that previously contained that node no longer
/// has sufficient children.
///
/// Returns the value previousoly stored at this key.
///
/// The caller is responsible for rebalancing its children to ensure that each node has at
/// least this minimum number of children. If the balance invariant can be resolved locally,
/// the caller should return `Removed` to its caller. If rebalancing the local children
/// causes this node to have fewer than the minimum number of children, the caller should
/// return `Underflow` to its caller.
Underflow(V),
}
impl<K, V> NodeLeaf<K, V>
where
K: Ord + Copy,
V: Clone,
{
/// Create an empty leaf node.
///
/// Empty leaf nodes are used only at the root of the tree.
fn empty() -> Self {
Self { keys: ArrayVec::new(), values: ArrayVec::new() }
}
/// Gets the index in this leaf that corresponds to the given cursor.
///
/// Assumes the cursor contains exactly one index.
///
/// Returns `None` if the cursor points beyond the end if this node.
fn get_index(&self, mut cursor: Cursor) -> Option<usize> {
let index = cursor.pop().expect("Cursor has sufficient depth");
assert!(cursor.is_empty(), "Cursor has excess depth");
if index >= self.keys.len() {
return None;
}
Some(index)
}
/// Search this leaf for the given key and return both the key and the value found.
fn get_key_value(&self, cursor: Cursor) -> Option<(&Range<K>, &V)> {
if let Some(index) = self.get_index(cursor) {
let key = &self.keys[index];
let value = &self.values[index];
Some((key, value))
} else {
None
}
}
/// The last key/value pair stored in this leaf.
fn last_key_value(&self) -> Option<(&Range<K>, &V)> {
let key = self.keys.last()?;
let value = self.values.last()?;
Some((key, value))
}
/// Find the given key in this node.
///
/// Updates `cursor` to point to the position indicated by `position`.
fn find(&self, key: &K, position: CursorPosition, cursor: &mut Cursor) {
let index = binary_search(key, &self.keys);
match position {
CursorPosition::Left => {
cursor.push(index);
}
CursorPosition::Right => {
if let Some(range) = self.keys.get(index) {
if *key > range.start {
cursor.push(index + 1);
return;
}
}
cursor.push(index);
}
}
}
/// Insert the given entry at the location indicated by `cursor`.
///
/// Inserting a value into a leaf node might cause this node to split into two leaf nodes.
fn insert(&mut self, mut cursor: Cursor, range: Range<K>, value: V) -> InsertResult<K, V> {
let index = cursor.pop().expect("valid cursor");
if self.keys.len() == NODE_CAPACITY {
if index == NODE_CAPACITY {
let mut keys = ArrayVec::new();
let mut values = ArrayVec::new();
let key = range.start;
keys.push(range);
values.push(value);
return InsertResult::SplitLeaf(key, Arc::new(Self { keys, values }));
}
let middle = NODE_CAPACITY / 2;
assert!(middle > 0);
let mut right = Self {
keys: self.keys.drain(middle..).collect(),
values: self.values.drain(middle..).collect(),
};
if index <= middle {
self.keys.insert(index, range);
self.values.insert(index, value);
} else {
right.keys.insert(index - middle, range);
right.values.insert(index - middle, value);
}
InsertResult::SplitLeaf(right.keys[0].start, Arc::new(right))
} else {
self.keys.insert(index, range);
self.values.insert(index, value);
InsertResult::Inserted
}
}
/// Remove the entry indicated by `cursor`.
fn remove(&mut self, cursor: Cursor) -> RemoveResult<V> {
if let Some(index) = self.get_index(cursor) {
self.keys.remove(index);
let value = self.values.remove(index);
if self.keys.len() < NODE_CAPACITY / 2 {
RemoveResult::Underflow(value)
} else {
RemoveResult::Removed(value)
}
} else {
RemoveResult::NotFound
}
}
}
/// The children of an internal node in the btree.
#[derive(Clone, Debug)]
enum ChildList<K: Ord + Copy, V: Clone> {
/// Used when an internal node has leaf nodes as children.
Leaf(ArrayVec<Arc<NodeLeaf<K, V>>, NODE_CAPACITY>),
/// Used when an internal node has other internal nodes as children.
Internal(ArrayVec<Arc<NodeInternal<K, V>>, NODE_CAPACITY>),
}
impl<K, V> ChildList<K, V>
where
K: Ord + Copy,
V: Clone,
{
/// Create a child list that has no children.
fn new_empty(&self) -> Self {
match self {
ChildList::Leaf(_) => ChildList::Leaf(ArrayVec::new()),
ChildList::Internal(_) => ChildList::Internal(ArrayVec::new()),
}
}
/// The number of children for this node.
fn len(&self) -> usize {
match self {
ChildList::Leaf(children) => children.len(),
ChildList::Internal(children) => children.len(),
}
}
/// The number of gradchildren located at the child with the given index.
fn size_at(&self, i: usize) -> usize {
match self {
ChildList::Leaf(children) => children[i].keys.len(),
ChildList::Internal(children) => children[i].children.len(),
}
}
/// Obtain the child located at the given index.
fn get(&self, i: usize) -> Node<K, V> {
match self {
ChildList::Leaf(children) => Node::Leaf(children[i].clone()),
ChildList::Internal(children) => Node::Internal(children[i].clone()),
}
}
/// Get a reference to the child located at the given index.
fn get_ref(&self, i: usize) -> NodeRef<'_, K, V> {
match self {
ChildList::Leaf(children) => NodeRef::Leaf(&children[i]),
ChildList::Internal(children) => NodeRef::Internal(&children[i]),
}
}
/// Removes all the entries starting at the given index from the child list.
///
/// The removed entries are returned in a new child list.
fn split_off(&mut self, index: usize) -> Self {
match self {
ChildList::Leaf(children) => ChildList::Leaf(children.drain(index..).collect()),
ChildList::Internal(children) => ChildList::Internal(children.drain(index..).collect()),
}
}
/// Removes all the entries prior to the given index from the child list.
///
/// The removed entries are returned in a new child list.
fn split_off_front(&mut self, index: usize) -> Self {
match self {
ChildList::Leaf(children) => ChildList::Leaf(children.drain(..index).collect()),
ChildList::Internal(children) => ChildList::Internal(children.drain(..index).collect()),
}
}
/// Insert a child into the child list.
///
/// The type of child node must match the type of the child list.
fn insert(&mut self, index: usize, child: Node<K, V>) {
match self {
ChildList::Leaf(children) => {
let Node::Leaf(leaf) = child else {
unreachable!("Inserting a non-leaf into an internal node for leaf nodes.");
};
children.insert(index, leaf);
}
ChildList::Internal(children) => {
let Node::Internal(internal) = child else {
unreachable!(
"Inserting a non-internal into an internal node for internal nodes."
);
};
children.insert(index, internal);
}
}
}
/// Remove the child at the given index from the child list.
fn remove(&mut self, index: usize) {
match self {
ChildList::Leaf(children) => {
children.remove(index);
}
ChildList::Internal(children) => {
children.remove(index);
}
}
}
/// Add the children from the given `ChildList` to this child list.
fn extend(&mut self, other: &Self) {
match (self, other) {
(ChildList::Leaf(self_children), ChildList::Leaf(other_children)) => {
self_children.extend(other_children.iter().cloned());
}
(ChildList::Internal(self_children), ChildList::Internal(other_children)) => {
self_children.extend(other_children.iter().cloned());
}
_ => unreachable!("Type mismatch while extending a child list."),
}
}
}
/// An internal node in the btree.
#[derive(Clone, Debug)]
struct NodeInternal<K: Ord + Copy, V: Clone> {
/// A cache of the keys that partition the keys in the children.
/// The key at index `i` is the smallest key stored in the subtree
/// of the `i`+1 child.
///
/// We only ever store CAPACITY - 1 keys in this array.
keys: ArrayVec<K, NODE_CAPACITY>,
/// The children of this node.
children: ChildList<K, V>,
}
/// Get mutable references to two entries in a slice.
///
/// When rebalancing nodes, we need to mutate two nodes at the same time. Normally, if you take a
/// mutable reference to one element of an array, the borrow checker prevents you from taking a
/// mutable reference to a second element of the same array.
///
/// The nightly version of `std::primitive::slice` has `get_many_mut` to let you get mutable
/// references to multiple elements. However, without that interface, the recommended approach for
/// avoiding `unsafe` is to use `split_at_mut`.
fn get_two_mut<T>(slice: &mut [T], i: usize, j: usize) -> (&mut T, &mut T) {
if i < j {
let (a, b) = slice.split_at_mut(j);
(&mut a[i], &mut b[0])
} else {
let (a, b) = slice.split_at_mut(i);
(&mut b[0], &mut a[j])
}
}
impl<K, V> NodeInternal<K, V>
where
K: Ord + Copy,
V: Clone,
{
/// The index of the child that might contain the given key.
///
/// Searches the cached keys at this node to determine which child node might contain the given
/// key.
fn get_child_index(&self, key: &K) -> usize {
let p = self.keys.partition_point(|k| k < key);
if self.keys.get(p) == Some(key) {
// If the query key exactly matches the split key, then we need to look for this key to
// the right of the split.
p + 1
} else {
// Otherwise, we look to the left of the split.
p
}
}
/// Search this subtree for the given key and return both the key and the value found.
fn get_key_value(&self, mut cursor: Cursor) -> Option<(&Range<K>, &V)> {
let index = cursor.pop().expect("valid cursor");
match &self.children {
ChildList::Leaf(children) => children[index].get_key_value(cursor),
ChildList::Internal(children) => children[index].get_key_value(cursor),
}
}
/// Returns a reference to the node that contains the entry indicated by the cursor.
///
/// Assumes the cursor points a descendant of this node.
fn get_containing_node(&self, mut cursor: Cursor) -> NodeRef<'_, K, V> {
debug_assert!(cursor.depth >= 2);
let index = cursor.pop().expect("valid cursor");
if cursor.depth == 1 {
return self.children.get_ref(index);
}
match &self.children {
ChildList::Leaf(_) => unreachable!("leaf nodes do not have children"),
ChildList::Internal(children) => children[index].get_containing_node(cursor),
}
}
/// The last key/value pair stored in this subtree.
fn last_key_value(&self) -> Option<(&Range<K>, &V)> {
match &self.children {
ChildList::Leaf(children) => {
children.last().expect("child lists are always non-empty").last_key_value()
}
ChildList::Internal(children) => {
children.last().expect("child lists are always non-empty").last_key_value()
}
}
}
/// Find the given key in this node.
///
/// Updates `cursor` to point to the position indicated by `position`.
fn find(&self, key: &K, position: CursorPosition, cursor: &mut Cursor) {
let index = self.get_child_index(&key);
match &self.children {
ChildList::Leaf(children) => children[index].find(key, position, cursor),
ChildList::Internal(children) => children[index].find(key, position, cursor),
}
cursor.push(index);
}
/// Insert the given child node at `index` in this node.
///
/// `key` must be the smallest key that occurs in the `child` subtree.
///
/// The caller must ensure that the child is inserted in the correct location.
fn insert_child(&mut self, index: usize, key: K, child: Node<K, V>) -> InsertResult<K, V> {
let n = self.children.len();
if n == NODE_CAPACITY {
if index == NODE_CAPACITY {
let mut children = self.children.new_empty();
children.insert(0, child);
let right = Self { keys: ArrayVec::new(), children };
return InsertResult::SplitInternal(key, Arc::new(right));
}
let middle = NODE_CAPACITY / 2;
assert!(middle > 0);
let mut internal = Self {
keys: self.keys.drain(middle..).collect(),
children: self.children.split_off(middle),
};
let split_key = self.keys.pop().unwrap();
if index < middle {
self.keys.insert(index, key);
self.children.insert(index + 1, child);
} else {
internal.keys.insert(index - middle, key);
internal.children.insert(index - middle + 1, child);
}
debug_assert!(self.keys.len() + 1 == self.children.len());
debug_assert!(internal.keys.len() + 1 == internal.children.len());
InsertResult::SplitInternal(split_key, Arc::new(internal))
} else {
self.keys.insert(index, key);
self.children.insert(index + 1, child);
debug_assert!(self.keys.len() + 1 == self.children.len());
InsertResult::Inserted
}
}
/// Insert the given entry at the location indicated by `cursor`.
///
/// Inserting a value into an internal node might cause this node to split into two internal
/// nodes.
fn insert(&mut self, mut cursor: Cursor, range: Range<K>, value: V) -> InsertResult<K, V> {
let index = cursor.pop().expect("valid cursor");
let result = match &mut self.children {
ChildList::Leaf(children) => {
Arc::make_mut(&mut children[index]).insert(cursor, range, value)
}
ChildList::Internal(children) => {
Arc::make_mut(&mut children[index]).insert(cursor, range, value)
}
};
match result {
InsertResult::Inserted => InsertResult::Inserted,
InsertResult::SplitLeaf(key, right) => self.insert_child(index, key, Node::Leaf(right)),
InsertResult::SplitInternal(key, right) => {
self.insert_child(index, key, Node::Internal(right))
}
}
}
/// Determine whether to rebalance the child with the given index to the left or to the right.
///
/// Given a choice, we will rebalance the child with its larger neighbor.
///
/// The indices returned are always sequential.
fn select_children_to_rebalance(&self, index: usize) -> (usize, usize) {
if index == 0 {
(index, index + 1)
} else if index == self.children.len() - 1 {
(index - 1, index)
} else {
let left_index = index - 1;
let left_size = self.children.size_at(left_index);
let right_index = index + 1;
let right_size = self.children.size_at(right_index);
if left_size > right_size {
(left_index, index)
} else {
(index, right_index)
}
}
}
/// Rebalance the child at the given index.
///
/// If the child and its neighbor are sufficiently small, this function will merge them into a
/// single node.
fn rebalance_child(&mut self, index: usize) {
// Cannot rebalance if we have fewer than two children. This situation occurs only at the
// root of the tree.
if self.children.len() < 2 {
return;
}
let (left, right) = self.select_children_to_rebalance(index);
let n = self.children.size_at(left) + self.children.size_at(right);
match &mut self.children {
ChildList::Leaf(children) => {
let (left_shard_node, right_shared_node) = get_two_mut(children, left, right);
let left_node = Arc::make_mut(left_shard_node);
if n <= NODE_CAPACITY {
// Merge the right node into the left node.
left_node.keys.extend(right_shared_node.keys.iter().cloned());
left_node.values.extend(right_shared_node.values.iter().cloned());
self.keys.remove(left);
self.children.remove(right);
} else {
// Rebalance the elements between the nodes.
let split = n / 2;
let right_node = Arc::make_mut(right_shared_node);
if left_node.values.len() < split {
// Move elements from right to left.
let move_count = split - left_node.values.len();
left_node.keys.extend(right_node.keys.drain(..move_count));
left_node.values.extend(right_node.values.drain(..move_count));
} else {
// Move elements from left to right.
let mut keys = ArrayVec::new();
keys.extend(left_node.keys.drain(split..));
keys.extend(right_node.keys.iter().cloned());
right_node.keys = keys;
let mut values = ArrayVec::new();
values.extend(left_node.values.drain(split..));
values.extend(right_node.values.iter().cloned());
right_node.values = values;
}
// Update the split key to reflect the new division between the nodes.
self.keys[left] = right_node.keys[0].start;
}
}
ChildList::Internal(children) => {
let (left_shard_node, right_shared_node) = get_two_mut(children, left, right);
let left_node = Arc::make_mut(left_shard_node);
let old_split_key = &self.keys[left];
if n <= NODE_CAPACITY {
// Merge the right node into the left node.
left_node.keys.push(old_split_key.clone());
left_node.keys.extend(right_shared_node.keys.iter().cloned());
left_node.children.extend(&right_shared_node.children);
debug_assert!(left_node.keys.len() + 1 == left_node.children.len());
self.keys.remove(left);
self.children.remove(right);
} else {
// Rebalance the elements between the nodes.
let split = n / 2;
let split_key;
let right_node = Arc::make_mut(right_shared_node);
if left_node.children.len() < split {
// Move elements from right to left.
let move_count = split - left_node.children.len();
left_node.keys.push(old_split_key.clone());
left_node.keys.extend(right_node.keys.drain(..move_count));
split_key =
left_node.keys.pop().expect("must have moved at least one element");
left_node.children.extend(&right_node.children.split_off_front(move_count));
debug_assert!(left_node.keys.len() + 1 == left_node.children.len());
} else {
// Move elements from left to right.
let mut it = left_node.keys.drain((split - 1)..);
split_key = it.next().expect("must be moving at least one element");
let mut keys = ArrayVec::new();
keys.extend(it);
keys.push(old_split_key.clone());
keys.extend(right_node.keys.iter().cloned());
right_node.keys = keys;
let mut children = right_node.children.new_empty();
children.extend(&left_node.children.split_off(split));
children.extend(&right_node.children);
right_node.children = children;
debug_assert!(left_node.keys.len() + 1 == left_node.children.len());
debug_assert!(right_node.keys.len() + 1 == right_node.children.len());
}
// Update the split key to reflect the new division between the nodes.
self.keys[left] = split_key;
}
}
}
}
/// Remove the entry indicated by `cursor`.
fn remove(&mut self, mut cursor: Cursor) -> RemoveResult<V> {
let index = cursor.pop().expect("valid cursor");
let result = match &mut self.children {
ChildList::Leaf(children) => Arc::make_mut(&mut children[index]).remove(cursor),
ChildList::Internal(children) => Arc::make_mut(&mut children[index]).remove(cursor),
};
match result {
RemoveResult::NotFound => RemoveResult::NotFound,
RemoveResult::Removed(value) => RemoveResult::Removed(value),
RemoveResult::Underflow(value) => {
self.rebalance_child(index);
if self.children.len() < NODE_CAPACITY / 2 {
RemoveResult::Underflow(value)
} else {
RemoveResult::Removed(value)
}
}
}
}
}
/// A node in the btree.
#[derive(Clone, Debug)]
enum Node<K: Ord + Copy, V: Clone> {
/// An internal node.
Internal(Arc<NodeInternal<K, V>>),
/// A leaf node.
Leaf(Arc<NodeLeaf<K, V>>),
}
impl<K, V> Node<K, V>
where
K: Ord + Copy,
V: Clone,
{
/// The number of children stored at this node.
fn len(&self) -> usize {
match self {
Node::Internal(node) => node.children.len(),
Node::Leaf(node) => node.keys.len(),
}
}
/// Search this node for the given key and return both the key and the value found.
fn get_key_value(&self, cursor: Cursor) -> Option<(&Range<K>, &V)> {
match self {
Node::Leaf(node) => node.get_key_value(cursor),
Node::Internal(node) => node.get_key_value(cursor),
}
}
/// The last key/value pair stored in this node.
fn last_key_value(&self) -> Option<(&Range<K>, &V)> {
match self {
Node::Leaf(node) => node.last_key_value(),
Node::Internal(node) => node.last_key_value(),
}
}
/// Converts a reference into a Node into a NodeRef.
fn as_ref(&self) -> NodeRef<'_, K, V> {
match self {
Node::Internal(node) => NodeRef::Internal(node),
Node::Leaf(node) => NodeRef::Leaf(node),
}
}
/// Returns a reference to the node that contains the entry indicated by the cursor.
///
/// Assumes the cursor is non-empty.
fn get_containing_node(&self, cursor: Cursor) -> NodeRef<'_, K, V> {
assert!(cursor.depth > 0);
if cursor.depth == 1 {
return self.as_ref();
}
match self {
Node::Internal(node) => node.get_containing_node(cursor),
Node::Leaf(_) => unreachable!("leaf nodes do not have children"),
}
}
/// Insert the given value at the location indicated by `cursor`.
///
/// If the insertion causes this node to split, the node will always split into two instances
/// of the same type of node.
fn insert(&mut self, cursor: Cursor, range: Range<K>, value: V) -> InsertResult<K, V> {
match self {
Node::Internal(node) => Arc::make_mut(node).insert(cursor, range, value),
Node::Leaf(node) => Arc::make_mut(node).insert(cursor, range, value),
}
}
/// Remove the entry indicated by `cursor`.
fn remove(&mut self, cursor: Cursor) -> RemoveResult<V> {
match self {
Node::Internal(node) => Arc::make_mut(node).remove(cursor),
Node::Leaf(node) => Arc::make_mut(node).remove(cursor),
}
}
/// Find the given key in this node.
///
/// Updates `cursor` to point to the position indicated by `position`.
fn find(&self, key: &K, position: CursorPosition, cursor: &mut Cursor) {
match self {
Node::Internal(node) => node.find(key, position, cursor),
Node::Leaf(node) => node.find(key, position, cursor),
}
}
}
/// A node in the btree.
#[derive(Clone, Debug)]
enum NodeRef<'a, K: Ord + Copy, V: Clone> {
/// An internal node.
Internal(&'a Arc<NodeInternal<K, V>>),
/// A leaf node.
Leaf(&'a Arc<NodeLeaf<K, V>>),
}
impl<'a, K, V> NodeRef<'a, K, V>
where
K: Ord + Copy,
V: Clone,
{
/// The number of children stored at this node.
fn len(&self) -> usize {
match self {
NodeRef::Internal(node) => node.children.len(),
NodeRef::Leaf(node) => node.keys.len(),
}
}
}
/// An iterator over the key-value pairs stored in a RangeMap2.
#[derive(Debug)]
pub struct Iter<'a, K: Ord + Copy, V: Clone> {
/// The state of the forward iteration.
///
/// The cursor points to the next entry to enumerate.
forward: Cursor,
/// The state of the backward iteration.
///
/// The cursor points to the child that was most recently iterated or just past the end of the
/// entry list if no entries have been enumerated from this leaf yet.
backward: Cursor,
/// The root node of the tree.
root: &'a Node<K, V>,
}
impl<'a, K, V> Iter<'a, K, V>
where
K: Ord + Copy,
V: Clone,
{
/// Whether the iterator is complete.
///
/// Iteration stops when the forward and backward cursors meet.
fn is_done(&self) -> bool {
self.forward == self.backward
}
}
impl<'a, K, V> Iterator for Iter<'a, K, V>
where
K: Ord + Copy,
V: Clone,
{
type Item = (&'a Range<K>, &'a V);
fn next(&mut self) -> Option<Self::Item> {
while !self.is_done() {
match self.root.get_containing_node(self.forward) {
NodeRef::Leaf(leaf) => {
let index = self.forward.back();
if index < leaf.keys.len() {
let key = &leaf.keys[index];
let value = &leaf.values[index];
self.forward.increment_back();
return Some((key, value));
} else {
self.forward.pop_back();
self.forward.increment_back();
}
}
NodeRef::Internal(internal) => {
let index = self.forward.back();
if index < internal.children.len() {
self.forward.push_back(0);
} else {
self.forward.pop_back();
self.forward.increment_back();
}
}
}
}
None
}
}
impl<'a, K, V> DoubleEndedIterator for Iter<'a, K, V>
where
K: Ord + Copy,
V: Clone,
{
fn next_back(&mut self) -> Option<Self::Item> {
while !self.is_done() {
match self.root.get_containing_node(self.backward) {
NodeRef::Leaf(leaf) => {
let index = self.backward.back();
if index > 0 {
let key = &leaf.keys[index - 1];
let value = &leaf.values[index - 1];
self.backward.decrement_back();
return Some((key, value));
} else {
self.backward.pop_back();
}
}
NodeRef::Internal(internal) => {
let index = self.backward.back();
if index > 0 {
let child = internal.children.get_ref(index - 1);
self.backward.decrement_back();
self.backward.push_back(child.len());
} else {
self.backward.pop_back();
}
}
}
}
None
}
}
/// A map from ranges to values.
///
/// This map can be cloned efficiently. If the map is modified after being cloned, the relevant
/// parts of the map's internal structure will be copied lazily.
#[derive(Clone, Debug)]
pub struct RangeMap2<K: Ord + Copy, V: Clone + Eq> {
/// The root node of the tree.
///
/// The root node is either a leaf of an internal node, depending on the number of entries in
/// the map.
node: Node<K, V>,
}
impl<K, V> Default for RangeMap2<K, V>
where
K: Ord + Copy,
V: Clone + Eq,
{
fn default() -> Self {
Self { node: Node::Leaf(Arc::new(NodeLeaf::empty())) }
}
}
impl<K, V> RangeMap2<K, V>
where
K: Ord + Copy,
V: Clone + Eq,
{
/// Whether this map contains any entries.
pub fn is_empty(&self) -> bool {
match &self.node {
Node::Leaf(node) => node.keys.is_empty(),
Node::Internal(_) => false,
}
}
/// Find the given key in this node.
///
/// Returns a Cursor that points to the position indicated by `position`.
fn find(&self, key: &K, position: CursorPosition) -> Cursor {
let mut cursor = Cursor::default();
self.node.find(key, position, &mut cursor);
cursor
}
/// If the entry indicated by the cursor contains `key`, returns the range and value stored at
/// that entry.
fn get_if_contains_key(&self, key: &K, cursor: Cursor) -> Option<(&Range<K>, &V)> {
if let Some((range, value)) = self.node.get_key_value(cursor) {
if range.contains(key) {
return Some((range, value));
}
}
None
}
/// Searches the map for a range that contains the given key.
///
/// Returns the range and value if such a range is found.
pub fn get(&self, key: K) -> Option<(&Range<K>, &V)> {
self.get_if_contains_key(&key, self.find(&key, CursorPosition::Left))
}
/// The last range stored in this map.
pub fn last_range(&self) -> Option<&Range<K>> {
self.node.last_key_value().map(|(key, _)| key)
}
/// Searches the map for a range that contains the given key.
///
/// If such a range is found, returns a cursor to that entry, the range, and the value.
fn get_cursor_key_value(&mut self, key: &K) -> Option<(Cursor, Range<K>, V)> {
let cursor = self.find(key, CursorPosition::Left);
self.get_if_contains_key(key, cursor)
.map(|(range, value)| (cursor, range.clone(), value.clone()))
}
/// Remove the entry with the given key from the map.
///
/// If the key was present in the map, returns the value previously stored at the given key.
pub fn remove(&mut self, range: Range<K>) -> Vec<V> {
let mut removed_values = vec![];
if range.is_empty() {
return removed_values;
}
if let Some((cursor, old_range, v)) = self.get_cursor_key_value(&range.start) {
// Remove that range from the map.
if let Some(value) = self.remove_at(cursor) {
removed_values.push(value);
};
// If the removed range extends after the end of the given range,
// re-insert the part of the old range that extends beyond the end
// of the given range.
if old_range.end > range.end {
self.insert_range_internal(range.end..old_range.end, v.clone());
}
// If the removed range extends before the start of the given
// range, re-insert the part of the old range that extends before
// the start of the given range.
if old_range.start < range.start {
self.insert_range_internal(old_range.start..range.start, v);
}
// Notice that we can end up splitting the old range into two
// separate ranges if the old range extends both beyond the given
// range and before the given range.
}
if let Some((cursor, old_range, v)) = self.get_cursor_key_value(&range.end) {
// If the old range starts before the removed range, we need to trim the old range.
// TODO: Optimize with replace once available.
if old_range.start < range.end {
// Remove that range from the map.
if let Some(value) = self.remove_at(cursor) {
removed_values.push(value);
}
// If the removed range extends after the end of the given range,
// re-insert the part of the old range that extends beyond the end
// of the given range.
if old_range.end > range.end {
self.insert_range_internal(range.end..old_range.end, v);
}
}
}
let doomed = self.range(range.start..range.end).map(|(r, _)| r.start).collect::<Vec<_>>();
for key in doomed {
let cursor = self.find(&key, CursorPosition::Left);
removed_values.push(self.remove_at(cursor).expect("entry should exist"));
}
removed_values
}
/// Insert the given range and value at the location indicated by the cursor.
fn insert_at(&mut self, cursor: Cursor, range: Range<K>, value: V) -> Option<V> {
let result = self.node.insert(cursor, range, value);
match result {
InsertResult::Inserted => None,
InsertResult::SplitLeaf(key, right) => {
let mut keys = ArrayVec::new();
let mut children = ArrayVec::new();
keys.push(key);
let Node::Leaf(left) = self.node.clone() else {
unreachable!("non-leaf node split into leaf node");
};
children.push(left);
children.push(right);
self.node = Node::Internal(Arc::new(NodeInternal {
keys,
children: ChildList::Leaf(children),
}));
None
}
InsertResult::SplitInternal(key, right) => {
let mut keys = ArrayVec::new();
let mut children = ArrayVec::new();
keys.push(key);
let Node::Internal(left) = self.node.clone() else {
unreachable!("non-internal node split into internal node");
};
children.push(left);
children.push(right);
self.node = Node::Internal(Arc::new(NodeInternal {
keys,
children: ChildList::Internal(children),
}));
None
}
}
}
/// Insert the given range and value.
///
/// Assumes the range is empty and that adjacent ranges have different values.
fn insert_range_internal(&mut self, range: Range<K>, value: V) -> Option<V> {
let cursor = self.find(&range.start, CursorPosition::Left);
self.insert_at(cursor, range, value)
}
/// Inserts a range with the given value.
///
/// The keys included in the given range are now associated with the given
/// value. If those keys were previously associated with another value,
/// are no longer associated with that previous value.
///
/// This method can cause one or more values in the map to be dropped if
/// the all of the keys associated with those values are contained within
/// the given range.
///
/// If the inserted range is directly adjacent to another range with an equal value, the
/// inserted range will be merged with the adjacent ranges.
pub fn insert(&mut self, mut range: Range<K>, value: V) {
if range.is_empty() {
return;
}
self.remove(range.clone());
// Check for a range directly before this one. If it exists, it will be the last range with
// start < range.start.
if let Some((prev_range, prev_value)) = self.range(..range.start).next_back() {
if prev_range.end == range.start && value == *prev_value {
let cursor = self.find(&prev_range.start, CursorPosition::Left);
range.start = prev_range.start;
self.remove_at(cursor);
}
}
// Check for a range directly after. If it exists, we can look it up by exact start value
// of range.end.
if let Some((cursor, next_range, next_value)) = self.get_cursor_key_value(&range.end) {
if next_range.start == range.end && value == next_value {
range.end = next_range.end;
self.remove_at(cursor);
}
}
let cursor = self.find(&range.start, CursorPosition::Left);
self.insert_at(cursor, range, value);
}
/// Remove the entry with the given cursor from the map.
fn remove_at(&mut self, cursor: Cursor) -> Option<V> {
let result = self.node.remove(cursor);
match result {
RemoveResult::NotFound => None,
RemoveResult::Removed(value) => Some(value),
RemoveResult::Underflow(value) => {
match &mut self.node {
Node::Leaf(_) => {
// Nothing we can do about an underflow of a single leaf node at the root.
}
Node::Internal(node) => {
// If the root has underflown to a trivial list, we can shrink the tree.
if node.children.len() == 1 {
self.node = node.children.get(0);
}
}
}
Some(value)
}
}
}
/// Iterate through the keys and values stored in the map.
pub fn iter(&self) -> Iter<'_, K, V> {
Iter {
forward: Cursor::with_index(0),
backward: Cursor::with_index(self.node.len()),
root: &self.node,
}
}
/// Create the cursor stack for the start bound of the given range.
fn find_start_bound(&self, bounds: &impl RangeBounds<K>) -> Cursor {
let key = match bounds.start_bound() {
Bound::Included(key) => key,
Bound::Excluded(key) => key,
Bound::Unbounded => {
return Cursor::with_index(0);
}
};
self.find(key, CursorPosition::Left)
}
/// Create the cursor stack for the end bound of the given range.
fn find_end_bound(&self, bounds: &impl RangeBounds<K>) -> Cursor {
let key = match bounds.end_bound() {
Bound::Included(key) => key,
Bound::Excluded(key) => key,
Bound::Unbounded => {
return Cursor::with_index(self.node.len());
}
};
self.find(key, CursorPosition::Right)
}
/// Iterate through the keys and values stored in the given range in the map.
pub fn range(&self, bounds: impl RangeBounds<K>) -> Iter<'_, K, V> {
let forward = self.find_start_bound(&bounds);
let backward = self.find_end_bound(&bounds);
Iter { forward, backward, root: &self.node }
}
/// Iterate over the ranges in the map, starting at the first range starting after or at the given point.
pub fn iter_starting_at(&self, key: K) -> impl Iterator<Item = (&Range<K>, &V)> {
self.range(key..).filter(move |(range, _)| key <= range.start)
}
/// Iterate over the ranges in the map, starting at the last range starting before or at the given point.
pub fn iter_ending_at(&self, key: K) -> impl DoubleEndedIterator<Item = (&Range<K>, &V)> {
self.range(..key)
}
pub fn intersection(&self, range: impl Borrow<Range<K>>) -> Iter<'_, K, V> {
let range = range.borrow();
self.range(range.start..range.end)
}
}
#[cfg(test)]
mod test {
use super::*;
#[::fuchsia::test]
fn test_empty() {
let mut map = RangeMap2::<u32, i32>::default();
assert!(map.get(12).is_none());
map.remove(10..34);
// This is a test to make sure we can handle reversed ranges
#[allow(clippy::reversed_empty_ranges)]
map.remove(34..10);
}
#[::fuchsia::test]
fn test_insert_into_empty() {
let mut map = RangeMap2::<u32, i32>::default();
map.insert(10..34, -14);
assert_eq!((&(10..34), &-14), map.get(12).unwrap());
assert_eq!((&(10..34), &-14), map.get(10).unwrap());
assert!(map.get(9).is_none());
assert_eq!((&(10..34), &-14), map.get(33).unwrap());
assert!(map.get(34).is_none());
}
#[::fuchsia::test]
fn test_iter() {
let mut map = RangeMap2::<u32, i32>::default();
map.insert(10..34, -14);
map.insert(74..92, -12);
let mut iter = map.iter();
assert_eq!(iter.next().expect("missing elem"), (&(10..34), &-14));
assert_eq!(iter.next().expect("missing elem"), (&(74..92), &-12));
assert!(iter.next().is_none());
let mut iter = map.iter_starting_at(10);
assert_eq!(iter.next().expect("missing elem"), (&(10..34), &-14));
let mut iter = map.iter_starting_at(11);
assert_eq!(iter.next().expect("missing elem"), (&(74..92), &-12));
let mut iter = map.iter_starting_at(74);
assert_eq!(iter.next().expect("missing elem"), (&(74..92), &-12));
let mut iter = map.iter_starting_at(75);
assert_eq!(iter.next(), None);
assert_eq!(map.iter_ending_at(9).collect::<Vec<_>>(), vec![]);
assert_eq!(map.iter_ending_at(34).collect::<Vec<_>>(), vec![(&(10..34), &-14)]);
assert_eq!(map.iter_ending_at(74).collect::<Vec<_>>(), vec![(&(10..34), &-14)]);
assert_eq!(
map.iter_ending_at(75).collect::<Vec<_>>(),
vec![(&(10..34), &-14), (&(74..92), &-12)]
);
assert_eq!(
map.iter_ending_at(91).collect::<Vec<_>>(),
vec![(&(10..34), &-14), (&(74..92), &-12)]
);
assert_eq!(
map.iter_ending_at(92).collect::<Vec<_>>(),
vec![(&(10..34), &-14), (&(74..92), &-12)]
);
}
#[::fuchsia::test]
fn test_remove_overlapping_edge() {
let mut map = RangeMap2::<u32, i32>::default();
map.insert(10..34, -14);
map.remove(2..11);
assert_eq!((&(11..34), &-14), map.get(11).unwrap());
map.remove(33..42);
assert_eq!((&(11..33), &-14), map.get(12).unwrap());
}
#[::fuchsia::test]
fn test_remove_middle_splits_range() {
let mut map = RangeMap2::<u32, i32>::default();
map.insert(10..34, -14);
map.remove(15..18);
assert_eq!((&(10..15), &-14), map.get(12).unwrap());
assert_eq!((&(18..34), &-14), map.get(20).unwrap());
}
#[::fuchsia::test]
fn test_remove_upper_half_of_split_range_leaves_lower_range() {
let mut map = RangeMap2::<u32, i32>::default();
map.insert(10..34, -14);
map.remove(15..18);
map.insert(2..7, -21);
map.remove(20..42);
assert_eq!((&(2..7), &-21), map.get(5).unwrap());
assert_eq!((&(10..15), &-14), map.get(12).unwrap());
}
#[::fuchsia::test]
fn test_range_map_overlapping_insert() {
let mut map = RangeMap2::<u32, i32>::default();
map.insert(2..7, -21);
map.insert(5..9, -42);
map.insert(1..3, -43);
map.insert(6..8, -44);
assert_eq!((&(1..3), &-43), map.get(2).unwrap());
assert_eq!((&(3..5), &-21), map.get(4).unwrap());
assert_eq!((&(5..6), &-42), map.get(5).unwrap());
assert_eq!((&(6..8), &-44), map.get(7).unwrap());
}
#[::fuchsia::test]
fn test_intersect_single() {
let mut map = RangeMap2::<u32, i32>::default();
map.insert(2..7, -10);
let mut iter = map.intersection(3..4);
assert_eq!(iter.next(), Some((&(2..7), &-10)));
assert_eq!(iter.next(), None);
let mut iter = map.intersection(2..3);
assert_eq!(iter.next(), Some((&(2..7), &-10)));
assert_eq!(iter.next(), None);
let mut iter = map.intersection(1..4);
assert_eq!(iter.next(), Some((&(2..7), &-10)));
assert_eq!(iter.next(), None);
let mut iter = map.intersection(1..2);
assert_eq!(iter.next(), None);
let mut iter = map.intersection(6..7);
assert_eq!(iter.next(), Some((&(2..7), &-10)));
assert_eq!(iter.next(), None);
}
#[::fuchsia::test]
fn test_intersect_multiple() {
let mut map = RangeMap2::<u32, i32>::default();
map.insert(2..7, -10);
map.insert(7..9, -20);
map.insert(10..11, -30);
let mut iter = map.intersection(3..8);
assert_eq!(iter.next(), Some((&(2..7), &-10)));
assert_eq!(iter.next(), Some((&(7..9), &-20)));
assert_eq!(iter.next(), None);
let mut iter = map.intersection(3..11);
assert_eq!(iter.next(), Some((&(2..7), &-10)));
assert_eq!(iter.next(), Some((&(7..9), &-20)));
assert_eq!(iter.next(), Some((&(10..11), &-30)));
assert_eq!(iter.next(), None);
}
#[::fuchsia::test]
fn test_intersect_no_gaps() {
let mut map = RangeMap2::<u32, i32>::default();
map.insert(0..1, -10);
map.insert(1..2, -20);
map.insert(2..3, -30);
let mut iter = map.intersection(0..3);
assert_eq!(iter.next(), Some((&(0..1), &-10)));
assert_eq!(iter.next(), Some((&(1..2), &-20)));
assert_eq!(iter.next(), Some((&(2..3), &-30)));
assert_eq!(iter.next(), None);
}
#[test]
fn test_merging() {
let mut map = RangeMap2::<u32, i32>::default();
map.insert(1..2, -10);
assert_eq!(map.iter().collect::<Vec<_>>(), vec![(&(1..2), &-10)]);
map.insert(3..4, -10);
assert_eq!(map.iter().collect::<Vec<_>>(), vec![(&(1..2), &-10), (&(3..4), &-10)]);
map.insert(2..3, -10);
assert_eq!(map.iter().collect::<Vec<_>>(), vec![(&(1..4), &-10)]);
map.insert(0..1, -10);
assert_eq!(map.iter().collect::<Vec<_>>(), vec![(&(0..4), &-10)]);
map.insert(4..5, -10);
assert_eq!(map.iter().collect::<Vec<_>>(), vec![(&(0..5), &-10)]);
map.insert(2..3, -20);
assert_eq!(
map.iter().collect::<Vec<_>>(),
vec![(&(0..2), &-10), (&(2..3), &-20), (&(3..5), &-10)]
);
}
#[test]
fn test_remove_multiple_ranges_exact_query() {
let first = 15..21;
let second = first.end..29;
let mut map = RangeMap2::default();
map.insert(first.clone(), 1);
map.insert(second.clone(), 2);
assert_eq!(map.remove(first.start..second.end), &[1, 2]);
}
#[::fuchsia::test]
fn test_large_insert_and_remove() {
let mut map = RangeMap2::<u32, i32>::default();
let num_entries = 1000;
// Insert a large number of entries
for i in 0..num_entries {
let start = i as u32 * 10;
let end = start + 5;
let value = i as i32;
map.insert(start..end, value);
}
// Verify that all inserted entries can be retrieved
for i in 0..num_entries {
let start = i as u32 * 10;
let end = start + 5;
let point = start + 2;
if let Some((range, value)) = map.get(point) {
assert!(range.start <= point && point < range.end);
assert_eq!(*range, start..end);
assert_eq!(*value, i as i32);
} else {
panic!("Expected to find a range for point {}", point);
}
}
// Remove a large number of entries
for i in 0..num_entries {
let start = i as u32 * 10;
let end = start + 5;
map.remove(start..end);
}
// Verify that the map is empty after removing all entries
assert!(map.is_empty());
}
#[::fuchsia::test]
fn test_large_insert_and_remove_overlapping() {
let mut map = RangeMap2::<u32, i32>::default();
let num_entries = 1000;
// Insert a large number of entries with overlapping ranges
for i in 0..num_entries {
let start = i as u32 * 5;
let end = start + 20;
let value = i as i32;
map.insert(start..end, value);
}
// Verify that all inserted entries can be retrieved
for i in 0..num_entries {
let point = i as u32 * 5 + 1;
if let Some((range, value)) = map.get(point) {
assert!(range.start <= point && point < range.end);
assert_eq!(*value, i as i32);
} else {
panic!("Expected to find a range for point {}", point);
}
}
// Remove a large number of entries with overlapping ranges
for i in 0..num_entries {
let start = i as u32 * 5;
let end = start + 20;
map.remove(start..end);
}
// Verify that the map is empty after removing all entries
assert!(map.is_empty());
}
#[::fuchsia::test]
fn test_large_insert_and_get_specific_points() {
let mut map = RangeMap2::<u32, i32>::default();
let num_entries = 1000;
let mut inserted_ranges = Vec::new();
// Insert a large number of entries
for i in 0..num_entries {
let start = i as u32 * 10;
let end = start + 5;
let value = i as i32;
map.insert(start..end, value);
inserted_ranges.push((start..end, value));
}
// Verify that specific points can be retrieved correctly
for (range, value) in &inserted_ranges {
let point = range.start + 2;
let (retrieved_range, retrieved_value) = map.get(point).unwrap();
assert_eq!(retrieved_range, range);
assert_eq!(retrieved_value, value);
}
}
#[::fuchsia::test]
fn test_large_insert_and_iter() {
let mut map = RangeMap2::<u32, i32>::default();
let num_entries = 1000;
let mut inserted_ranges = Vec::new();
// Insert a large number of entries
for i in 0..num_entries {
let start = i as u32 * 10;
let end = start + 5;
let value = i as i32;
map.insert(start..end, value);
inserted_ranges.push((start..end, value));
}
// Verify that iter() returns all inserted entries
let mut iter_ranges: Vec<(&Range<u32>, &i32)> = map.iter().collect();
iter_ranges.sort_by_key(|(range, _)| range.start);
let mut inserted_ranges_sorted: Vec<(Range<u32>, i32)> = inserted_ranges.clone();
inserted_ranges_sorted.sort_by_key(|(range, _)| range.start);
assert_eq!(iter_ranges.len(), inserted_ranges_sorted.len());
for (i, (range, value)) in iter_ranges.iter().enumerate() {
assert_eq!(*range, &inserted_ranges_sorted[i].0);
assert_eq!(*value, &inserted_ranges_sorted[i].1);
}
}
#[::fuchsia::test]
fn test_large_insert_and_iter_starting_at() {
let mut map = RangeMap2::<u32, i32>::default();
let num_entries = 1000;
// Insert a large number of entries
for i in 0..num_entries {
let start = i as u32 * 10;
let end = start + 5;
let value = i as i32;
map.insert(start..end, value);
}
// Verify iter_starting_at()
let start_point = 5000;
let mut iter = map.iter_starting_at(start_point);
while let Some((range, _)) = iter.next() {
assert!(range.start >= start_point);
}
}
#[::fuchsia::test]
fn test_large_insert_and_iter_ending_at() {
let mut map = RangeMap2::<u32, i32>::default();
let num_entries = 1000;
// Insert a large number of entries
for i in 0..num_entries {
let start = i as u32 * 10;
let end = start + 5;
let value = i as i32;
map.insert(start..end, value);
}
// Verify iter_ending_at()
let end_point = 5000;
let mut iter = map.iter_ending_at(end_point);
while let Some((range, _)) = iter.next() {
assert!(range.start < end_point);
}
}
#[::fuchsia::test]
fn test_large_insert_and_intersection() {
let mut map = RangeMap2::<u32, i32>::default();
let num_entries = 1000;
// Insert a large number of entries
for i in 0..num_entries {
let start = i as u32 * 10;
let end = start + 5;
let value = i as i32;
map.insert(start..end, value);
}
// Verify intersection()
let intersect_start = 4000;
let intersect_end = 4050;
let mut iter = map.intersection(intersect_start..intersect_end);
while let Some((range, _)) = iter.next() {
assert!((range.start < intersect_end && range.end > intersect_start));
}
}
#[::fuchsia::test]
fn test_large_insert_and_last_range() {
let mut map = RangeMap2::<u32, i32>::default();
let num_entries = 1000;
let mut last_range = None;
// Insert a large number of entries
for i in 0..num_entries {
let start = i as u32 * 10;
let end = start + 5;
let value = i as i32;
map.insert(start..end, value);
last_range = Some(start..end);
}
// Verify last_range()
if let Some(expected_last_range) = last_range {
assert_eq!(map.last_range().unwrap(), &expected_last_range);
}
}
#[::fuchsia::test]
fn test_large_insert_and_remove_alternating() {
let mut map = RangeMap2::<u32, i32>::default();
let num_entries = 1000;
// Insert and remove entries in an alternating pattern
for i in 0..num_entries {
let start = i as u32 * 10;
let end = start + 5;
let value = i as i32;
map.insert(start..end, value);
if i % 2 == 0 {
// Remove every other entry
map.remove(start..end);
}
}
// Verify that only the non-removed entries remain
for i in 0..num_entries {
let start = i as u32 * 10;
let end = start + 5;
let point = start + 2;
if i % 2 != 0 {
if let Some((range, value)) = map.get(point) {
assert!(range.start <= point && point < range.end);
assert_eq!(*range, start..end);
assert_eq!(*value, i as i32);
} else {
panic!("Expected to find a range for point {}", point);
}
} else {
assert!(map.get(point).is_none());
}
}
}
#[::fuchsia::test]
fn test_large_insert_and_remove_multiple_times() {
let mut map = RangeMap2::<u32, i32>::default();
let num_entries = 200;
let num_iterations = 5;
for _ in 0..num_iterations {
// Insert a large number of entries
for i in 0..num_entries {
let start = i as u32 * 10;
let end = start + 5;
let value = i as i32;
map.insert(start..end, value);
}
// Remove a large number of entries
for i in 0..num_entries {
let start = i as u32 * 10;
let end = start + 5;
map.remove(start..end);
}
}
// Verify that the map is empty after multiple insert/remove cycles
assert!(map.is_empty());
}
#[::fuchsia::test]
fn test_merging_ranges_with_equal_values() {
let mut map = RangeMap2::<u32, i32>::default();
// Insert some initial ranges
map.insert(10..20, 100);
map.insert(30..40, 200);
map.insert(50..60, 100);
// Merge adjacent ranges with equal values
map.insert(20..30, 100);
assert_eq!(map.get(15).unwrap(), (&(10..30), &100));
assert_eq!(map.get(35).unwrap(), (&(30..40), &200));
assert_eq!(map.get(55).unwrap(), (&(50..60), &100));
// Merge non-adjacent ranges with equal values
map.insert(40..50, 100);
assert_eq!(map.get(15).unwrap(), (&(10..30), &100));
assert_eq!(map.get(35).unwrap(), (&(30..40), &200));
assert_eq!(map.get(45).unwrap(), (&(40..60), &100));
// Insert a range with a different value
map.insert(60..70, 300);
assert_eq!(map.get(65).unwrap(), (&(60..70), &300));
// Merge a range with a different value
map.insert(70..80, 300);
assert_eq!(map.get(65).unwrap(), (&(60..80), &300));
// Merge a range with a different value at the beginning
map.insert(0..10, 400);
assert_eq!(map.get(5).unwrap(), (&(0..10), &400));
// Merge a range with a different value at the end
map.insert(80..90, 400);
assert_eq!(map.get(85).unwrap(), (&(80..90), &400));
// Merge a range with a different value in the middle
map.insert(90..100, 400);
assert_eq!(map.get(95).unwrap(), (&(80..100), &400));
map.insert(100..110, 400);
assert_eq!(map.get(95).unwrap(), (&(80..110), &400));
map.insert(110..120, 400);
assert_eq!(map.get(95).unwrap(), (&(80..120), &400));
// Merge a range with a different value in the middle
map.insert(10..90, 400);
assert_eq!(map.get(5).unwrap(), (&(0..120), &400));
}
#[::fuchsia::test]
fn test_large_insert_and_remove_with_gaps() {
let mut map = RangeMap2::<u32, i32>::default();
let num_entries = 500;
// Insert entries with gaps
for i in 0..num_entries {
let start = i as u32 * 20;
let end = start + 5;
let value = i as i32;
map.insert(start..end, value);
}
// Remove entries with gaps
for i in 0..num_entries {
if i % 2 == 0 {
let start = i as u32 * 20;
let end = start + 5;
map.remove(start..end);
}
}
// Verify the state of the map
for i in 0..num_entries {
let start = i as u32 * 20;
let end = start + 5;
let point = start + 2;
if i % 2 != 0 {
if let Some((range, value)) = map.get(point) {
assert!(range.start <= point && point < range.end);
assert_eq!(*range, start..end);
assert_eq!(*value, i as i32);
} else {
panic!("Expected to find a range for point {}", point);
}
} else {
assert!(map.get(point).is_none());
}
}
}
}