mod set;
#[cfg(test)]
mod tests;
pub use set::{OwnedSet, OwnedSetIntoIter, OwnedSetIter};
use std::{borrow::Borrow, ops::Bound};
use super::{tree, BudgetedMapIter, Link, Node, OwnedNode, MAX_HEIGHT};
pub struct OwnedMap<K, V> {
root: Link<K, V>,
len: usize,
}
impl<K, V> Default for OwnedMap<K, V> {
fn default() -> Self {
Self { root: None, len: 0 }
}
}
impl<K, V> OwnedMap<K, V> {
pub fn new() -> Self {
Self::default()
}
pub const fn entry_bytes() -> usize {
size_of::<Node<K, V>>()
}
pub fn allocated_bytes(&self) -> usize {
self.len * Self::entry_bytes()
}
pub fn len(&self) -> usize {
self.len
}
pub fn is_empty(&self) -> bool {
self.len == 0
}
pub fn iter(&self) -> BudgetedMapIter<'_, K, V> {
BudgetedMapIter::new(&self.root, self.len)
}
pub fn keys(&self) -> impl ExactSizeIterator<Item = &K> + std::iter::FusedIterator {
self.iter().map(|(key, _)| key)
}
pub fn values(&self) -> impl ExactSizeIterator<Item = &V> + std::iter::FusedIterator {
self.iter().map(|(_, value)| value)
}
}
impl<K: Ord, V> OwnedMap<K, V> {
pub fn get<Q: Ord + ?Sized>(&self, key: &Q) -> Option<&V>
where
K: Borrow<Q>,
{
tree::get(&self.root, key).map(|node| &node.value)
}
pub fn get_mut<Q: Ord + ?Sized>(&mut self, key: &Q) -> Option<&mut V>
where
K: Borrow<Q>,
{
tree::get_mut(&mut self.root, key).map(|node| &mut node.value)
}
pub fn contains_key<Q: Ord + ?Sized>(&self, key: &Q) -> bool
where
K: Borrow<Q>,
{
self.get(key).is_some()
}
pub fn insert(&mut self, key: K, value: V) -> Option<V> {
if let Some(previous) = self.get_mut(&key) {
return Some(std::mem::replace(previous, value));
}
let entry = OwnedNode {
value: Box::new(Node {
key,
value,
left: None,
right: None,
height: 1,
}),
memory: None,
};
let previous = tree::insert(&mut self.root, entry);
self.len += 1;
previous
}
pub fn append(&mut self, other: Self) {
if self.is_empty() {
*self = other;
return;
}
let mut entries = other.into_iter();
while let Some(node) = entries.next_node() {
self.len += usize::from(tree::insert(&mut self.root, node).is_none());
}
}
pub fn remove<Q: Ord + ?Sized>(&mut self, key: &Q) -> Option<V>
where
K: Borrow<Q>,
{
self.remove_entry(key).map(|(_, value)| value)
}
pub fn remove_entry<Q: Ord + ?Sized>(&mut self, key: &Q) -> Option<(K, V)>
where
K: Borrow<Q>,
{
let removed = tree::remove(&mut self.root, key);
self.len -= usize::from(removed.is_some());
removed
}
pub fn first_from<Q: Ord + ?Sized>(&self, start: Bound<&Q>) -> Option<(&K, &V)>
where
K: Borrow<Q>,
{
let mut link = &self.root;
let mut candidate = None;
while let Some(node) = link {
let included = match start {
Bound::Unbounded => true,
Bound::Included(key) => node.key.borrow() >= key,
Bound::Excluded(key) => node.key.borrow() > key,
};
if included {
candidate = Some((&node.key, &node.value.value));
link = &node.left;
} else {
link = &node.right;
}
}
candidate
}
}
impl<K: Ord + Borrow<Q>, V, Q: Ord + ?Sized> std::ops::Index<&Q> for OwnedMap<K, V> {
type Output = V;
fn index(&self, key: &Q) -> &V {
self.get(key).expect("missing owned map key")
}
}
impl<K: Ord + Clone, V: Clone> Clone for OwnedMap<K, V> {
fn clone(&self) -> Self {
self.iter()
.map(|(key, value)| (key.clone(), value.clone()))
.collect()
}
}
impl<K: std::fmt::Debug, V: std::fmt::Debug> std::fmt::Debug for OwnedMap<K, V> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_map().entries(self.iter()).finish()
}
}
impl<K: PartialEq, V: PartialEq> PartialEq for OwnedMap<K, V> {
fn eq(&self, other: &Self) -> bool {
self.len == other.len && self.iter().eq(other.iter())
}
}
impl<K: Eq, V: Eq> Eq for OwnedMap<K, V> {}
impl<K: Ord, V> FromIterator<(K, V)> for OwnedMap<K, V> {
fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
let mut map = Self::new();
for (key, value) in iter {
map.insert(key, value);
}
map
}
}
impl<'a, K, V> IntoIterator for &'a OwnedMap<K, V> {
type Item = (&'a K, &'a V);
type IntoIter = BudgetedMapIter<'a, K, V>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
pub struct OwnedMapIntoIter<K, V> {
stack: [Option<OwnedNode<K, V>>; MAX_HEIGHT],
depth: usize,
remaining: usize,
}
impl<K, V> OwnedMapIntoIter<K, V> {
fn push_left(&mut self, mut link: Link<K, V>) {
while let Some(mut node) = link {
link = node.value.left.take();
self.stack[self.depth] = Some(node);
self.depth += 1;
}
}
fn next_node(&mut self) -> Option<OwnedNode<K, V>> {
self.depth = self.depth.checked_sub(1)?;
let mut node = self.stack[self.depth].take().expect("owned traversal node");
self.push_left(node.value.right.take());
node.value.height = 1;
self.remaining -= 1;
Some(node)
}
}
impl<K, V> Iterator for OwnedMapIntoIter<K, V> {
type Item = (K, V);
fn next(&mut self) -> Option<Self::Item> {
self.next_node().map(tree::into_entry)
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.remaining, Some(self.remaining))
}
}
impl<K, V> ExactSizeIterator for OwnedMapIntoIter<K, V> {}
impl<K, V> std::iter::FusedIterator for OwnedMapIntoIter<K, V> {}
impl<K, V> IntoIterator for OwnedMap<K, V> {
type Item = (K, V);
type IntoIter = OwnedMapIntoIter<K, V>;
fn into_iter(self) -> Self::IntoIter {
let mut iter = OwnedMapIntoIter {
stack: std::array::from_fn(|_| None),
depth: 0,
remaining: self.len,
};
iter.push_left(self.root);
iter
}
}