Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
fominok committed Dec 6, 2024
1 parent fda42a1 commit 919ed0e
Show file tree
Hide file tree
Showing 6 changed files with 195 additions and 117 deletions.
24 changes: 15 additions & 9 deletions grovedb/src/merk_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use std::{

use grovedb_costs::{cost_return_on_error, cost_return_on_error_no_add, CostResult, CostsExt};

Check warning on line 9 in grovedb/src/merk_cache.rs

View workflow job for this annotation

GitHub Actions / clippy

unused import: `cost_return_on_error_no_add`

warning: unused import: `cost_return_on_error_no_add` --> grovedb/src/merk_cache.rs:9:43 | 9 | use grovedb_costs::{cost_return_on_error, cost_return_on_error_no_add, CostResult, CostsExt}; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `#[warn(unused_imports)]` on by default
use grovedb_merk::Merk;
use grovedb_path::SubtreePath;
use grovedb_path::{SubtreePath, SubtreePathBuilder};

Check warning on line 11 in grovedb/src/merk_cache.rs

View workflow job for this annotation

GitHub Actions / clippy

unused import: `SubtreePath`

warning: unused import: `SubtreePath` --> grovedb/src/merk_cache.rs:11:20 | 11 | use grovedb_path::{SubtreePath, SubtreePathBuilder}; | ^^^^^^^^^^^
use grovedb_storage::{
rocksdb_storage::{PrefixedRocksDbTransactionContext, RocksDbStorage},

Check warning on line 13 in grovedb/src/merk_cache.rs

View workflow job for this annotation

GitHub Actions / clippy

unused import: `RocksDbStorage`

warning: unused import: `RocksDbStorage` --> grovedb/src/merk_cache.rs:13:58 | 13 | rocksdb_storage::{PrefixedRocksDbTransactionContext, RocksDbStorage}, | ^^^^^^^^^^^^^^
StorageBatch,
Expand All @@ -25,7 +25,7 @@ pub(crate) struct MerkCache<'db, 'b, B: AsRef<[u8]>> {
version: &'db GroveVersion,
batch: Box<StorageBatch>,
tx: &'db Transaction<'db>,
merks: UnsafeCell<BTreeMap<SubtreePath<'b, B>, Box<(Cell<bool>, TxMerk<'db>)>>>,
merks: UnsafeCell<BTreeMap<SubtreePathBuilder<'b, B>, Box<(Cell<bool>, TxMerk<'db>)>>>,

Check warning on line 28 in grovedb/src/merk_cache.rs

View workflow job for this annotation

GitHub Actions / clippy

very complex type used. Consider factoring parts into `type` definitions

warning: very complex type used. Consider factoring parts into `type` definitions --> grovedb/src/merk_cache.rs:28:12 | 28 | merks: UnsafeCell<BTreeMap<SubtreePathBuilder<'b, B>, Box<(Cell<bool>, TxMerk<'db>)>>>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#type_complexity = note: `#[warn(clippy::type_complexity)]` on by default
}

impl<'db, 'b, B: AsRef<[u8]>> MerkCache<'db, 'b, B> {
Expand All @@ -51,7 +51,7 @@ impl<'db, 'b, B: AsRef<[u8]>> MerkCache<'db, 'b, B> {
/// shall reach end of the scope or to be `drop`ped manually.
pub(crate) fn get_merk<'c>(
&'c self,
path: SubtreePath<'b, B>,
path: SubtreePathBuilder<'b, B>,
) -> CostResult<MerkHandle<'db, 'c>, Error> {
let mut cost = Default::default();

Expand All @@ -62,13 +62,13 @@ impl<'db, 'b, B: AsRef<[u8]>> MerkCache<'db, 'b, B> {
.as_mut()
.expect("`UnsafeCell` is never null")
}
.entry(path.clone())
.entry(path)
{
Entry::Vacant(e) => {
let merk = cost_return_on_error!(
&mut cost,
self.db.open_transactional_merk_at_path(
e.key().clone(),
e.key().into(),
self.tx,
// SAFETY: batch is allocated on the heap and we use only shared
// references, so as long as the `Box` allocation
Expand Down Expand Up @@ -149,7 +149,7 @@ impl<'db, 'b, B: AsRef<[u8]>> MerkCache<'db, 'b, B> {
// path's first.
while let Some((path, flag_and_merk)) = self.merks.get_mut().pop_first() {
let merk = flag_and_merk.1;
if let Some((parent_path, parent_key)) = path.derive_parent() {
if let Some((parent_path, parent_key)) = path.derive_parent_owned() {
let mut parent_merk = cost_return_on_error!(&mut cost, self.get_merk(parent_path));

let (root_hash, root_key, sum) = cost_return_on_error!(
Expand Down Expand Up @@ -221,8 +221,14 @@ mod tests {

let cache = MerkCache::new(&db, &tx, version);

cache.get_merk(SubtreePath::empty()).unwrap().unwrap();
cache.get_merk(SubtreePath::empty()).unwrap().unwrap();
cache
.get_merk(SubtreePath::empty().derive_owned())
.unwrap()
.unwrap();
cache
.get_merk(SubtreePath::empty().derive_owned())
.unwrap()
.unwrap();
}

#[test]
Expand Down Expand Up @@ -251,7 +257,7 @@ mod tests {

let cache = MerkCache::new(&db, &tx, version);

let mut merk = cache.get_merk(path).unwrap().unwrap();
let mut merk = cache.get_merk(path.derive_owned()).unwrap().unwrap();

item.insert(&mut merk, b"k1", None, &version)
.unwrap()
Expand Down
120 changes: 32 additions & 88 deletions grovedb/src/operations/insert/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ use grovedb_version::{
};

use crate::{
reference_path::path_from_reference_path_type, util::TxRef, Element, Error, GroveDb,
Transaction, TransactionArg,
merk_cache::MerkCache, reference_path::path_from_reference_path_type, util::TxRef, Element,
Error, GroveDb, Transaction, TransactionArg,

Check warning on line 17 in grovedb/src/operations/insert/mod.rs

View workflow job for this annotation

GitHub Actions / clippy

unused import: `Transaction`

warning: unused import: `Transaction` --> grovedb/src/operations/insert/mod.rs:17:21 | 17 | Error, GroveDb, Transaction, TransactionArg, | ^^^^^^^^^^^
};
#[derive(Clone)]
/// Insert options
Expand Down Expand Up @@ -70,94 +70,43 @@ impl GroveDb {
grove_version.grovedb_versions.operations.insert.insert
);

let subtree_path: SubtreePath<B> = path.into();
let batch = StorageBatch::new();

let tx = TxRef::new(&self.db, transaction);

let collect_costs = self.insert_on_transaction(
subtree_path,
key,
element,
options.unwrap_or_default(),
tx.as_ref(),
&batch,
grove_version,
);

collect_costs.flat_map_ok(|_| {
self.db
.commit_multi_context_batch(batch, Some(tx.as_ref()))
.map_err(Into::into)
.map_ok(|_| tx.commit_local())
.flatten()
})
}

fn insert_on_transaction<'db, 'b, B: AsRef<[u8]>>(
&self,
path: SubtreePath<'b, B>,
key: &[u8],
element: Element,
options: InsertOptions,
transaction: &'db Transaction,
batch: &StorageBatch,
grove_version: &GroveVersion,
) -> CostResult<(), Error> {
check_grovedb_v0_with_cost!(
"insert_on_transaction",
grove_version
.grovedb_versions
.operations
.insert
.insert_on_transaction
);

let mut cost = OperationCost::default();
let merk_cache = MerkCache::new(&self, tx.as_ref(), grove_version);

Check warning on line 75 in grovedb/src/operations/insert/mod.rs

View workflow job for this annotation

GitHub Actions / clippy

this expression creates a reference which is immediately dereferenced by the compiler

warning: this expression creates a reference which is immediately dereferenced by the compiler --> grovedb/src/operations/insert/mod.rs:75:41 | 75 | let merk_cache = MerkCache::new(&self, tx.as_ref(), grove_version); | ^^^^^ help: change this to: `self` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow

let mut merk_cache: HashMap<SubtreePath<'b, B>, Merk<PrefixedRocksDbTransactionContext>> =
HashMap::default();

let merk = cost_return_on_error!(
cost_return_on_error!(
&mut cost,
self.add_element_on_transaction(
path.clone(),
path.into(),
key,
element,
options,
transaction,
batch,
grove_version
)
);
merk_cache.insert(path.clone(), merk);
cost_return_on_error!(
&mut cost,
self.propagate_changes_with_transaction(
merk_cache,
path,
transaction,
batch,
options.unwrap_or_default(),
&merk_cache,
grove_version
)
);

Ok(()).wrap_with_cost(cost)
let batch = cost_return_on_error!(&mut cost, merk_cache.into_batch());
self.db
.commit_multi_context_batch(*batch, Some(tx.as_ref()))
.map_err(Into::into)
.map_ok(|_| tx.commit_local())
.flatten()
.add_cost(cost)
}

/// Add subtree to another subtree.
/// We want to add a new empty merk to another merk at a key
/// first make sure other merk exist
/// if it exists, then create merk to be inserted, and get root hash
/// we only care about root hash of merk to be inserted
fn add_element_on_transaction<'db, B: AsRef<[u8]>>(
fn add_element_on_transaction<'db, 'b, B: AsRef<[u8]>>(
&'db self,
path: SubtreePath<B>,
path: SubtreePath<'b, B>,
key: &[u8],
element: Element,
options: InsertOptions,
transaction: &'db Transaction,
batch: &'db StorageBatch,
merk_cache: &MerkCache<'db, 'b, B>,
grove_version: &GroveVersion,
) -> CostResult<Merk<PrefixedRocksDbTransactionContext<'db>>, Error> {
check_grovedb_v0_with_cost!(
Expand All @@ -171,17 +120,10 @@ impl GroveDb {

let mut cost = OperationCost::default();

let mut subtree_to_insert_into = cost_return_on_error!(
&mut cost,
self.open_transactional_merk_at_path(
path.clone(),
transaction,
Some(batch),
grove_version
)
);
// if we don't allow a tree override then we should check
let mut subtree_to_insert_into =
cost_return_on_error!(&mut cost, merk_cache.get_merk(path.derive_owned()));

// if we don't allow a tree override then we should check
if options.checks_for_override() {
let maybe_element_bytes = cost_return_on_error!(
&mut cost,
Expand Down Expand Up @@ -229,15 +171,16 @@ impl GroveDb {
.wrap_with_cost(OperationCost::default())
);

let referenced_item = cost_return_on_error!(
&mut cost,
self.follow_reference(
reference_path.as_slice().into(),
false,
transaction,
grove_version
)
);
let referenced_item: Element = todo!();

Check warning on line 174 in grovedb/src/operations/insert/mod.rs

View workflow job for this annotation

GitHub Actions / clippy

unused variable: `referenced_item`

warning: unused variable: `referenced_item` --> grovedb/src/operations/insert/mod.rs:174:21 | 174 | let referenced_item: Element = todo!(); | ^^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_referenced_item`
// cost_return_on_error!(
// &mut cost,
// self.follow_reference(
// reference_path.as_slice().into(),
// false,
// transaction,
// grove_version
// )
// );

if matches!(
referenced_item,
Expand Down Expand Up @@ -295,7 +238,8 @@ impl GroveDb {
}
}

Ok(subtree_to_insert_into).wrap_with_cost(cost)
// Ok(subtree_to_insert_into).wrap_with_cost(cost)
todo!()
}

/// Inserts an element at the specified path and key if it does not already
Expand Down
5 changes: 4 additions & 1 deletion grovedb/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use grovedb_storage::{
use grovedb_version::version::GroveVersion;
use grovedb_visualize::DebugByteVectors;

use crate::{Element, Error, Transaction, TransactionArg};
use crate::{merk_cache::MerkCache, Element, Error, Transaction, TransactionArg};

Check warning on line 11 in grovedb/src/util.rs

View workflow job for this annotation

GitHub Actions / clippy

unused import: `merk_cache::MerkCache`

warning: unused import: `merk_cache::MerkCache` --> grovedb/src/util.rs:11:13 | 11 | use crate::{merk_cache::MerkCache, Element, Error, Transaction, TransactionArg}; | ^^^^^^^^^^^^^^^^^^^^^

pub(crate) enum TxRef<'a, 'db: 'a> {
Owned(Transaction<'db>),
Expand Down Expand Up @@ -104,3 +104,6 @@ where
.add_cost(cost)
}
}

// pub(crate) fn follow_reference<'db, 'b, B>(merk_cache: &MerkCache<'db, 'b,
// B>, path: )
28 changes: 28 additions & 0 deletions path/src/subtree_path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,25 @@ where
}
}

impl<'bl, 'br, BL, BR> PartialOrd<SubtreePathBuilder<'br, BR>> for SubtreePathBuilder<'bl, BL>

Check warning on line 108 in path/src/subtree_path.rs

View workflow job for this annotation

GitHub Actions / clippy

the following explicit lifetimes could be elided: 'bl

warning: the following explicit lifetimes could be elided: 'bl --> path/src/subtree_path.rs:108:6 | 108 | impl<'bl, 'br, BL, BR> PartialOrd<SubtreePathBuilder<'br, BR>> for SubtreePathBuilder<'bl, BL> | ^^^ ^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes help: elide the lifetimes | 108 - impl<'bl, 'br, BL, BR> PartialOrd<SubtreePathBuilder<'br, BR>> for SubtreePathBuilder<'bl, BL> 108 + impl<'br, BL, BR> PartialOrd<SubtreePathBuilder<'br, BR>> for SubtreePathBuilder<'_, BL> |
where
BL: AsRef<[u8]>,
BR: AsRef<[u8]>,
{
fn partial_cmp(&self, other: &SubtreePathBuilder<'br, BR>) -> Option<cmp::Ordering> {
let iter_a = self.reverse_iter();
let iter_b = other.reverse_iter();

Some(
iter_a
.len()
.cmp(&iter_b.len())
.reverse()
.then_with(|| iter_a.cmp(iter_b)),
)
}
}

impl<'bl, 'br, BL, BR> PartialOrd<SubtreePathBuilder<'br, BR>> for SubtreePath<'bl, BL>

Check warning on line 127 in path/src/subtree_path.rs

View workflow job for this annotation

GitHub Actions / clippy

the following explicit lifetimes could be elided: 'bl

warning: the following explicit lifetimes could be elided: 'bl --> path/src/subtree_path.rs:127:6 | 127 | impl<'bl, 'br, BL, BR> PartialOrd<SubtreePathBuilder<'br, BR>> for SubtreePath<'bl, BL> | ^^^ ^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes help: elide the lifetimes | 127 - impl<'bl, 'br, BL, BR> PartialOrd<SubtreePathBuilder<'br, BR>> for SubtreePath<'bl, BL> 127 + impl<'br, BL, BR> PartialOrd<SubtreePathBuilder<'br, BR>> for SubtreePath<'_, BL> |
where
BL: AsRef<[u8]>,
Expand All @@ -124,6 +143,15 @@ where
}
}

impl<'bl, BL> Ord for SubtreePathBuilder<'bl, BL>

Check warning on line 146 in path/src/subtree_path.rs

View workflow job for this annotation

GitHub Actions / clippy

the following explicit lifetimes could be elided: 'bl

warning: the following explicit lifetimes could be elided: 'bl --> path/src/subtree_path.rs:146:6 | 146 | impl<'bl, BL> Ord for SubtreePathBuilder<'bl, BL> | ^^^ ^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes help: elide the lifetimes | 146 - impl<'bl, BL> Ord for SubtreePathBuilder<'bl, BL> 146 + impl<BL> Ord for SubtreePathBuilder<'_, BL> |
where
BL: AsRef<[u8]>,
{
fn cmp(&self, other: &Self) -> cmp::Ordering {
self.partial_cmp(other).expect("order is totally defined")
}
}

impl<'b, B: AsRef<[u8]>> Eq for SubtreePath<'b, B> {}

Check warning on line 155 in path/src/subtree_path.rs

View workflow job for this annotation

GitHub Actions / clippy

the following explicit lifetimes could be elided: 'b

warning: the following explicit lifetimes could be elided: 'b --> path/src/subtree_path.rs:155:6 | 155 | impl<'b, B: AsRef<[u8]>> Eq for SubtreePath<'b, B> {} | ^^ ^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes help: elide the lifetimes | 155 - impl<'b, B: AsRef<[u8]>> Eq for SubtreePath<'b, B> {} 155 + impl<B: AsRef<[u8]>> Eq for SubtreePath<'_, B> {} |

impl<'b, B> From<SubtreePathInner<'b, B>> for SubtreePath<'b, B> {
Expand Down
Loading

0 comments on commit 919ed0e

Please sign in to comment.