use crate::envelope::Envelope;
use crate::object::RTreeObject;
use crate::params::RTreeParams;
#[cfg(not(test))]
use alloc::vec::Vec;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(
feature = "serde",
serde(bound(
serialize = "T: Serialize, T::Envelope: Serialize",
deserialize = "T: Deserialize<'de>, T::Envelope: Deserialize<'de>"
))
)]
pub enum RTreeNode<T>
where
T: RTreeObject,
{
Leaf(T),
Parent(ParentNode<T>),
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct ParentNode<T>
where
T: RTreeObject,
{
pub(crate) children: Vec<RTreeNode<T>>,
pub(crate) envelope: T::Envelope,
}
impl<T> RTreeObject for RTreeNode<T>
where
T: RTreeObject,
{
type Envelope = T::Envelope;
fn envelope(&self) -> Self::Envelope {
match self {
RTreeNode::Leaf(ref t) => t.envelope(),
RTreeNode::Parent(ref data) => data.envelope.clone(),
}
}
}
#[doc(hidden)]
impl<T> RTreeNode<T>
where
T: RTreeObject,
{
pub fn is_leaf(&self) -> bool {
match self {
RTreeNode::Leaf(..) => true,
RTreeNode::Parent(..) => false,
}
}
}
impl<T> ParentNode<T>
where
T: RTreeObject,
{
pub fn children(&self) -> &[RTreeNode<T>] {
&self.children
}
pub fn envelope(&self) -> T::Envelope {
self.envelope.clone()
}
pub(crate) fn new_root<Params>() -> Self
where
Params: RTreeParams,
{
ParentNode {
envelope: Envelope::new_empty(),
children: Vec::with_capacity(Params::MAX_SIZE + 1),
}
}
pub(crate) fn new_parent(children: Vec<RTreeNode<T>>) -> Self {
let envelope = envelope_for_children(&children);
ParentNode { envelope, children }
}
#[cfg(test)]
#[allow(missing_docs)]
pub fn sanity_check<Params>(&self, check_max_size: bool) -> Option<usize>
where
Params: RTreeParams,
{
if self.children.is_empty() {
Some(0)
} else {
let mut result = None;
self.sanity_check_inner::<Params>(check_max_size, 1, &mut result);
result
}
}
#[cfg(test)]
fn sanity_check_inner<Params>(
&self,
check_max_size: bool,
height: usize,
leaf_height: &mut Option<usize>,
) where
Params: RTreeParams,
{
if height > 1 {
let min_size = Params::MIN_SIZE;
assert!(self.children.len() >= min_size);
}
let mut envelope = T::Envelope::new_empty();
if check_max_size {
let max_size = Params::MAX_SIZE;
assert!(self.children.len() <= max_size);
}
for child in &self.children {
match child {
RTreeNode::Leaf(ref t) => {
envelope.merge(&t.envelope());
if let Some(ref leaf_height) = leaf_height {
assert_eq!(height, *leaf_height);
} else {
*leaf_height = Some(height);
}
}
RTreeNode::Parent(ref data) => {
envelope.merge(&data.envelope);
data.sanity_check_inner::<Params>(check_max_size, height + 1, leaf_height);
}
}
}
assert_eq!(self.envelope, envelope);
}
}
pub fn envelope_for_children<T>(children: &[RTreeNode<T>]) -> T::Envelope
where
T: RTreeObject,
{
let mut result = T::Envelope::new_empty();
for child in children {
result.merge(&child.envelope());
}
result
}