avl
This commit is contained in:
parent
45dbf1a13c
commit
911c26b174
@ -1,5 +1,6 @@
|
||||
//! Standard generic collections.
|
||||
|
||||
pub mod avl;
|
||||
pub mod pair;
|
||||
pub mod rbtree;
|
||||
pub mod stack;
|
||||
|
165
src/rstd/collections/avl.rs
Normal file
165
src/rstd/collections/avl.rs
Normal file
@ -0,0 +1,165 @@
|
||||
use std::{error::Error, fmt::Display, rc::Rc};
|
||||
|
||||
use crate::rcore::*;
|
||||
use crate::rstd::{
|
||||
atomic::{au64::*, *},
|
||||
nullable::*,
|
||||
point::*,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum TreeParseError<E> {
|
||||
Int(IntParseError),
|
||||
Point(PointParseError),
|
||||
Key(E),
|
||||
LeafHeight(u64),
|
||||
Balance(u64, u64),
|
||||
}
|
||||
|
||||
impl<E> From<IntParseError> for TreeParseError<E> {
|
||||
fn from(value: IntParseError) -> Self {
|
||||
Self::Int(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<E> From<PointParseError> for TreeParseError<E> {
|
||||
fn from(value: PointParseError) -> Self {
|
||||
Self::Point(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: Display> Display for TreeParseError<E> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::Int(int_error) => {
|
||||
f.write_fmt(format_args!("failed to parse AVL tree height: {int_error}"))
|
||||
}
|
||||
Self::Point(point_error) => f.write_fmt(format_args!(
|
||||
"failed to parse AVL node reference: {point_error}"
|
||||
)),
|
||||
Self::Key(key_error) => {
|
||||
f.write_fmt(format_args!("failed to parse AVL node key: {key_error}"))
|
||||
}
|
||||
Self::LeafHeight(height) => {
|
||||
f.write_fmt(format_args!("invalid AVL leaf height: {height}!=0."))
|
||||
}
|
||||
Self::Balance(lh, rh) => f.write_fmt(format_args!("unbalanced AVL node: {lh} {rh}.")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: Error> Error for TreeParseError<E> {}
|
||||
|
||||
struct AvlNode<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> {
|
||||
l: AvlTree<'a, Ctx, A>,
|
||||
r: AvlTree<'a, Ctx, A>,
|
||||
key: Rc<A>,
|
||||
}
|
||||
|
||||
struct AvlTree<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> {
|
||||
node: Nullable<'a, Ctx, AvlNode<'a, Ctx, A>>,
|
||||
height: u64,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct AvlNodeFactory<F>(F);
|
||||
|
||||
#[derive(Clone)]
|
||||
struct AvlTreeFactory<F>(NullableFactory<AvlNodeFactory<F>>);
|
||||
|
||||
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Serializable for AvlNode<'a, Ctx, A> {
|
||||
fn serialize(&self, serializer: &mut dyn Serializer) {
|
||||
self.l.serialize(serializer);
|
||||
self.r.serialize(serializer);
|
||||
self.key.serialize(serializer);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Serializable for AvlTree<'a, Ctx, A> {
|
||||
fn serialize(&self, serializer: &mut dyn Serializer) {
|
||||
self.height.serialize(serializer);
|
||||
self.node.serialize(serializer);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Mentionable<'a, Ctx> for AvlNode<'a, Ctx, A> {
|
||||
type Fctr = AvlNodeFactory<A::Fctr>;
|
||||
|
||||
fn factory(&self) -> Self::Fctr {
|
||||
AvlNodeFactory(self.key.factory())
|
||||
}
|
||||
|
||||
fn points_typed(&self, points: &mut impl TakesPoints<'a, Ctx>) {
|
||||
self.l.points_typed(points);
|
||||
self.r.points_typed(points);
|
||||
self.key.points_typed(points);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Mentionable<'a, Ctx> for AvlTree<'a, Ctx, A> {
|
||||
type Fctr = AvlTreeFactory<A::Fctr>;
|
||||
|
||||
fn factory(&self) -> Self::Fctr {
|
||||
AvlTreeFactory(self.node.factory())
|
||||
}
|
||||
|
||||
fn points_typed(&self, points: &mut impl TakesPoints<'a, Ctx>) {
|
||||
self.node.points_typed(points);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Ctx: Context<'a>, F: Factory<'a, Ctx>> Factory<'a, Ctx> for AvlNodeFactory<F> {
|
||||
type Mtbl = AvlNode<'a, Ctx, F::Mtbl>;
|
||||
|
||||
type ParseError = TreeParseError<F::ParseError>;
|
||||
|
||||
fn deserialize(
|
||||
&self,
|
||||
deserializer: &mut dyn Deserializer,
|
||||
resolver: Rc<dyn Resolver<'a, Ctx>>,
|
||||
addresses: &mut Addresses,
|
||||
) -> ParseResult<'a, Ctx, Self> {
|
||||
let tree_factory = AvlTreeFactory(NullableFactory::new(self.clone()));
|
||||
let l = tree_factory.deserialize(deserializer, resolver.clone(), addresses)?;
|
||||
let r = tree_factory.deserialize(deserializer, resolver.clone(), addresses)?;
|
||||
if std::cmp::max(l.height, r.height) - std::cmp::min(l.height, r.height) > 1 {
|
||||
return Err(TreeParseError::Balance(l.height, r.height));
|
||||
}
|
||||
let key = self
|
||||
.0
|
||||
.deserialize(deserializer, resolver.clone(), addresses)
|
||||
.map_err(TreeParseError::Key)?
|
||||
.into();
|
||||
Ok(AvlNode { l, r, key })
|
||||
}
|
||||
|
||||
fn unexpected_tail(&self, tail: &[u8]) -> Self::ParseError {
|
||||
TreeParseError::Key(self.0.unexpected_tail(tail))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Ctx: Context<'a>, F: Factory<'a, Ctx>> Factory<'a, Ctx> for AvlTreeFactory<F> {
|
||||
type Mtbl = AvlTree<'a, Ctx, F::Mtbl>;
|
||||
|
||||
type ParseError = TreeParseError<F::ParseError>;
|
||||
|
||||
fn deserialize(
|
||||
&self,
|
||||
deserializer: &mut dyn Deserializer,
|
||||
resolver: Rc<dyn Resolver<'a, Ctx>>,
|
||||
addresses: &mut Addresses,
|
||||
) -> ParseResult<'a, Ctx, Self> {
|
||||
let node = self.0.deserialize(deserializer, resolver, addresses)?;
|
||||
let height = u64::a_deserialize(deserializer)?;
|
||||
if let Nullable::Null(_) = node {
|
||||
if height != 0 {
|
||||
return Err(TreeParseError::LeafHeight(height));
|
||||
}
|
||||
}
|
||||
Ok(AvlTree { node, height })
|
||||
}
|
||||
|
||||
fn unexpected_tail(&self, tail: &[u8]) -> Self::ParseError {
|
||||
u64::a_unexpected_tail(tail).into()
|
||||
}
|
||||
}
|
@ -22,28 +22,27 @@ pub enum TreeParseError<E> {
|
||||
|
||||
impl<E> From<BooleanParseError> for TreeParseError<E> {
|
||||
fn from(value: BooleanParseError) -> Self {
|
||||
TreeParseError::Boolean(value)
|
||||
Self::Boolean(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<E> From<PointParseError> for TreeParseError<E> {
|
||||
fn from(value: PointParseError) -> Self {
|
||||
TreeParseError::Point(value)
|
||||
Self::Point(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: Display> Display for TreeParseError<E> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
TreeParseError::Boolean(boolean_error) => {
|
||||
f.write_fmt(format_args!("failed to parse RB flag: {}", boolean_error))
|
||||
Self::Boolean(boolean_error) => {
|
||||
f.write_fmt(format_args!("failed to parse RB flag: {boolean_error}"))
|
||||
}
|
||||
TreeParseError::Point(point_error) => f.write_fmt(format_args!(
|
||||
"failed to parse RB tree reference: {}",
|
||||
point_error
|
||||
Self::Point(point_error) => f.write_fmt(format_args!(
|
||||
"failed to parse RB tree reference: {point_error}"
|
||||
)),
|
||||
TreeParseError::Key(key_error) => {
|
||||
f.write_fmt(format_args!("failed to parse RB tree key: {}", key_error))
|
||||
Self::Key(key_error) => {
|
||||
f.write_fmt(format_args!("failed to parse RB tree key: {key_error}"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user