From e89e44d129ee5031deda56909420719ce2235aca Mon Sep 17 00:00:00 2001 From: timofey Date: Mon, 24 Apr 2023 13:36:57 +0000 Subject: [PATCH] rbtree --- src/std/atomic.rs | 1 + src/std/atomic/boolean.rs | 65 +++++++++ src/std/collections.rs | 1 + src/std/collections/rbtree.rs | 260 ++++++++++++++++++++++++++++++++++ src/std/inlining.rs | 2 + src/std/nullable.rs | 29 ++-- 6 files changed, 338 insertions(+), 20 deletions(-) create mode 100644 src/std/atomic/boolean.rs create mode 100644 src/std/collections/rbtree.rs diff --git a/src/std/atomic.rs b/src/std/atomic.rs index e1563c0..ae792ab 100644 --- a/src/std/atomic.rs +++ b/src/std/atomic.rs @@ -2,6 +2,7 @@ //! simple static types, which are completely [Context]-independent. pub mod atomic_object; +pub mod boolean; pub mod plain; use std::marker::PhantomData; diff --git a/src/std/atomic/boolean.rs b/src/std/atomic/boolean.rs new file mode 100644 index 0000000..a380478 --- /dev/null +++ b/src/std/atomic/boolean.rs @@ -0,0 +1,65 @@ +use crate::std::inlining::*; + +use super::*; + +impl Serializable for bool { + fn serialize(&self, serializer: &mut dyn Serializer) { + match self { + true => serializer.write(&[0]), + false => serializer.write(&[1]), + } + } +} + +#[derive(Debug)] +pub enum BooleanParseError { + OutOfBounds(u8), + Eof, + ExtraData(usize), +} + +impl Display for BooleanParseError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + BooleanParseError::OutOfBounds(value) => { + f.write_fmt(format_args!("boolean value out of bounds: {}.", value)) + } + BooleanParseError::Eof => { + f.write_fmt(format_args!("encountered EOF write parsing a boolean.")) + } + BooleanParseError::ExtraData(length) => f.write_fmt(format_args!( + "encountered extra data of length {} while parsing a boolean", + length + )), + } + } +} + +impl Error for BooleanParseError {} + +impl From<&[u8]> for BooleanParseError { + fn from(_value: &[u8]) -> Self { + Self::Eof + } +} + +impl Atomic for bool { + type ParseError = BooleanParseError; + + fn deserialize(deserializer: &mut dyn Deserializer) -> Result { + let byte = deserializer.read_n_const::<1>()?; + match byte[0] { + 0 => Ok(false), + 1 => Ok(true), + value => Err(BooleanParseError::OutOfBounds(value)), + } + } + + fn unexpected_tail(tail: &[u8]) -> Self::ParseError { + BooleanParseError::ExtraData(tail.len()) + } +} + +impl ConstSizeAtomic for bool { + const SIZE: usize = 1; +} diff --git a/src/std/collections.rs b/src/std/collections.rs index edfa86f..579e1a6 100644 --- a/src/std/collections.rs +++ b/src/std/collections.rs @@ -1,4 +1,5 @@ //! Standard generic collections. pub mod pair; +pub mod rbtree; pub mod stack; diff --git a/src/std/collections/rbtree.rs b/src/std/collections/rbtree.rs new file mode 100644 index 0000000..cff332d --- /dev/null +++ b/src/std/collections/rbtree.rs @@ -0,0 +1,260 @@ +use std::{error::Error, fmt::Display}; + +use crate::core::*; +use crate::std::{ + atomic::{boolean::*, *}, + nullable::*, + point::*, +}; + +const B: bool = false; +const R: bool = true; +type RB = bool; + +#[derive(Debug)] +pub enum TreeParseError { + Boolean(BooleanParseError), + Point(PointParseError), + Key(E), +} + +impl From for TreeParseError { + fn from(value: BooleanParseError) -> Self { + TreeParseError::Boolean(value) + } +} + +impl From for TreeParseError { + fn from(value: PointParseError) -> Self { + TreeParseError::Point(value) + } +} + +impl Display for TreeParseError { + 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)) + } + TreeParseError::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)) + } + } + } +} + +impl Error for TreeParseError {} + +pub enum RBNode<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> { + R(RNode<'a, Ctx, A>), + B(BNode<'a, Ctx, A>), +} + +pub struct BNode<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> { + cl: Nullable<'a, Ctx, RBNode<'a, Ctx, A>>, + cr: Nullable<'a, Ctx, RBNode<'a, Ctx, A>>, + key: A, +} + +pub struct RNode<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> { + cl: Nullable<'a, Ctx, BNode<'a, Ctx, A>>, + cr: Nullable<'a, Ctx, BNode<'a, Ctx, A>>, + key: A, +} + +#[derive(Clone)] +pub struct RBFactory { + key_factory: F, +} + +#[derive(Clone)] +pub struct BFactory { + key_factory: F, +} + +#[derive(Clone)] +pub struct RFactory { + key_factory: F, +} + +impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> RBNode<'a, Ctx, A> { + fn key(&self) -> &A { + match self { + RBNode::R(RNode { key, .. }) => key, + RBNode::B(BNode { key, .. }) => key, + } + } +} + +impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Serializable for RBNode<'a, Ctx, A> { + fn serialize(&self, serializer: &mut dyn Serializer) { + match self { + RBNode::R(r) => { + R.serialize(serializer); + r.serialize(serializer); + } + RBNode::B(b) => { + B.serialize(serializer); + b.serialize(serializer); + } + } + } +} + +impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Serializable for BNode<'a, Ctx, A> { + fn serialize(&self, serializer: &mut dyn Serializer) { + self.cl.serialize(serializer); + self.cr.serialize(serializer); + self.key.serialize(serializer); + } +} + +impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Serializable for RNode<'a, Ctx, A> { + fn serialize(&self, serializer: &mut dyn Serializer) { + self.cl.serialize(serializer); + self.cr.serialize(serializer); + self.key.serialize(serializer); + } +} + +impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Mentionable<'a, Ctx> for RBNode<'a, Ctx, A> { + type Fctr = RBFactory; + + fn factory(&self) -> Self::Fctr { + RBFactory { + key_factory: self.key().factory(), + } + } + + fn points(&self, points: &mut Vec>>) { + match self { + RBNode::R(r) => r.points(points), + RBNode::B(b) => b.points(points), + } + } +} + +impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Mentionable<'a, Ctx> for BNode<'a, Ctx, A> { + type Fctr = BFactory; + + fn factory(&self) -> Self::Fctr { + BFactory { + key_factory: self.key.factory(), + } + } + + fn points(&self, points: &mut Vec>>) { + self.cl.points(points); + self.cr.points(points); + self.key.points(points); + } +} + +impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Mentionable<'a, Ctx> for RNode<'a, Ctx, A> { + type Fctr = RFactory; + + fn factory(&self) -> Self::Fctr { + RFactory { + key_factory: self.key.factory(), + } + } + + fn points(&self, points: &mut Vec>>) { + self.cl.points(points); + self.cr.points(points); + self.key.points(points); + } +} + +impl<'a, Ctx: 'a + Context, F: Factory<'a, Ctx>> Factory<'a, Ctx> for RBFactory { + type Mtbl = RBNode<'a, Ctx, F::Mtbl>; + + type ParseError = TreeParseError; + + fn deserialize( + &self, + deserializer: &mut dyn Deserializer, + resolver: std::rc::Rc>, + addresses: &mut Addresses, + ) -> ParseResult<'a, Ctx, Self> { + let rb = RB::deserialize(deserializer)?; + Ok(match rb { + R => RBNode::R( + RFactory { + key_factory: self.key_factory.clone(), + } + .deserialize(deserializer, resolver, addresses)?, + ), + B => RBNode::B( + BFactory { + key_factory: self.key_factory.clone(), + } + .deserialize(deserializer, resolver, addresses)?, + ), + }) + } + + fn unexpected_tail(&self, tail: &[u8]) -> Self::ParseError { + TreeParseError::Key(self.key_factory.unexpected_tail(tail)) + } +} + +impl<'a, Ctx: 'a + Context, F: Factory<'a, Ctx>> Factory<'a, Ctx> for BFactory { + type Mtbl = BNode<'a, Ctx, F::Mtbl>; + + type ParseError = TreeParseError; + + fn deserialize( + &self, + deserializer: &mut dyn Deserializer, + resolver: std::rc::Rc>, + addresses: &mut Addresses, + ) -> ParseResult<'a, Ctx, Self> { + let nullable_factory = NullableFactory::new(RBFactory { + key_factory: self.key_factory.clone(), + }); + let cl = nullable_factory.deserialize(deserializer, resolver.clone(), addresses)?; + let cr = nullable_factory.deserialize(deserializer, resolver.clone(), addresses)?; + let key = self + .key_factory + .deserialize(deserializer, resolver, addresses) + .map_err(TreeParseError::Key)?; + Ok(BNode { cl, cr, key }) + } + + fn unexpected_tail(&self, tail: &[u8]) -> Self::ParseError { + TreeParseError::Key(self.key_factory.unexpected_tail(tail)) + } +} + +impl<'a, Ctx: 'a + Context, F: Factory<'a, Ctx>> Factory<'a, Ctx> for RFactory { + type Mtbl = RNode<'a, Ctx, F::Mtbl>; + + type ParseError = TreeParseError; + + fn deserialize( + &self, + deserializer: &mut dyn Deserializer, + resolver: std::rc::Rc>, + addresses: &mut Addresses, + ) -> ParseResult<'a, Ctx, Self> { + let nullable_factory = NullableFactory::new(BFactory { + key_factory: self.key_factory.clone(), + }); + let cl = nullable_factory.deserialize(deserializer, resolver.clone(), addresses)?; + let cr = nullable_factory.deserialize(deserializer, resolver.clone(), addresses)?; + let key = self + .key_factory + .deserialize(deserializer, resolver, addresses) + .map_err(TreeParseError::Key)?; + Ok(RNode { cl, cr, key }) + } + + fn unexpected_tail(&self, tail: &[u8]) -> Self::ParseError { + TreeParseError::Key(self.key_factory.unexpected_tail(tail)) + } +} diff --git a/src/std/inlining.rs b/src/std/inlining.rs index 4cf3d9d..7c2edd5 100644 --- a/src/std/inlining.rs +++ b/src/std/inlining.rs @@ -52,6 +52,8 @@ pub trait ConstSizeAtomic: InlineableAtomic { const SIZE: usize; } +impl InlineableAtomic for A {} + impl InlineableFactory for AtomicFactory {} impl FixedSizeFactory for AtomicFactory { diff --git a/src/std/nullable.rs b/src/std/nullable.rs index 9ef461f..537b49c 100644 --- a/src/std/nullable.rs +++ b/src/std/nullable.rs @@ -12,9 +12,10 @@ pub enum Nullable<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> { } /// Nullable reference factory. -pub struct NullableFactory<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> { +#[derive(Clone)] +pub struct NullableFactory { /// Factory of the referenced object. - factory: A::Fctr, + factory: F, } impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Serializable for Nullable<'a, Ctx, A> { @@ -27,7 +28,7 @@ impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Serializable for Nullable<' } impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Mentionable<'a, Ctx> for Nullable<'a, Ctx, A> { - type Fctr = NullableFactory<'a, Ctx, A>; + type Fctr = NullableFactory; fn factory(&self) -> Self::Fctr { match self { @@ -48,18 +49,8 @@ impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Mentionable<'a, Ctx> for Nu } } -impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Clone for NullableFactory<'a, Ctx, A> { - fn clone(&self) -> Self { - Self { - factory: self.factory.clone(), - } - } -} - -impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Factory<'a, Ctx> - for NullableFactory<'a, Ctx, A> -{ - type Mtbl = Nullable<'a, Ctx, A>; +impl<'a, Ctx: 'a + Context, F: Factory<'a, Ctx>> Factory<'a, Ctx> for NullableFactory { + type Mtbl = Nullable<'a, Ctx, F::Mtbl>; type ParseError = PointParseError; @@ -96,8 +87,8 @@ impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Nullable<'a, Ctx, Nullable< } } -impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> NullableFactory<'a, Ctx, A> { - pub fn new(factory: A::Fctr) -> Self { +impl NullableFactory { + pub fn new(factory: F) -> Self { Self { factory } } } @@ -111,8 +102,6 @@ impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Clone for Nullable<'a, Ctx, } } -impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> AlwaysConstSize - for NullableFactory<'a, Ctx, A> -{ +impl AlwaysConstSize for NullableFactory { const _SIZE: usize = HASH_SIZE; }