Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
fominok committed Nov 1, 2024
1 parent e8385ae commit 4af11cf
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 23 deletions.
1 change: 1 addition & 0 deletions grovedb/src/batch/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1315,6 +1315,7 @@ where
Element::Reference(path_reference, element_max_reference_hop, _)
| Element::BidirectionalReference(
path_reference,
_,
element_max_reference_hop,
..,
) => {
Expand Down
7 changes: 7 additions & 0 deletions grovedb/src/debugger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,7 @@ fn element_to_grovedbg(element: crate::Element) -> grovedbg_types::Element {
| crate::Element::BidirectionalReference(
ReferencePathType::AbsolutePathReference(path),
_,
_,
element_flags,
) => grovedbg_types::Element::Reference(grovedbg_types::Reference::AbsolutePathReference {
path,
Expand All @@ -551,6 +552,7 @@ fn element_to_grovedbg(element: crate::Element) -> grovedbg_types::Element {
| crate::Element::BidirectionalReference(
ReferencePathType::UpstreamRootHeightReference(n_keep, path_append),
_,
_,
element_flags,
) => grovedbg_types::Element::Reference(
grovedbg_types::Reference::UpstreamRootHeightReference {
Expand All @@ -573,6 +575,7 @@ fn element_to_grovedbg(element: crate::Element) -> grovedbg_types::Element {
path_append,
),
_,
_,
element_flags,
) => grovedbg_types::Element::Reference(
grovedbg_types::Reference::UpstreamRootHeightWithParentPathAdditionReference {
Expand All @@ -589,6 +592,7 @@ fn element_to_grovedbg(element: crate::Element) -> grovedbg_types::Element {
| crate::Element::BidirectionalReference(
ReferencePathType::UpstreamFromElementHeightReference(n_remove, path_append),
_,
_,
element_flags,
) => grovedbg_types::Element::Reference(
grovedbg_types::Reference::UpstreamFromElementHeightReference {
Expand All @@ -605,6 +609,7 @@ fn element_to_grovedbg(element: crate::Element) -> grovedbg_types::Element {
| crate::Element::BidirectionalReference(
ReferencePathType::CousinReference(swap_parent),
_,
_,
element_flags,
) => grovedbg_types::Element::Reference(grovedbg_types::Reference::CousinReference {
swap_parent,
Expand All @@ -618,6 +623,7 @@ fn element_to_grovedbg(element: crate::Element) -> grovedbg_types::Element {
| crate::Element::BidirectionalReference(
ReferencePathType::RemovedCousinReference(swap_parent),
_,
_,
element_flags,
) => {
grovedbg_types::Element::Reference(grovedbg_types::Reference::RemovedCousinReference {
Expand All @@ -633,6 +639,7 @@ fn element_to_grovedbg(element: crate::Element) -> grovedbg_types::Element {
| crate::Element::BidirectionalReference(
ReferencePathType::SiblingReference(sibling_key),
_,
_,
element_flags,
) => grovedbg_types::Element::Reference(grovedbg_types::Reference::SiblingReference {
sibling_key,
Expand Down
8 changes: 4 additions & 4 deletions grovedb/src/element/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ impl Element {
| Element::SumItem(_, flags)
| Element::ItemWithBackwardsReferences(_, _, flags)
| Element::SumItemWithBackwardsReferences(_, _, flags)
| Element::BidirectionalReference(_, _, flags) => flags,
| Element::BidirectionalReference(_, _, _, flags) => flags,
}
}

Expand All @@ -180,7 +180,7 @@ impl Element {
| Element::SumItem(_, flags)
| Element::ItemWithBackwardsReferences(_, _, flags)
| Element::SumItemWithBackwardsReferences(_, _, flags)
| Element::BidirectionalReference(_, _, flags) => flags,
| Element::BidirectionalReference(_, _, _, flags) => flags,
}
}

Expand All @@ -195,7 +195,7 @@ impl Element {
| Element::SumItem(_, flags)
| Element::ItemWithBackwardsReferences(_, _, flags)
| Element::SumItemWithBackwardsReferences(_, _, flags)
| Element::BidirectionalReference(_, _, flags) => flags,
| Element::BidirectionalReference(_, _, _, flags) => flags,
}
}

Expand All @@ -210,7 +210,7 @@ impl Element {
| Element::SumItem(_, flags)
| Element::ItemWithBackwardsReferences(_, _, flags)
| Element::SumItemWithBackwardsReferences(_, _, flags)
| Element::BidirectionalReference(_, _, flags) => *flags = new_flags,
| Element::BidirectionalReference(_, _, _, flags) => *flags = new_flags,
}
}

Expand Down
51 changes: 39 additions & 12 deletions grovedb/src/element/insert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@ use grovedb_version::{
};
use integer_encoding::VarInt;

use crate::{reference_path::ReferencePathType, Element, Error, Hash};

use super::CascadeOnUpdate;
use crate::{reference_path::ReferencePathType, Element, Error, Hash};

impl Element {
#[cfg(feature = "full")]
Expand Down Expand Up @@ -468,19 +467,47 @@ impl Element {

/// Adds info on reference that points to this element.
fn referenced_from(

Check warning on line 469 in grovedb/src/element/insert.rs

View workflow job for this annotation

GitHub Actions / clippy

method `referenced_from` is never used

warning: method `referenced_from` is never used --> grovedb/src/element/insert.rs:469:8 | 18 | impl Element { | ------------ method in this implementation ... 469 | fn referenced_from( | ^^^^^^^^^^^^^^^
&mut self,
mut self,
reference: ReferencePathType,
cascade_on_update: CascadeOnUpdate,
) -> Result<(), Error> {
) -> Result<Self, Error> {
match self {
Element::Item(_, _) => todo!(),
Element::ItemWithBackwardsReferences(_, _, _) => todo!(),
Element::Reference(_, _, _) => todo!(),
Element::BidirectionalReference(_, _, _) => todo!(),
Element::SumItem(_, _) => todo!(),
Element::SumItemWithBackwardsReferences(_, _, _) => todo!(),
Element::Tree(_, _) => todo!(),
Element::SumTree(_, _, _) => todo!(),
Element::Item(data, flags) => Ok(Element::ItemWithBackwardsReferences(
data,
vec![(reference, cascade_on_update)],
flags,
)),
Element::ItemWithBackwardsReferences(_, ref mut backward_references, _) => {
backward_references.push((reference, cascade_on_update));
Ok(self)
}
Element::Reference(reference_path, max_hops, flags) => {
Ok(Element::BidirectionalReference(
reference_path,
vec![(reference, cascade_on_update)],
max_hops,
flags,
))
}
Element::BidirectionalReference(_, ref mut backward_references, ..) => {
backward_references.push((reference, cascade_on_update));
Ok(self)
}
Element::SumItem(value, flags) => Ok(Element::SumItemWithBackwardsReferences(
value,
vec![(reference, cascade_on_update)],
flags,
)),
Element::SumItemWithBackwardsReferences(_, ref mut backward_references, _) => {
backward_references.push((reference, cascade_on_update));
Ok(self)
}
Element::Tree(..) => Err(Error::NotSupported(
"Cannot add references pointing to subtrees".to_owned(),
)),
Element::SumTree(..) => Err(Error::NotSupported(
"Cannot add references pointing to sumtrees".to_owned(),
)),
}
}
}
Expand Down
10 changes: 8 additions & 2 deletions grovedb/src/element/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,12 @@ pub enum Element {
/// nodes
SumTree(Option<Vec<u8>>, SumValue, Option<ElementFlags>),
/// A reference to an object by its path
BidirectionalReference(ReferencePathType, MaxReferenceHop, Option<ElementFlags>),
BidirectionalReference(
ReferencePathType,
Vec<(ReferencePathType, CascadeOnUpdate)>,
MaxReferenceHop,
Option<ElementFlags>,
),
/// An ordinary value that has a backwards reference
ItemWithBackwardsReferences(
Vec<u8>,
Expand Down Expand Up @@ -130,7 +135,8 @@ impl fmt::Display for Element {
.map_or(String::new(), |f| format!(", flags: {:?}", f))
)
}
Element::BidirectionalReference(path, max_hop, flags) => {
Element::BidirectionalReference(path, backward_references, max_hop, flags) => {

Check warning on line 138 in grovedb/src/element/mod.rs

View workflow job for this annotation

GitHub Actions / clippy

unused variable: `backward_references`

warning: unused variable: `backward_references` --> grovedb/src/element/mod.rs:138:51 | 138 | Element::BidirectionalReference(path, backward_references, max_hop, flags) => { | ^^^^^^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_backward_references` | = note: `#[warn(unused_variables)]` on by default
// TODO: print something on backward_references
write!(
f,
"BidirectionalReference({}, max_hop: {}{})",
Expand Down
9 changes: 5 additions & 4 deletions grovedb/src/element/serialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ impl Element {

#[cfg(feature = "full")]
/// Serializes Element without including backreferences.
/// This allows for identical serialization regardless of whether the item is referenced or not.
/// This allows for identical serialization regardless of whether the item
/// is referenced or not.
pub(crate) fn serialize_for_value_hash(
&self,
grove_version: &GroveVersion,
Expand Down Expand Up @@ -192,8 +193,8 @@ mod tests {
}
}

/// Wrapper type to alter [Element]'s bincode serialization for variants with backward references,
/// practically ignoring that part.
/// Wrapper type to alter [Element]'s bincode serialization for variants with
/// backward references, practically ignoring that part.
struct SerializeElementData<'a>(&'a Element);

impl bincode::Encode for SerializeElementData<'_> {
Expand All @@ -209,7 +210,7 @@ impl bincode::Encode for SerializeElementData<'_> {
Ok(())
}
Element::Reference(ref_path, max_hops, flags)
| Element::BidirectionalReference(ref_path, max_hops, flags) => {
| Element::BidirectionalReference(ref_path, _, max_hops, flags) => {
<u32 as bincode::Encode>::encode(&(1u32), encoder)?;
bincode::Encode::encode(ref_path, encoder)?;
bincode::Encode::encode(max_hops, encoder)?;
Expand Down
27 changes: 26 additions & 1 deletion grovedb/src/operations/insert/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,12 @@ impl GroveDb {
}

match element {
Element::Reference(ref reference_path, ..) => {
Element::Reference(ref reference_path, ..)
| Element::BidirectionalReference(ref reference_path, ..) => {
// TODO: 1. turn referenced value into a backreference kind
// 2. if referencing another reference first, that one shall become
// bidirectional, the rest shall be bidirectional already

let path = path.to_vec(); // TODO: need for support for references in path library
let reference_path = cost_return_on_error!(
&mut cost,
Expand All @@ -239,6 +244,16 @@ impl GroveDb {
)
);

if matches!(
referenced_item,
Element::Tree(_, _) | Element::SumTree(_, _, _)
) {
return Err(Error::NotSupported(
"References cannot point to subtrees".to_owned(),
))
.wrap_with_cost(cost);
}

let referenced_element_value_hash =
cost_return_on_error!(&mut cost, referenced_item.value_hash(grove_version));

Expand Down Expand Up @@ -273,6 +288,16 @@ impl GroveDb {
}
}
_ => {
// TODO: Check if overwriting an backreference-flavored item:
// 1. Item/SumItem -- update reference chains
// 2. Replace bidirectional reference with item: Previous in chain --
// update hashes Next in chain reference -- make one directional
// reference if the last one Next is an actual item -- downgrade from
// backreferenced-flavor if the last one
// 3. Replace bidirectional reference with another reference: Old target
// reference becomes one directional if the last one Old target item is
// downgraded if the last one Update previous in chain with a new
// target
cost_return_on_error!(
&mut cost,
element.insert(
Expand Down

0 comments on commit 4af11cf

Please sign in to comment.