Skip to content

Commit

Permalink
fix: add compact test and correct compact bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
tbrezot committed Feb 20, 2024
1 parent 59116a3 commit 6605584
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 47 deletions.
3 changes: 3 additions & 0 deletions src/dx_enc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ pub trait DynRhDxEnc<const VALUE_LENGTH: usize>: Sized {
/// Removes any binding on the given tags from the stored DX.
async fn delete(&self, tags: Set<Self::Tag>) -> Result<(), Self::Error>;

/// Returns the entire stored DX.
async fn dump(&self) -> Result<Dx<VALUE_LENGTH, Self::Tag, Self::Item>, Self::Error>;

/// Gets the currently stored DX and stores it using the given connection
/// under the given seed. Returns the new instance of the scheme allowing to
/// manipulate this copy.
Expand Down
9 changes: 5 additions & 4 deletions src/dx_enc/structs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,11 @@ impl<Item: Hash + PartialEq + Eq> DerefMut for Set<Item> {

impl<Item: Hash + PartialEq + Eq + Display> Display for Set<Item> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
writeln!(f, "[")?;
writeln!(f, "{{")?;
for tag in &self.0 {
writeln!(f, " {},", tag)?;
}
write!(f, "]")
writeln!(f, "}}")
}
}

Expand Down Expand Up @@ -106,6 +106,7 @@ impl<Item: Hash + PartialEq + Eq + Clone> Clone for Set<Item> {
const TOKEN_LENGTH: usize = 32;

impl_byte_array!(Token, TOKEN_LENGTH, "Token");

#[derive(PartialEq)]
pub struct Dx<const VALUE_LENGTH: usize, Tag: Hash + PartialEq + Eq, Item>(HashMap<Tag, Item>);

Expand Down Expand Up @@ -219,12 +220,12 @@ impl DerefMut for Edx {

impl Display for Edx {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Token to EncryptedValue map: {{")?;
writeln!(f, "Token to EncryptedValue map: {{")?;
for (token, encrypted_value) in self.iter() {
writeln!(
f,
" '{}': {}",
STANDARD.encode(token),
token,
STANDARD.encode(encrypted_value)
)?;
}
Expand Down
8 changes: 6 additions & 2 deletions src/dx_enc/vera.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,13 @@ impl<
.map_err(Self::Error::from)
}

async fn rebuild(&self, seed: &[u8], connection: DbConnection) -> Result<Self, Self::Error> {
async fn dump(&self) -> Result<Dx<VALUE_LENGTH, Self::Tag, Self::Item>, Self::Error> {
let edx = self.connection.dump().await?;
let dx = self.resolve(&edx)?;
self.resolve(&edx).map_err(Self::Error::from)
}

async fn rebuild(&self, seed: &[u8], connection: DbConnection) -> Result<Self, Self::Error> {
let dx = self.dump().await?;
let new_scheme = Self::setup(seed, connection)?;
<Self as DynRhDxEnc<VALUE_LENGTH>>::insert(&new_scheme, dx).await?;
Ok(new_scheme)
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ mod mm_enc;
#[cfg(feature = "in_memory")]
pub use db::in_memory_db::{InMemoryDb, InMemoryDbError};
pub use db::DbInterface;
pub use dx_enc::{CsRhDxEnc, DynRhDxEnc, Token, Vera};
pub use dx_enc::{CsRhDxEnc, DynRhDxEnc, Token, Tag, Set, Vera};
pub use error::{CoreError, DbInterfaceErrorTrait, Error};
pub use mm_enc::{CsRhMmEnc, Findex};

Expand Down
7 changes: 5 additions & 2 deletions src/macros.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pub use base64::engine::{general_purpose::STANDARD, Engine};
pub use base64::engine::{general_purpose::{GeneralPurpose, STANDARD}, Engine};
pub use core::{
default::Default,
ops::{Deref, DerefMut},
Expand Down Expand Up @@ -92,7 +92,10 @@ macro_rules! impl_byte_array {
f,
"{}({})",
$str_name,
$crate::macros::STANDARD.encode(self)
<$crate::macros::GeneralPurpose as $crate::macros::Engine>::encode(
&$crate::macros::STANDARD,
self
)
)
}
}
Expand Down
112 changes: 89 additions & 23 deletions src/mm_enc/findex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ impl<
)))
})?;
deleted_chain_tags.extend(
Metadata::new(metadata.stop + n_links, metadata.stop)
Metadata::new(metadata.start - n_links, metadata.start)
.unroll(entry_tag.as_ref())
.into_iter(),
)
Expand Down Expand Up @@ -332,10 +332,46 @@ impl<
}
}

async fn compact(&self) -> Result<(), Error<EntryDxEnc::Error, ChainDxEnc::Error>> {
todo!()
}
pub async fn compact(&self) -> Result<(), Error<EntryDxEnc::Error, ChainDxEnc::Error>> {
let entry_dx = self.entry.dump().await.map_err(Error::Entry)?;
let chain_tags = entry_dx
.iter()
.map(|(tag, metadata)| (tag.clone(), metadata.unroll(tag.as_ref())))
.collect::<Mm<EntryDxEnc::Tag, ChainDxEnc::Tag>>();
let links = self
.chain
.get(chain_tags.values().flatten().cloned().collect())
.await
.map_err(Error::Chain)?;
let old_chain_items = chain_tags
.into_iter()
.map(|(entry_tag, tags)| {
let items = tags
.iter()
.map(|chain_tag| {
links
.get(chain_tag)
.ok_or_else(|| {
CoreError::Crypto(format!(
"missing link value for tag '{chain_tag}"
))
})
.cloned()
})
.collect::<Result<Vec<_>, _>>()?;
Ok((entry_tag, items))
})
.collect::<Result<Mm<_, _>, CoreError>>()?;
let new_chain_items = old_chain_items
.iter()
.map(|(tag, items)| {
let new_items = decompose(Operation::Insert, &recompose(&items)?)?;
Ok((tag.clone(), new_items))
})
.collect::<Result<Mm<_, _>, CoreError>>()?;

self.apply(new_chain_items, old_chain_items).await
}
}

impl<
Expand Down Expand Up @@ -370,8 +406,8 @@ impl<
let metadata = self.entry.get(tags).await.map_err(Self::Error::Entry)?;
let chain_tags = metadata
.into_iter()
.map(|(tag, bytes)| {
let chain_tags = bytes.unroll(&tag.as_ref());
.map(|(tag, metadata)| {
let chain_tags = metadata.unroll(&tag.as_ref());
(tag, chain_tags)
})
.collect::<Mm<EntryDxEnc::Tag, ChainDxEnc::Tag>>();
Expand Down Expand Up @@ -450,10 +486,7 @@ mod tests {
use futures::executor::block_on;
use rand::{RngCore, SeedableRng};

use crate::{
dx_enc::{Tag, Vera},
InMemoryDb,
};
use crate::{InMemoryDb, Set, Tag, Vera};

use super::*;

Expand All @@ -466,29 +499,26 @@ mod tests {
/// preserves order but removes duplicates and deleted values.
#[test]
fn decomposition() {
let added_value = vec![
let added_values = vec![
vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
"I am a very long test string".as_bytes().to_vec(),
"I am a second very long test string".as_bytes().to_vec(),
];
let deleted_value = vec![
let deleted_values = vec![
"I am a deleted-only string".as_bytes().to_vec(),
"I am a very long test string".as_bytes().to_vec(),
];

let mut chain = decompose(Operation::Insert, &added_value).unwrap();
chain.extend_from_slice(&decompose(Operation::Insert, &added_value).unwrap());
chain.extend_from_slice(&decompose(Operation::Delete, &deleted_value).unwrap());
let recomposed_value = recompose(&chain).unwrap();
let mut chain = decompose(Operation::Insert, &added_values).unwrap();
chain.extend_from_slice(&decompose(Operation::Insert, &added_values).unwrap());
chain.extend_from_slice(&decompose(Operation::Delete, &deleted_values).unwrap());
let recomposed_values = recompose(&chain).unwrap();

// Assert all elements are recovered, without the duplicated and deleted
// ones.
assert_eq!(recomposed_value.len(), 2);
assert!(added_value.contains(&recomposed_value[0]));
assert!(added_value.contains(&recomposed_value[1]));
// Assert the order is preserved.
assert_eq!(recomposed_value[0], added_value[0]);
assert_eq!(recomposed_value[1], added_value[2]);
// ones, and that the order is preserved.
assert_eq!(recomposed_values.len(), 2);
assert_eq!(recomposed_values[0], added_values[0]);
assert_eq!(recomposed_values[1], added_values[2]);
}

/// Checks the insert, delete and fetch work correctly in a sequential
Expand Down Expand Up @@ -664,4 +694,40 @@ mod tests {
block_on(findex.search(inserted_mm.keys().copied().collect::<Set<Tag>>())).unwrap();
assert_eq!(inserted_mm, fetched_mm);
}

#[test]
fn test_compact() {
let mut rng = CsRng::from_entropy();
let seed = Secret::<32>::random(&mut rng);
let db = (InMemoryDb::default(), InMemoryDb::default());
let findex = Findex::<
{ Tag::LENGTH },
Tag,
Vera<METADATA_LENGTH, InMemoryDb, Metadata>,
Vera<LINK_LENGTH, InMemoryDb, Link>,
>::setup(&*seed, db.clone())
.unwrap();

let tag = Tag::random(&mut rng);
let added_values = vec![
vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
"I am a very long test string".as_bytes().to_vec(),
"I am a second very long test string".as_bytes().to_vec(),
];
let deleted_values = vec![
"I am a deleted-only string".as_bytes().to_vec(),
"I am a very long test string".as_bytes().to_vec(),
];

block_on(findex.insert(Mm::from_iter([(tag.clone(), added_values.clone())]))).unwrap();
block_on(findex.insert(Mm::from_iter([(tag.clone(), deleted_values)]))).unwrap();

let chain_len_pre = db.1.len();
let fetched_mm_pre = block_on(findex.search(Set::from_iter([tag]))).unwrap();
block_on(findex.compact()).unwrap();
let fetched_mm_post = block_on(findex.search(Set::from_iter([tag]))).unwrap();
let chain_len_post = db.1.len();
assert_eq!(fetched_mm_pre, fetched_mm_post);
assert!(chain_len_post < chain_len_pre);
}
}
18 changes: 3 additions & 15 deletions src/mm_enc/structs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,15 @@ impl<Tag: Hash + PartialEq + Eq + Clone, Item: Clone> Clone for Mm<Tag, Item> {

impl<Tag: Hash + PartialEq + Eq + Display, Item: Display> Display for Mm<Tag, Item> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Multi-Map: {{")?;
writeln!(f, "Multi-Map: {{")?;
for (tag, items) in self.iter() {
writeln!(f, " '{}': [", tag)?;
for i in items {
writeln!(f, " '{}',", i)?;
}
writeln!(f, " ],")?;
}
writeln!(f, "}}")
write!(f, "}}")
}
}

Expand Down Expand Up @@ -161,8 +161,7 @@ impl Display for Metadata {

pub type Block = [u8; BLOCK_LENGTH];

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Link([u8; LINK_LENGTH]);
impl_byte_array!(Link, LINK_LENGTH, "Link");

impl Link {
pub fn new() -> Self {
Expand Down Expand Up @@ -204,17 +203,6 @@ impl Link {
}
}

impl From<[u8; LINK_LENGTH]> for Link {
fn from(bytes: [u8; LINK_LENGTH]) -> Self {
Self(bytes)
}
}

impl From<Link> for [u8; LINK_LENGTH] {
fn from(link: Link) -> Self {
link.0
}
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Flag {
Expand Down

0 comments on commit 6605584

Please sign in to comment.