Skip to content

Commit

Permalink
prototype map key redesign
Browse files Browse the repository at this point in the history
  • Loading branch information
uint committed Jul 11, 2024
1 parent 099aa3e commit 75261e8
Show file tree
Hide file tree
Showing 6 changed files with 298 additions and 52 deletions.
3 changes: 2 additions & 1 deletion packages/storey/src/containers/column.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::encoding::{DecodableWith, EncodableWith};
use crate::storage::{IterableStorage, StorageBranch};
use crate::storage::{Storage, StorageMut};

use super::{BoundFor, BoundedIterableAccessor, IterableAccessor, Storable};
use super::{BoundFor, BoundedIterableAccessor, IterableAccessor, NonTerminal, Storable};

const META_LAST_IX: &[u8] = &[0];
const META_LEN: &[u8] = &[1];
Expand Down Expand Up @@ -85,6 +85,7 @@ where
E: Encoding,
T: EncodableWith<E> + DecodableWith<E>,
{
type Kind = NonTerminal;
type Accessor<S> = ColumnAccess<E, T, S>;
type Key = u32;
type KeyDecodeError = ColumnKeyDecodeError;
Expand Down
3 changes: 2 additions & 1 deletion packages/storey/src/containers/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::encoding::{DecodableWith, EncodableWith, Encoding};
use crate::storage::StorageBranch;
use crate::storage::{Storage, StorageMut};

use super::Storable;
use super::{Storable, Terminal};

/// A single item in the storage.
///
Expand Down Expand Up @@ -70,6 +70,7 @@ where
E: Encoding,
T: EncodableWith<E> + DecodableWith<E>,
{
type Kind = Terminal;
type Accessor<S> = ItemAccess<E, T, S>;
type Key = ();
type KeyDecodeError = ItemKeyDecodeError;
Expand Down
99 changes: 99 additions & 0 deletions packages/storey/src/containers/map/key.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
pub trait Key {
type Kind: KeyKind;

fn encode(&self) -> Vec<u8>;
}

pub trait OwnedKey: Key {
type Error;

fn from_bytes(bytes: &[u8]) -> Result<Self, Self::Error>
where
Self: Sized;
}

impl Key for String {
type Kind = DynamicKey;

fn encode(&self) -> Vec<u8> {
self.as_bytes().to_vec()
}
}

impl Key for str {
type Kind = DynamicKey;

fn encode(&self) -> Vec<u8> {
self.as_bytes().to_vec()
}
}

#[derive(Debug, PartialEq, Eq, Clone, Copy, thiserror::Error)]
#[error("invalid UTF8")]
pub struct InvalidUtf8;

impl OwnedKey for String {
type Error = InvalidUtf8;

fn from_bytes(bytes: &[u8]) -> Result<Self, Self::Error>
where
Self: Sized,
{
std::str::from_utf8(bytes)
.map(String::from)
.map_err(|_| InvalidUtf8)
}
}

pub trait KeyKind {}

pub struct FixedSizeKey<const L: usize>;
pub struct DynamicKey;

impl<const L: usize> KeyKind for FixedSizeKey<L> {}
impl KeyKind for DynamicKey {}

pub enum NumericKeyDecodeError {
InvalidLength,
}

macro_rules! impl_key_for_numeric {
($($t:ty),*) => {
$(
impl Key for $t {
type Kind = FixedSizeKey<{(Self::BITS / 8) as usize}>;

fn encode(&self) -> Vec<u8> {
self.to_be_bytes().to_vec()
}
}

impl OwnedKey for $t {
type Error = NumericKeyDecodeError;

fn from_bytes(bytes: &[u8]) -> Result<Self, Self::Error>
where
Self: Sized,
{
if bytes.len() != std::mem::size_of::<Self>() {
return Err(NumericKeyDecodeError::InvalidLength);
}

let mut buf = [0; std::mem::size_of::<Self>()];
buf.copy_from_slice(bytes);
Ok(Self::from_be_bytes(buf))
}
}
)*
};
}

impl_key_for_numeric!(u8, u16, u32, u64, u128, i8, i16, i32, i64, i128);

impl<const N: usize> Key for [u8; N] {
type Kind = FixedSizeKey<N>;

fn encode(&self) -> Vec<u8> {
self.to_vec()
}
}
Loading

0 comments on commit 75261e8

Please sign in to comment.