Skip to content

Commit

Permalink
Add alternative memtable
Browse files Browse the repository at this point in the history
  • Loading branch information
al8n committed Oct 30, 2024
1 parent 46e1fe5 commit 9b2e66a
Show file tree
Hide file tree
Showing 11 changed files with 828 additions and 19 deletions.
3 changes: 3 additions & 0 deletions src/memtable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ pub mod linked;
/// Memtable implementation based on ARNEA based [`SkipMap`](skl).
pub mod arena;

/// Sum type for different memtable implementations.
pub mod alternative;

/// An entry which is stored in the memory table.
pub trait BaseEntry<'a>: Sized {
/// The key type.
Expand Down
232 changes: 232 additions & 0 deletions src/memtable/alternative.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
pub use multiple_version::MultipleVersionTable;
pub use table::Table;

macro_rules! match_op {
($self:ident.$op:ident($($args:ident),*) $(.map($associated_ty:ident))?) => {{
match $self {
Self::Arena(e) => e.$op($($args,)*) $(.map(Self::$associated_ty::Arena))?,
Self::Linked(e) => e.$op($($args,)*) $(.map(Self::$associated_ty::Linked))?,
}}
};
(Dispatch::$associated_ty:ident($self:ident.$op:ident($($args:ident),*))) => {{
match $self {
Self::Arena(e) => Self::$associated_ty::Arena(e.$op($($args,)*)),
Self::Linked(e) => Self::$associated_ty::Linked(e.$op($($args,)*)),
}}
};
(new($opts:ident)) => {{
match $opts {
Self::Options::Arena(opts) => ArenaTable::new(opts).map(Self::Arena).map_err(Self::Error::Arena),
Self::Options::Linked => LinkedTable::new(())
.map(Self::Linked)
.map_err(|_| Self::Error::Linked),
}
}};
(update($self:ident.$op:ident($($args:ident),*))) => {{
match $self {
Self::Arena(t) => t.$op($($args,)*).map_err(Self::Error::Arena),
Self::Linked(t) => t.$op($($args,)*).map_err(|_| Self::Error::Linked),
}
}};
}

macro_rules! iter {
(enum $name:ident {
Arena($arena:ident),
Linked($linked:ident),
} -> $ent:ident) => {
/// A sum type of iter for different memtable implementations.
#[non_exhaustive]
pub enum $name<'a, K, V>
where
K: ?Sized + Type + Ord,
KeyPointer<K>: Type<Ref<'a> = KeyPointer<K>> + KeyRef<'a, KeyPointer<K>>,
V: ?Sized + Type,
{
/// Arena iter
Arena($arena<'a, KeyPointer<K>, ValuePointer<V>>),
/// Linked iter
Linked($linked<'a, KeyPointer<K>, ValuePointer<V>>),
}

impl<'a, K, V> Iterator for $name<'a, K, V>
where
K: ?Sized + Type + Ord + 'static,
KeyPointer<K>: Type<Ref<'a> = KeyPointer<K>> + KeyRef<'a, KeyPointer<K>>,
V: ?Sized + Type + 'static,
{
type Item = $ent<'a, K, V>;

#[inline]
fn next(&mut self) -> Option<Self::Item> {
match_op!(self.next().map(Item))
}
}

impl<'a, K, V> DoubleEndedIterator for $name<'a, K, V>
where
K: ?Sized + Type + Ord + 'static,
KeyPointer<K>: Type<Ref<'a> = KeyPointer<K>> + KeyRef<'a, KeyPointer<K>>,
V: ?Sized + Type + 'static,
{
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
match_op!(self.next_back().map(Item))
}
}
};
}

macro_rules! range {
(enum $name:ident {
Arena($arena:ident),
Linked($linked:ident),
} -> $ent:ident) => {
/// A sum type of range for different memtable implementations.
#[non_exhaustive]
pub enum $name<'a, K, V, Q, R>
where
R: RangeBounds<Q>,
Q: ?Sized + Comparable<KeyPointer<K>>,
K: ?Sized + Type + Ord,
KeyPointer<K>: Type<Ref<'a> = KeyPointer<K>> + KeyRef<'a, KeyPointer<K>>,
V: ?Sized + Type,
{
/// Arena range
Arena($arena<'a, KeyPointer<K>, ValuePointer<V>, Q, R>),
/// Linked range
Linked($linked<'a, Q, R, KeyPointer<K>, ValuePointer<V>>),
}

impl<'a, K, V, Q, R> Iterator for $name<'a, K, V, Q, R>
where
R: RangeBounds<Q>,
Q: ?Sized + Comparable<KeyPointer<K>>,
K: ?Sized + Type + Ord + 'a,
KeyPointer<K>: Type<Ref<'a> = KeyPointer<K>> + KeyRef<'a, KeyPointer<K>>,
V: ?Sized + Type + 'a,
{
type Item = $ent<'a, K, V>;

#[inline]
fn next(&mut self) -> Option<Self::Item> {
match_op!(self.next().map(Item))
}
}

impl<'a, K, V, Q, R> DoubleEndedIterator for $name<'a, K, V, Q, R>
where
R: RangeBounds<Q>,
Q: ?Sized + Comparable<KeyPointer<K>>,
K: ?Sized + Type + Ord + 'a,
KeyPointer<K>: Type<Ref<'a> = KeyPointer<K>> + KeyRef<'a, KeyPointer<K>>,
V: ?Sized + Type + 'a,
{
fn next_back(&mut self) -> Option<Self::Item> {
match_op!(self.next_back().map(Item))
}
}
};
}

macro_rules! base_entry {
(enum $name:ident {
Arena($arena:ident),
Linked($linked:ident),
}) => {
/// A sum type of entry for different memtable implementations.
#[derive(Debug)]
#[non_exhaustive]
pub enum $name<'a, K, V>
where
K: ?Sized,
V: ?Sized,
{
/// Arena entry
Arena($arena<'a, KeyPointer<K>, ValuePointer<V>>),
/// Linked entry
Linked($linked<'a, KeyPointer<K>, ValuePointer<V>>),
}

impl<K: ?Sized, V: ?Sized> Clone for $name<'_, K, V> {
#[inline]
fn clone(&self) -> Self {
match self {
Self::Arena(e) => Self::Arena(e.clone()),
Self::Linked(e) => Self::Linked(e.clone()),
}
}
}

impl<'a, K, V> BaseEntry<'a> for $name<'a, K, V>
where
K: ?Sized + Type + Ord,
KeyPointer<K>: Type<Ref<'a> = KeyPointer<K>> + KeyRef<'a, KeyPointer<K>>,
V: ?Sized + Type,
{
type Key = K;

type Value = V;

#[inline]
fn key(&self) -> KeyPointer<Self::Key> {
*match_op!(self.key())
}

fn next(&mut self) -> Option<Self> {
match self {
Self::Arena(e) => e.next().map(Self::Arena),
Self::Linked(e) => e.next().map(Self::Linked),
}
}

fn prev(&mut self) -> Option<Self> {
match self {
Self::Arena(e) => e.prev().map(Self::Arena),
Self::Linked(e) => e.prev().map(Self::Linked),
}
}
}
};
}

/// The sum type for different memtable implementations options.
#[derive(Debug)]
#[non_exhaustive]
pub enum TableOptions {
/// The options for the arena memtable.
Arena(super::arena::TableOptions),
/// The options for the linked memtable.
Linked,
}

/// The sum type of error for different memtable implementations.
#[derive(Debug)]
#[non_exhaustive]
pub enum Error {
/// The error for the arena memtable.
Arena(skl::Error),
/// The error for the linked memtable.
Linked,
}

impl From<skl::Error> for Error {
#[inline]
fn from(e: skl::Error) -> Self {
Self::Arena(e)

Check warning on line 216 in src/memtable/alternative.rs

View check run for this annotation

Codecov / codecov/patch

src/memtable/alternative.rs#L215-L216

Added lines #L215 - L216 were not covered by tests
}
}

impl core::fmt::Display for Error {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::Arena(e) => write!(f, "{e}"),
Self::Linked => Ok(()),

Check warning on line 224 in src/memtable/alternative.rs

View check run for this annotation

Codecov / codecov/patch

src/memtable/alternative.rs#L221-L224

Added lines #L221 - L224 were not covered by tests
}
}
}

impl core::error::Error for Error {}

mod multiple_version;
mod table;
Loading

0 comments on commit 9b2e66a

Please sign in to comment.