Skip to content

Commit

Permalink
Fix HAMT PartialEq issue
Browse files Browse the repository at this point in the history
  • Loading branch information
appcypher committed Dec 8, 2022
1 parent 5b2dad0 commit c4978a5
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 24 deletions.
26 changes: 8 additions & 18 deletions wnfs/src/private/forest.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
use super::{diff, hamt::Hamt, namefilter::Namefilter, ChangeType, Key, PrivateNode, PrivateRef};
use crate::{BlockStore, HashOutput, Hasher, Link};
use super::{hamt::Hamt, namefilter::Namefilter, ChangeType, Key, PrivateNode, PrivateRef};
use crate::{BlockStore, HashOutput, Hasher};
use anyhow::Result;
use libipld::Cid;
use log::debug;
use rand_core::RngCore;
use sha3::Sha3_256;
use std::{collections::BTreeSet, fmt, rc::Rc};

//--------------------------------------------------------------------------------------------------
Expand All @@ -29,7 +28,7 @@ use std::{collections::BTreeSet, fmt, rc::Rc};
/// println!("{:?}", forest);
/// ```
// TODO(appcypher): Change Cid to PrivateLink<PrivateNode>.
pub type PrivateForest<H = Sha3_256> = Hamt<Namefilter, BTreeSet<Cid>, H>;
pub type PrivateForest = Hamt<Namefilter, BTreeSet<Cid>>;

//--------------------------------------------------------------------------------------------------
// Implementations
Expand Down Expand Up @@ -296,19 +295,13 @@ impl PrivateForest {
}
}

impl<H> PrivateForest<H>
impl<H> Hamt<Namefilter, BTreeSet<Cid>, H>
where
H: Hasher + fmt::Debug + Clone + 'static,
{
/// TODO(appcypher): Add docs.
pub async fn merge<B: BlockStore>(&self, other: &Self, store: &mut B) -> Result<Self> {
let kv_changes = diff::kv_diff(
Link::from(Rc::clone(&self.root)),
Link::from(Rc::clone(&other.root)),
None,
store,
)
.await?;
let kv_changes = self.kv_diff(other, None, store).await?;

let mut merge_node = Rc::clone(&self.root);
for change in kv_changes {
Expand All @@ -334,6 +327,7 @@ where
.cloned()
.unwrap_or_default(),
);

merge_node = merge_node.set(change.key, merge_values, store).await?;
}
_ => (),
Expand Down Expand Up @@ -362,8 +356,6 @@ mod hamt_store_tests {
use std::rc::Rc;

mod helper {
use std::collections::BTreeSet;

use crate::{utils, HashOutput, Hasher, Namefilter};
use lazy_static::lazy_static;
use libipld::{Cid, Multihash};
Expand Down Expand Up @@ -585,8 +577,8 @@ mod hamt_store_tests {
.unwrap();
}

let main_forest = PrivateForest::with_root(main_node);
let other_forest = PrivateForest::with_root(other_node);
let main_forest = Hamt::<Namefilter, BTreeSet<Cid>, _>::with_root(main_node);
let other_forest = Hamt::<Namefilter, BTreeSet<Cid>, _>::with_root(other_node);

let merge_forest = main_forest.merge(&other_forest, store).await.unwrap();

Expand All @@ -600,7 +592,5 @@ mod hamt_store_tests {
assert!(retrieved.unwrap().contains(&HASH_KV_PAIRS[1].2));
}
}

println!("Merge forest: {:#?}", merge_forest);
}
}
73 changes: 67 additions & 6 deletions wnfs/src/private/hamt/hamt.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::{Node, HAMT_VERSION};
use crate::{AsyncSerialize, BlockStore, Hasher};
use super::{diff, KeyValueChange, Node, NodeChange, HAMT_VERSION};
use crate::{AsyncSerialize, BlockStore, Hasher, Link};
use anyhow::Result;
use async_trait::async_trait;
use libipld::{serde as ipld_serde, Ipld};
Expand All @@ -10,7 +10,7 @@ use serde::{
Deserialize, Deserializer, Serialize, Serializer,
};
use sha3::Sha3_256;
use std::{collections::BTreeMap, rc::Rc, str::FromStr};
use std::{collections::BTreeMap, fmt, hash::Hash, rc::Rc, str::FromStr};

//--------------------------------------------------------------------------------------------------
// Type Definitions
Expand All @@ -29,7 +29,7 @@ use std::{collections::BTreeMap, rc::Rc, str::FromStr};
/// let hamt = Hamt::<String, usize>::new();
/// println!("HAMT: {:?}", hamt);
/// ```
#[derive(Debug, Clone, PartialEq)]
#[derive(Debug, Clone)]
pub struct Hamt<K, V, H = Sha3_256>
where
H: Hasher,
Expand Down Expand Up @@ -78,6 +78,56 @@ impl<K, V, H: Hasher> Hamt<K, V, H> {
}
}

/// TODO(appcypher): Add docs.
pub async fn node_diff<B: BlockStore>(
&self,
other: &Self,
depth: Option<u8>,
store: &mut B,
) -> Result<Vec<NodeChange>>
where
K: DeserializeOwned + Clone + fmt::Debug + Eq + Hash + AsRef<[u8]>,
V: DeserializeOwned + Clone + fmt::Debug + Eq,
H: Clone + fmt::Debug + 'static,
{
if self.version == other.version {
return diff::node_diff(
Link::from(Rc::clone(&self.root)),
Link::from(Rc::clone(&other.root)),
depth,
store,
)
.await;
}

Ok(vec![])
}

/// TODO(appcypher): Add docs.
pub async fn kv_diff<B: BlockStore>(
&self,
other: &Self,
depth: Option<u8>,
store: &mut B,
) -> Result<Vec<KeyValueChange<K, V>>>
where
K: DeserializeOwned + Clone + fmt::Debug + Eq + Hash + AsRef<[u8]>,
V: DeserializeOwned + Clone + fmt::Debug + Eq,
H: Clone + fmt::Debug + 'static,
{
if self.version == other.version {
return diff::kv_diff(
Link::from(Rc::clone(&self.root)),
Link::from(Rc::clone(&other.root)),
depth,
store,
)
.await;
}

Ok(vec![])
}

async fn to_ipld<B: BlockStore + ?Sized>(&self, store: &mut B) -> Result<Ipld>
where
K: Serialize,
Expand Down Expand Up @@ -155,6 +205,17 @@ impl<K, V, H: Hasher> Default for Hamt<K, V, H> {
}
}

impl<K, V, H> PartialEq for Hamt<K, V, H>
where
K: PartialEq,
V: PartialEq,
H: Hasher,
{
fn eq(&self, other: &Self) -> bool {
self.root == other.root && self.version == other.version
}
}

//--------------------------------------------------------------------------------------------------
// Tests
//--------------------------------------------------------------------------------------------------
Expand All @@ -171,8 +232,8 @@ mod hamt_tests {
let hamt: Hamt<String, i32> = Hamt::with_root(root);

let encoded_hamt = dagcbor::async_encode(&hamt, store).await.unwrap();
let _decoded_hamt = dagcbor::decode::<Hamt<String, i32>>(encoded_hamt.as_ref()).unwrap();
let decoded_hamt = dagcbor::decode::<Hamt<String, i32>>(encoded_hamt.as_ref()).unwrap();

// assert_eq!(hamt, decoded_hamt);
assert_eq!(hamt, decoded_hamt);
}
}

0 comments on commit c4978a5

Please sign in to comment.