Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 1 addition & 12 deletions grovedb/src/operations/get/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -402,18 +402,7 @@ impl GroveDb {
// check_subtree_exists would reject paths through wrapped
// parents — breaking the wrapper-transparency contract.
match element.map(|e| e.into_underlying()) {
Ok(Element::Tree(..))
| Ok(Element::SumTree(..))
| Ok(Element::BigSumTree(..))
| Ok(Element::CountTree(..))
| Ok(Element::CountSumTree(..))
| Ok(Element::ProvableCountTree(..))
| Ok(Element::ProvableCountSumTree(..))
| Ok(Element::ProvableSumTree(..))
| Ok(Element::CommitmentTree(..))
| Ok(Element::MmrTree(..))
| Ok(Element::BulkAppendTree(..))
| Ok(Element::DenseAppendOnlyFixedSizeTree(..)) => Ok(()).wrap_with_cost(cost),
Ok(e) if e.is_any_tree() => Ok(()).wrap_with_cost(cost),
Ok(_) | Err(Error::PathKeyNotFound(_)) => Err(error_fn()).wrap_with_cost(cost),
Err(e) => Err(e).wrap_with_cost(cost),
}
Comment on lines 404 to 408

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💬 Nitpick: Redundant into_underlying() before is_any_tree()

Element::is_any_tree() already invokes self.underlying() internally to look through NonCounted / NotSummed / NotCountedOrSummed wrappers (see grovedb-element/src/element/helpers.rs:323 and :56-63). Calling into_underlying() first re-does that unwrap, and for wrapped variants it performs an owned *inner boxed-element move on every successful subtree check. Since the subsequent arms no longer pattern-match against a specific unwrapped variant, you can pass the element straight to is_any_tree() and let the helper handle wrapper transparency. The comment about looking through NonCounted remains accurate either way.

Suggested change
match element.map(|e| e.into_underlying()) {
Ok(Element::Tree(..))
| Ok(Element::SumTree(..))
| Ok(Element::BigSumTree(..))
| Ok(Element::CountTree(..))
| Ok(Element::CountSumTree(..))
| Ok(Element::ProvableCountTree(..))
| Ok(Element::ProvableCountSumTree(..))
| Ok(Element::ProvableSumTree(..))
| Ok(Element::CommitmentTree(..))
| Ok(Element::MmrTree(..))
| Ok(Element::BulkAppendTree(..))
| Ok(Element::DenseAppendOnlyFixedSizeTree(..)) => Ok(()).wrap_with_cost(cost),
Ok(e) if e.is_any_tree() => Ok(()).wrap_with_cost(cost),
Ok(_) | Err(Error::PathKeyNotFound(_)) => Err(error_fn()).wrap_with_cost(cost),
Err(e) => Err(e).wrap_with_cost(cost),
}
match element {
Ok(ref e) if e.is_any_tree() => Ok(()).wrap_with_cost(cost),
Ok(_) | Err(Error::PathKeyNotFound(_)) => Err(error_fn()).wrap_with_cost(cost),
Err(e) => Err(e).wrap_with_cost(cost),
}

source: ['claude']

Expand Down
46 changes: 46 additions & 0 deletions grovedb/src/tests/is_empty_tree_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,52 @@ mod tests {
assert!(inner_result, "inner tree should be empty");
}

#[test]
fn test_is_empty_tree_on_provable_count_provable_sum_subtree() {
let grove_version = GroveVersion::latest();
let db = make_test_grovedb(grove_version);

db.insert(
[TEST_LEAF].as_ref(),
b"pcps",
Element::empty_provable_count_provable_sum_tree(),
None,
None,
grove_version,
)
.unwrap()
.expect("should insert ProvableCountProvableSumTree");

let empty_result = db
.is_empty_tree([TEST_LEAF, b"pcps"].as_ref(), None, grove_version)
.unwrap()
.expect("should succeed checking empty ProvableCountProvableSumTree");
assert!(
empty_result,
"empty ProvableCountProvableSumTree should be empty"
);

db.insert(
[TEST_LEAF, b"pcps"].as_ref(),
b"item",
Element::new_item(b"value".to_vec()),
None,
None,
grove_version,
)
.unwrap()
.expect("should insert item into ProvableCountProvableSumTree");

let non_empty_result = db
.is_empty_tree([TEST_LEAF, b"pcps"].as_ref(), None, grove_version)
.unwrap()
.expect("should succeed checking non-empty ProvableCountProvableSumTree");
assert!(
!non_empty_result,
"ProvableCountProvableSumTree with items should not be empty"
);
}

#[test]
fn test_is_empty_tree_after_delete() {
let grove_version = GroveVersion::latest();
Expand Down
54 changes: 54 additions & 0 deletions grovedb/src/tests/operations_coverage_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2259,6 +2259,60 @@ mod tests {
);
}

#[test]
fn delete_with_validate_tree_at_path_exists_success_on_pcps_path() {
let grove_version = GroveVersion::latest();
let db = make_test_grovedb(grove_version);

db.insert(
[TEST_LEAF].as_ref(),
b"pcps",
Element::empty_provable_count_provable_sum_tree(),
None,
None,
grove_version,
)
.unwrap()
.expect("should insert ProvableCountProvableSumTree");

db.insert(
[TEST_LEAF, b"pcps"].as_ref(),
b"item_v",
Element::new_item(b"data".to_vec()),
None,
None,
grove_version,
)
.unwrap()
.expect("should insert item into ProvableCountProvableSumTree");

db.delete(
[TEST_LEAF, b"pcps"].as_ref(),
b"item_v",
Some(DeleteOptions {
validate_tree_at_path_exists: true,
..Default::default()
}),
None,
grove_version,
)
.unwrap()
.expect("should delete with path validation through ProvableCountProvableSumTree");

let result = db
.get(
[TEST_LEAF, b"pcps"].as_ref(),
b"item_v",
None,
grove_version,
)
.unwrap();
assert!(
matches!(result, Err(Error::PathKeyNotFound(_))),
"item should be deleted from ProvableCountProvableSumTree"
);
}

#[test]
fn delete_with_sectional_storage_function_with_flags() {
let grove_version = GroveVersion::latest();
Expand Down
Loading