use super::defs::*;
use super::rule::*;
use super::node::RadixNode;
#[derive(Clone)]
pub struct RadixPack<V> {
pub regular: VecMap<RadixNode<V>>,
pub special: IndexMap<Bytes, RadixNode<V>>,
}
impl<V> RadixPack<V> {
#[inline]
pub fn is_empty(&self) -> bool {
self.regular.is_empty() && self.special.is_empty()
}
#[inline]
pub fn iter(&self) -> Iter<V> {
Iter::from(self)
}
#[inline]
pub fn iter_mut(&mut self) -> IterMut<V> {
IterMut::from(self)
}
pub fn insert(&mut self, rule: RadixRule) -> RadixResult<&mut RadixNode<V>> {
let frag = rule.origin();
if !matches!(rule, RadixRule::Plain { .. }) {
return match self.special.contains_key(frag) {
true => Ok(&mut self.special[frag]),
false => Ok(self.special.entry(frag.clone()).or_insert(RadixNode::from(rule)))
};
}
let first = *frag.first().ok_or(RadixError::PathEmpty)? as usize;
if !self.regular.contains_key(first) {
self.regular.insert(first, RadixNode::from(rule));
return match self.regular.get_mut(first) {
Some(node) => Ok(node),
_ => unreachable!()
};
}
let found = match self.regular.get_mut(first) {
Some(node) => node,
_ => unreachable!()
};
let share = found.rule.longest(frag.as_ref(), false).unwrap_or(b"");
let equal = found.rule.is_special() || found.rule.origin().len() == share.len();
if !equal {
let node = found.divide(share.len())?;
let byte = node.rule.origin()[0] as usize;
found.next.regular.insert(byte, node);
}
match frag.len() != share.len() {
true => found.next.insert(RadixRule::try_from(frag.slice(share.len()..))?),
false => Ok(found),
}
}
#[inline]
pub fn clear(&mut self) {
self.regular.clear();
self.special.clear();
}
}
impl<V> Default for RadixPack<V> {
#[inline]
fn default() -> Self {
Self { regular: VecMap::new(), special: IndexMap::new() }
}
}
#[derive(Default, Clone)]
pub struct Iter<'n, V> {
onetime: Option<&'n RadixNode<V>>,
regular: Option<vec_map::Values<'n, RadixNode<V>>>,
special: indexmap::map::Values<'n, Bytes, RadixNode<V>>,
}
impl<'n, V> From<&'n RadixNode<V>> for Iter<'n, V> {
#[inline]
fn from(value: &'n RadixNode<V>) -> Self {
Self { onetime: Some(value), regular: None, special: Default::default() }
}
}
impl<'n, V> From<&'n RadixPack<V>> for Iter<'n, V> {
#[inline]
fn from(value: &'n RadixPack<V>) -> Self {
Self { onetime: None, regular: Some(value.regular.values()), special: value.special.values() }
}
}
impl<'n, V> Iterator for Iter<'n, V> {
type Item = &'n RadixNode<V>;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
if let Some(node) = self.onetime.take() {
return Some(node);
}
if let Some(iter) = &mut self.regular {
if let Some(node) = iter.next() {
return Some(node);
}
}
self.special.next()
}
}
#[derive(Default)]
pub struct IterMut<'n, V> {
onetime: Option<&'n mut RadixNode<V>>,
regular: Option<vec_map::ValuesMut<'n, RadixNode<V>>>,
special: indexmap::map::ValuesMut<'n, Bytes, RadixNode<V>>,
}
impl<'n, V> From<&'n mut RadixNode<V>> for IterMut<'n, V> {
#[inline]
fn from(value: &'n mut RadixNode<V>) -> Self {
Self { onetime: Some(value), regular: None, special: Default::default() }
}
}
impl<'n, V> From<&'n mut RadixPack<V>> for IterMut<'n, V> {
#[inline]
fn from(value: &'n mut RadixPack<V>) -> Self {
Self { onetime: None, regular: Some(value.regular.values_mut()), special: value.special.values_mut() }
}
}
impl<'n, V> Iterator for IterMut<'n, V> {
type Item = &'n mut RadixNode<V>;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
if let Some(node) = self.onetime.take() {
return Some(node);
}
if let Some(iter) = &mut self.regular {
if let Some(node) = iter.next() {
return Some(node);
}
}
self.special.next()
}
}