diff --git a/docs/book/src/batch-operations.md b/docs/book/src/batch-operations.md index ae07d7180..596f2e33b 100644 --- a/docs/book/src/batch-operations.md +++ b/docs/book/src/batch-operations.md @@ -44,13 +44,24 @@ pub enum NonMerkTreeMeta { ```rust pub enum SubelementsDeletionBehavior { - DontCheck, // Skip emptiness check; caller guarantees tree is empty - Error, // Return Error::DeletingNonEmptyTree if non-empty - DeleteChildren, // Check, and recursively delete children if non-empty - Skip, // Check, and silently skip deletion if non-empty + DontCheckWithNoCleanup, // Skip emptiness check AND post-apply cleanup; caller guarantees tree is empty + Error, // Return Error::DeletingNonEmptyTree if non-empty + DeleteChildren, // Skip emptiness check, but perform post-apply storage cleanup + Skip, // Check, and silently skip deletion if non-empty } ``` +| Variant | Tree state | Emptiness check | Deletes tree | Storage cleanup | +|---|---|---|---|---| +| `DontCheckWithNoCleanup` | empty | No | Yes | No | +| `DontCheckWithNoCleanup` | non-empty | No | Yes | No | +| `DeleteChildren` | empty | No | Yes | Yes | +| `DeleteChildren` | non-empty | No | Yes | Yes | +| `Error` | empty | Yes | Yes | Yes | +| `Error` | non-empty | Yes | No (returns error) | No | +| `Skip` | empty | Yes | Yes | Yes | +| `Skip` | non-empty | Yes | No (silently skips) | No | + Each operation is wrapped in a `QualifiedGroveDbOp` that includes the path: ```rust diff --git a/docs/book/translations/ar/src/batch-operations.md b/docs/book/translations/ar/src/batch-operations.md index 29fc11766..cdfc91d79 100644 --- a/docs/book/translations/ar/src/batch-operations.md +++ b/docs/book/translations/ar/src/batch-operations.md @@ -44,9 +44,9 @@ pub enum NonMerkTreeMeta { ```rust pub enum SubelementsDeletionBehavior { - DontCheck, // Skip emptiness check; caller guarantees tree is empty + DontCheckWithNoCleanup, // Skip emptiness check AND post-apply cleanup; caller guarantees tree is empty Error, // Return Error::DeletingNonEmptyTree if non-empty - DeleteChildren, // Check, and recursively delete children if non-empty + DeleteChildren, // Skip emptiness check, but perform post-apply storage cleanup Skip, // Check, and silently skip deletion if non-empty } ``` diff --git a/docs/book/translations/cs/src/batch-operations.md b/docs/book/translations/cs/src/batch-operations.md index c9481d25a..6f47130f6 100644 --- a/docs/book/translations/cs/src/batch-operations.md +++ b/docs/book/translations/cs/src/batch-operations.md @@ -44,9 +44,9 @@ pub enum NonMerkTreeMeta { ```rust pub enum SubelementsDeletionBehavior { - DontCheck, // Skip emptiness check; caller guarantees tree is empty + DontCheckWithNoCleanup, // Skip emptiness check AND post-apply cleanup; caller guarantees tree is empty Error, // Return Error::DeletingNonEmptyTree if non-empty - DeleteChildren, // Check, and recursively delete children if non-empty + DeleteChildren, // Skip emptiness check, but perform post-apply storage cleanup Skip, // Check, and silently skip deletion if non-empty } ``` diff --git a/docs/book/translations/de/src/batch-operations.md b/docs/book/translations/de/src/batch-operations.md index eb8a2e144..b7d8cbbcb 100644 --- a/docs/book/translations/de/src/batch-operations.md +++ b/docs/book/translations/de/src/batch-operations.md @@ -44,9 +44,9 @@ pub enum NonMerkTreeMeta { ```rust pub enum SubelementsDeletionBehavior { - DontCheck, // Skip emptiness check; caller guarantees tree is empty + DontCheckWithNoCleanup, // Skip emptiness check AND post-apply cleanup; caller guarantees tree is empty Error, // Return Error::DeletingNonEmptyTree if non-empty - DeleteChildren, // Check, and recursively delete children if non-empty + DeleteChildren, // Skip emptiness check, but perform post-apply storage cleanup Skip, // Check, and silently skip deletion if non-empty } ``` diff --git a/docs/book/translations/es/src/batch-operations.md b/docs/book/translations/es/src/batch-operations.md index 0727ef4fe..d5aeefdd2 100644 --- a/docs/book/translations/es/src/batch-operations.md +++ b/docs/book/translations/es/src/batch-operations.md @@ -44,9 +44,9 @@ pub enum NonMerkTreeMeta { ```rust pub enum SubelementsDeletionBehavior { - DontCheck, // Skip emptiness check; caller guarantees tree is empty + DontCheckWithNoCleanup, // Skip emptiness check AND post-apply cleanup; caller guarantees tree is empty Error, // Return Error::DeletingNonEmptyTree if non-empty - DeleteChildren, // Check, and recursively delete children if non-empty + DeleteChildren, // Skip emptiness check, but perform post-apply storage cleanup Skip, // Check, and silently skip deletion if non-empty } ``` diff --git a/docs/book/translations/fr/src/batch-operations.md b/docs/book/translations/fr/src/batch-operations.md index aaac92436..c1ac59ea5 100644 --- a/docs/book/translations/fr/src/batch-operations.md +++ b/docs/book/translations/fr/src/batch-operations.md @@ -44,9 +44,9 @@ pub enum NonMerkTreeMeta { ```rust pub enum SubelementsDeletionBehavior { - DontCheck, // Skip emptiness check; caller guarantees tree is empty + DontCheckWithNoCleanup, // Skip emptiness check AND post-apply cleanup; caller guarantees tree is empty Error, // Return Error::DeletingNonEmptyTree if non-empty - DeleteChildren, // Check, and recursively delete children if non-empty + DeleteChildren, // Skip emptiness check, but perform post-apply storage cleanup Skip, // Check, and silently skip deletion if non-empty } ``` diff --git a/docs/book/translations/id/src/batch-operations.md b/docs/book/translations/id/src/batch-operations.md index b5998b6f1..835389955 100644 --- a/docs/book/translations/id/src/batch-operations.md +++ b/docs/book/translations/id/src/batch-operations.md @@ -44,9 +44,9 @@ pub enum NonMerkTreeMeta { ```rust pub enum SubelementsDeletionBehavior { - DontCheck, // Skip emptiness check; caller guarantees tree is empty + DontCheckWithNoCleanup, // Skip emptiness check AND post-apply cleanup; caller guarantees tree is empty Error, // Return Error::DeletingNonEmptyTree if non-empty - DeleteChildren, // Check, and recursively delete children if non-empty + DeleteChildren, // Skip emptiness check, but perform post-apply storage cleanup Skip, // Check, and silently skip deletion if non-empty } ``` diff --git a/docs/book/translations/it/src/batch-operations.md b/docs/book/translations/it/src/batch-operations.md index a95551476..9ea6e54af 100644 --- a/docs/book/translations/it/src/batch-operations.md +++ b/docs/book/translations/it/src/batch-operations.md @@ -44,9 +44,9 @@ pub enum NonMerkTreeMeta { ```rust pub enum SubelementsDeletionBehavior { - DontCheck, // Skip emptiness check; caller guarantees tree is empty + DontCheckWithNoCleanup, // Skip emptiness check AND post-apply cleanup; caller guarantees tree is empty Error, // Return Error::DeletingNonEmptyTree if non-empty - DeleteChildren, // Check, and recursively delete children if non-empty + DeleteChildren, // Skip emptiness check, but perform post-apply storage cleanup Skip, // Check, and silently skip deletion if non-empty } ``` diff --git a/docs/book/translations/ja/src/batch-operations.md b/docs/book/translations/ja/src/batch-operations.md index 3d17800b5..59d3201cc 100644 --- a/docs/book/translations/ja/src/batch-operations.md +++ b/docs/book/translations/ja/src/batch-operations.md @@ -44,9 +44,9 @@ pub enum NonMerkTreeMeta { ```rust pub enum SubelementsDeletionBehavior { - DontCheck, // Skip emptiness check; caller guarantees tree is empty + DontCheckWithNoCleanup, // Skip emptiness check AND post-apply cleanup; caller guarantees tree is empty Error, // Return Error::DeletingNonEmptyTree if non-empty - DeleteChildren, // Check, and recursively delete children if non-empty + DeleteChildren, // Skip emptiness check, but perform post-apply storage cleanup Skip, // Check, and silently skip deletion if non-empty } ``` diff --git a/docs/book/translations/ko/src/batch-operations.md b/docs/book/translations/ko/src/batch-operations.md index b1c006ea9..9d5b4ef34 100644 --- a/docs/book/translations/ko/src/batch-operations.md +++ b/docs/book/translations/ko/src/batch-operations.md @@ -44,9 +44,9 @@ pub enum NonMerkTreeMeta { ```rust pub enum SubelementsDeletionBehavior { - DontCheck, // Skip emptiness check; caller guarantees tree is empty + DontCheckWithNoCleanup, // Skip emptiness check AND post-apply cleanup; caller guarantees tree is empty Error, // Return Error::DeletingNonEmptyTree if non-empty - DeleteChildren, // Check, and recursively delete children if non-empty + DeleteChildren, // Skip emptiness check, but perform post-apply storage cleanup Skip, // Check, and silently skip deletion if non-empty } ``` diff --git a/docs/book/translations/pl/src/batch-operations.md b/docs/book/translations/pl/src/batch-operations.md index c3fad9d4f..00457c87a 100644 --- a/docs/book/translations/pl/src/batch-operations.md +++ b/docs/book/translations/pl/src/batch-operations.md @@ -44,9 +44,9 @@ pub enum NonMerkTreeMeta { ```rust pub enum SubelementsDeletionBehavior { - DontCheck, // Skip emptiness check; caller guarantees tree is empty + DontCheckWithNoCleanup, // Skip emptiness check AND post-apply cleanup; caller guarantees tree is empty Error, // Return Error::DeletingNonEmptyTree if non-empty - DeleteChildren, // Check, and recursively delete children if non-empty + DeleteChildren, // Skip emptiness check, but perform post-apply storage cleanup Skip, // Check, and silently skip deletion if non-empty } ``` diff --git a/docs/book/translations/pt/src/batch-operations.md b/docs/book/translations/pt/src/batch-operations.md index d08f6a311..13e99604a 100644 --- a/docs/book/translations/pt/src/batch-operations.md +++ b/docs/book/translations/pt/src/batch-operations.md @@ -44,9 +44,9 @@ pub enum NonMerkTreeMeta { ```rust pub enum SubelementsDeletionBehavior { - DontCheck, // Skip emptiness check; caller guarantees tree is empty + DontCheckWithNoCleanup, // Skip emptiness check AND post-apply cleanup; caller guarantees tree is empty Error, // Return Error::DeletingNonEmptyTree if non-empty - DeleteChildren, // Check, and recursively delete children if non-empty + DeleteChildren, // Skip emptiness check, but perform post-apply storage cleanup Skip, // Check, and silently skip deletion if non-empty } ``` diff --git a/docs/book/translations/ru/src/batch-operations.md b/docs/book/translations/ru/src/batch-operations.md index 2161ad42d..621bc39aa 100644 --- a/docs/book/translations/ru/src/batch-operations.md +++ b/docs/book/translations/ru/src/batch-operations.md @@ -44,9 +44,9 @@ pub enum NonMerkTreeMeta { ```rust pub enum SubelementsDeletionBehavior { - DontCheck, // Skip emptiness check; caller guarantees tree is empty + DontCheckWithNoCleanup, // Skip emptiness check AND post-apply cleanup; caller guarantees tree is empty Error, // Return Error::DeletingNonEmptyTree if non-empty - DeleteChildren, // Check, and recursively delete children if non-empty + DeleteChildren, // Skip emptiness check, but perform post-apply storage cleanup Skip, // Check, and silently skip deletion if non-empty } ``` diff --git a/docs/book/translations/th/src/batch-operations.md b/docs/book/translations/th/src/batch-operations.md index 6977b4cb4..fbec13079 100644 --- a/docs/book/translations/th/src/batch-operations.md +++ b/docs/book/translations/th/src/batch-operations.md @@ -44,9 +44,9 @@ pub enum NonMerkTreeMeta { ```rust pub enum SubelementsDeletionBehavior { - DontCheck, // Skip emptiness check; caller guarantees tree is empty + DontCheckWithNoCleanup, // Skip emptiness check AND post-apply cleanup; caller guarantees tree is empty Error, // Return Error::DeletingNonEmptyTree if non-empty - DeleteChildren, // Check, and recursively delete children if non-empty + DeleteChildren, // Skip emptiness check, but perform post-apply storage cleanup Skip, // Check, and silently skip deletion if non-empty } ``` diff --git a/docs/book/translations/tr/src/batch-operations.md b/docs/book/translations/tr/src/batch-operations.md index 76842c744..fc0450431 100644 --- a/docs/book/translations/tr/src/batch-operations.md +++ b/docs/book/translations/tr/src/batch-operations.md @@ -44,9 +44,9 @@ pub enum NonMerkTreeMeta { ```rust pub enum SubelementsDeletionBehavior { - DontCheck, // Skip emptiness check; caller guarantees tree is empty + DontCheckWithNoCleanup, // Skip emptiness check AND post-apply cleanup; caller guarantees tree is empty Error, // Return Error::DeletingNonEmptyTree if non-empty - DeleteChildren, // Check, and recursively delete children if non-empty + DeleteChildren, // Skip emptiness check, but perform post-apply storage cleanup Skip, // Check, and silently skip deletion if non-empty } ``` diff --git a/docs/book/translations/vi/src/batch-operations.md b/docs/book/translations/vi/src/batch-operations.md index 4a268220e..8a3cba9ed 100644 --- a/docs/book/translations/vi/src/batch-operations.md +++ b/docs/book/translations/vi/src/batch-operations.md @@ -44,9 +44,9 @@ pub enum NonMerkTreeMeta { ```rust pub enum SubelementsDeletionBehavior { - DontCheck, // Skip emptiness check; caller guarantees tree is empty + DontCheckWithNoCleanup, // Skip emptiness check AND post-apply cleanup; caller guarantees tree is empty Error, // Return Error::DeletingNonEmptyTree if non-empty - DeleteChildren, // Check, and recursively delete children if non-empty + DeleteChildren, // Skip emptiness check, but perform post-apply storage cleanup Skip, // Check, and silently skip deletion if non-empty } ``` diff --git a/docs/book/translations/zh/src/batch-operations.md b/docs/book/translations/zh/src/batch-operations.md index 95033ac93..0b826c400 100644 --- a/docs/book/translations/zh/src/batch-operations.md +++ b/docs/book/translations/zh/src/batch-operations.md @@ -44,9 +44,9 @@ pub enum NonMerkTreeMeta { ```rust pub enum SubelementsDeletionBehavior { - DontCheck, // Skip emptiness check; caller guarantees tree is empty + DontCheckWithNoCleanup, // Skip emptiness check AND post-apply cleanup; caller guarantees tree is empty Error, // Return Error::DeletingNonEmptyTree if non-empty - DeleteChildren, // Check, and recursively delete children if non-empty + DeleteChildren, // Skip emptiness check, but perform post-apply storage cleanup Skip, // Check, and silently skip deletion if non-empty } ``` diff --git a/grovedb/src/batch/mod.rs b/grovedb/src/batch/mod.rs index 3652ad66a..f01baafc6 100644 --- a/grovedb/src/batch/mod.rs +++ b/grovedb/src/batch/mod.rs @@ -94,18 +94,20 @@ use crate::{ /// `deleting_non_empty_trees_returns_error` flags on `BatchApplyOptions`. #[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)] pub enum SubelementsDeletionBehavior { - /// Do not check whether the subtree is empty before deleting. - /// The tree element is removed from the parent Merk unconditionally. - /// Any children that still exist will be left as orphaned data on disk - /// — callers typically use this when they have already ensured the - /// subtree is empty (e.g. the parent cleaned up children first) and - /// want to avoid the cost of a redundant emptiness check. - DontCheck, + /// Do not check whether the subtree is empty before deleting, and skip + /// post-apply storage cleanup. The tree element is removed from the + /// parent Merk unconditionally but no child subtree storage is cleared. + /// Callers use this when they have already ensured the subtree is empty + /// and want to avoid the I/O cost of both the emptiness check and the + /// cleanup phase. + DontCheckWithNoCleanup, /// Check emptiness. If the subtree is non-empty, return /// `Error::DeletingNonEmptyTree`. Error, - /// Check emptiness. If the subtree is non-empty, recursively delete - /// all children before deleting the tree itself. + /// Do not check whether the subtree is empty before deleting, but + /// still perform post-apply storage cleanup to remove the child + /// subtree's storage (and any nested subtrees). Use this when the + /// subtree may contain children that should be recursively cleaned up. DeleteChildren, /// Check emptiness. If the subtree is non-empty, silently skip this /// `DeleteTree` operation (no error, no deletion). @@ -3084,17 +3086,16 @@ impl GroveDb { .ok_or(Error::InvalidBatchOperation("delete op is missing a key")) ); // Map the per-op enum to the lower-level DeleteOptions. - // DontCheck and DeleteChildren both set + // DontCheckWithNoCleanup and DeleteChildren both set // allow_deleting_non_empty_trees = true because the // single-op `delete()` already performs recursive child - // subtree cleanup when that flag is true — the two - // behaviors converge at this layer. Skip maps to + // subtree cleanup when that flag is true. Skip maps to // allow=false + error=false, which makes `delete()` // silently return Ok(false) for non-empty trees. let delete_options = DeleteOptions { allow_deleting_non_empty_trees: matches!( subelements_deletion_behavior, - SubelementsDeletionBehavior::DontCheck + SubelementsDeletionBehavior::DontCheckWithNoCleanup | SubelementsDeletionBehavior::DeleteChildren ), deleting_non_empty_trees_returns_error: matches!( @@ -3491,12 +3492,16 @@ impl GroveDb { // Per-op emptiness check based on the SubelementsDeletionBehavior policy. match subelements_deletion_behavior { - SubelementsDeletionBehavior::DontCheck => { - // No check — unconditionally allow the delete. + SubelementsDeletionBehavior::DontCheckWithNoCleanup => { + // No emptiness check and no post-apply storage cleanup. + // The caller guarantees the subtree is already empty. + continue; } - SubelementsDeletionBehavior::Error - | SubelementsDeletionBehavior::DeleteChildren - | SubelementsDeletionBehavior::Skip => { + SubelementsDeletionBehavior::DeleteChildren => { + // No emptiness check, but still perform post-apply + // storage cleanup to remove child subtree storage. + } + SubelementsDeletionBehavior::Error | SubelementsDeletionBehavior::Skip => { let is_empty = if tree_type.uses_non_merk_data_storage() { // Non-Merk trees: check element-level entry count. let parent_path_vec = op.path.to_path(); @@ -3583,15 +3588,12 @@ impl GroveDb { )) .wrap_with_cost(cost); } - SubelementsDeletionBehavior::DeleteChildren => { - // Proceed — children will be cleaned up - // in the storage cleanup phase below. - } SubelementsDeletionBehavior::Skip => { skipped_delete_paths.insert(child_path); continue; } - SubelementsDeletionBehavior::DontCheck => unreachable!(), + SubelementsDeletionBehavior::DontCheckWithNoCleanup + | SubelementsDeletionBehavior::DeleteChildren => unreachable!(), } } } @@ -3844,12 +3846,16 @@ impl GroveDb { child_path.push(key.as_slice().to_vec()); match subelements_deletion_behavior { - SubelementsDeletionBehavior::DontCheck => { - // No check — unconditionally allow the delete. + SubelementsDeletionBehavior::DontCheckWithNoCleanup => { + // No emptiness check and no post-apply storage cleanup. + // The caller guarantees the subtree is already empty. + continue; } - SubelementsDeletionBehavior::Error - | SubelementsDeletionBehavior::DeleteChildren - | SubelementsDeletionBehavior::Skip => { + SubelementsDeletionBehavior::DeleteChildren => { + // No emptiness check, but still perform post-apply + // storage cleanup to remove child subtree storage. + } + SubelementsDeletionBehavior::Error | SubelementsDeletionBehavior::Skip => { let is_empty = if tree_type.uses_non_merk_data_storage() { let parent_path_vec = op.path.to_path(); let parent_path: SubtreePath> = @@ -3931,14 +3937,12 @@ impl GroveDb { )) .wrap_with_cost(cost); } - SubelementsDeletionBehavior::DeleteChildren => { - // Proceed — children will be cleaned up. - } SubelementsDeletionBehavior::Skip => { skipped_delete_paths.insert(child_path); continue; } - SubelementsDeletionBehavior::DontCheck => unreachable!(), + SubelementsDeletionBehavior::DontCheckWithNoCleanup + | SubelementsDeletionBehavior::DeleteChildren => unreachable!(), } } } @@ -5576,13 +5580,14 @@ mod tests { .unwrap() .expect("insert commitment tree data"); - // Delete it via batch. The tree is non-empty (has one entry), - // so we pass SubelementsDeletionBehavior::DontCheck to skip the emptiness check. + // Delete it via batch. The tree is non-empty (has one entry). + // Use DeleteChildren to skip the emptiness check but still perform + // post-apply storage cleanup. let ops = vec![QualifiedGroveDbOp::delete_tree_op( vec![], b"ct".to_vec(), grovedb_merk::tree_type::TreeType::CommitmentTree(4), - SubelementsDeletionBehavior::DontCheck, + SubelementsDeletionBehavior::DeleteChildren, )]; let batch_options = Some(BatchApplyOptions::default()); @@ -5662,13 +5667,13 @@ mod tests { .expect("append mmr value"); } - // The tree is non-empty (has 3 entries), so we pass - // SubelementsDeletionBehavior::DontCheck to skip the emptiness check. + // The tree is non-empty (has 3 entries). Use DeleteChildren to skip + // the emptiness check but still perform post-apply storage cleanup. let ops = vec![QualifiedGroveDbOp::delete_tree_op( vec![], b"mmr".to_vec(), grovedb_merk::tree_type::TreeType::MmrTree, - SubelementsDeletionBehavior::DontCheck, + SubelementsDeletionBehavior::DeleteChildren, )]; let batch_options = Some(BatchApplyOptions::default()); @@ -5739,13 +5744,13 @@ mod tests { .expect("insert dense tree value"); } - // The tree is non-empty (has 3 entries), so we pass - // SubelementsDeletionBehavior::DontCheck to skip the emptiness check. + // The tree is non-empty (has 3 entries). Use DeleteChildren to skip + // the emptiness check but still perform post-apply storage cleanup. let ops = vec![QualifiedGroveDbOp::delete_tree_op( vec![], b"dense".to_vec(), grovedb_merk::tree_type::TreeType::DenseAppendOnlyFixedSizeTree(3), - SubelementsDeletionBehavior::DontCheck, + SubelementsDeletionBehavior::DeleteChildren, )]; let batch_options = Some(BatchApplyOptions::default()); diff --git a/grovedb/src/operations/delete/mod.rs b/grovedb/src/operations/delete/mod.rs index 25be813c5..7ea218411 100644 --- a/grovedb/src/operations/delete/mod.rs +++ b/grovedb/src/operations/delete/mod.rs @@ -680,14 +680,14 @@ impl GroveDb { Ok(None) } } else if is_empty { - // Emptiness was already verified above — use DontCheck - // to avoid a redundant re-check when the batch processes - // this op. + // Emptiness was already verified above — use + // DontCheckWithNoCleanup to avoid a redundant re-check + // and skip cleanup (the tree is empty, nothing to clean). Ok(Some(QualifiedGroveDbOp::delete_tree_op( path.to_vec(), key.to_vec(), tree_type, - SubelementsDeletionBehavior::DontCheck, + SubelementsDeletionBehavior::DontCheckWithNoCleanup, ))) } else { Err(Error::NotSupported( diff --git a/grovedb/src/tests/batch_coverage_tests.rs b/grovedb/src/tests/batch_coverage_tests.rs index c425d5c57..3d302dd3e 100644 --- a/grovedb/src/tests/batch_coverage_tests.rs +++ b/grovedb/src/tests/batch_coverage_tests.rs @@ -195,12 +195,12 @@ mod tests { .unwrap() .expect("insert child item"); - // Delete non-empty tree with SubelementsDeletionBehavior::DontCheck + // Delete non-empty tree with SubelementsDeletionBehavior::DontCheckWithNoCleanup let ops = vec![QualifiedGroveDbOp::delete_tree_op( vec![], b"tree_with_items".to_vec(), TreeType::NormalTree, - SubelementsDeletionBehavior::DontCheck, + SubelementsDeletionBehavior::DontCheckWithNoCleanup, )]; let options = Some(BatchApplyOptions { diff --git a/grovedb/src/tests/batch_delete_tree_tests.rs b/grovedb/src/tests/batch_delete_tree_tests.rs index 8bed2f4be..9b9542e27 100644 --- a/grovedb/src/tests/batch_delete_tree_tests.rs +++ b/grovedb/src/tests/batch_delete_tree_tests.rs @@ -117,7 +117,7 @@ mod tests { vec![], b"parent_tree".to_vec(), TreeType::NormalTree, - SubelementsDeletionBehavior::DontCheck, + SubelementsDeletionBehavior::DontCheckWithNoCleanup, )]; let batch_options = Some(BatchApplyOptions { @@ -222,12 +222,13 @@ mod tests { .unwrap() .expect("insert item into inner tree"); - // Step 2: Delete the outer tree via batch (with DontCheck for non-empty subtrees) + // Step 2: Delete the outer tree via batch (with DeleteChildren since + // the tree is non-empty and we want storage cleanup) let ops = vec![QualifiedGroveDbOp::delete_tree_op( vec![], b"outer".to_vec(), TreeType::NormalTree, - SubelementsDeletionBehavior::DontCheck, + SubelementsDeletionBehavior::DeleteChildren, )]; let batch_options = Some(BatchApplyOptions { @@ -348,12 +349,13 @@ mod tests { .expect("verify item exists"); assert_eq!(val, Element::new_item(b"data".to_vec())); - // Delete the parent tree via batch + // Delete the parent tree via batch (with DeleteChildren since the + // tree is non-empty and we want storage cleanup) let delete_ops = vec![QualifiedGroveDbOp::delete_tree_op( vec![], b"parent".to_vec(), TreeType::NormalTree, - SubelementsDeletionBehavior::DontCheck, + SubelementsDeletionBehavior::DeleteChildren, )]; let batch_options = Some(BatchApplyOptions { @@ -646,10 +648,10 @@ mod tests { #[test] fn test_batch_delete_all_children_plus_delete_tree_dont_check() { - // Delete ALL children explicitly + DeleteTree(DontCheck) on parent. - // DontCheck skips the emptiness check entirely, so it succeeds + // Delete ALL children explicitly + DeleteTree(DontCheckWithNoCleanup) on parent. + // DontCheckWithNoCleanup skips the emptiness check entirely, so it succeeds // regardless. This is the typical pattern: caller cleans up children - // first, then uses DontCheck to avoid a redundant emptiness check. + // first, then uses DontCheckWithNoCleanup to avoid a redundant emptiness check. let grove_version = GroveVersion::latest(); let db = make_empty_grovedb(); @@ -693,13 +695,13 @@ mod tests { vec![], b"parent".to_vec(), TreeType::NormalTree, - SubelementsDeletionBehavior::DontCheck, + SubelementsDeletionBehavior::DontCheckWithNoCleanup, ), ]; db.apply_batch(ops, None, None, grove_version) .unwrap() - .expect("delete all children + DontCheck parent should succeed"); + .expect("delete all children + DontCheckWithNoCleanup parent should succeed"); assert!( db.get(EMPTY_PATH, b"parent", None, grove_version) @@ -776,8 +778,8 @@ mod tests { #[test] fn test_batch_delete_some_children_plus_delete_tree_dont_check() { - // Delete SOME children + DeleteTree(DontCheck) on parent. - // DontCheck skips the emptiness check, but apply_body rejects + // Delete SOME children + DeleteTree(DontCheckWithNoCleanup) on parent. + // DontCheckWithNoCleanup skips the emptiness check, but apply_body rejects // the combination because child ops produce a new root key for // a tree that is being deleted. let grove_version = GroveVersion::latest(); @@ -816,14 +818,14 @@ mod tests { .unwrap() .expect("insert child2"); - // Delete only child1, DontCheck on parent + // Delete only child1, DontCheckWithNoCleanup on parent let ops = vec![ QualifiedGroveDbOp::delete_op(vec![b"parent".to_vec()], b"child1".to_vec()), QualifiedGroveDbOp::delete_tree_op( vec![], b"parent".to_vec(), TreeType::NormalTree, - SubelementsDeletionBehavior::DontCheck, + SubelementsDeletionBehavior::DontCheckWithNoCleanup, ), ]; @@ -1184,7 +1186,7 @@ mod tests { vec![], b"outer".to_vec(), TreeType::NormalTree, - SubelementsDeletionBehavior::DontCheck, + SubelementsDeletionBehavior::DeleteChildren, )]; let batch_options = Some(BatchApplyOptions { @@ -1398,12 +1400,13 @@ mod tests { .unwrap() .expect("insert deep item"); - // Delete the top-level tree + // Delete the top-level tree (with DeleteChildren since the tree is + // non-empty and we want storage cleanup of nested subtrees) let ops = vec![QualifiedGroveDbOp::delete_tree_op( vec![], b"l1".to_vec(), TreeType::NormalTree, - SubelementsDeletionBehavior::DontCheck, + SubelementsDeletionBehavior::DeleteChildren, )]; let batch_options = Some(BatchApplyOptions { @@ -1620,7 +1623,7 @@ mod tests { #[test] fn test_without_batching_delete_tree_dont_check() { - // Exercise the non-batch fallback path for DeleteTree with DontCheck. + // Exercise the non-batch fallback path for DeleteTree with DontCheckWithNoCleanup. let grove_version = GroveVersion::latest(); let db = make_empty_grovedb(); @@ -1650,12 +1653,12 @@ mod tests { vec![], b"nb_tree".to_vec(), TreeType::NormalTree, - SubelementsDeletionBehavior::DontCheck, + SubelementsDeletionBehavior::DontCheckWithNoCleanup, )]; db.apply_operations_without_batching(ops, None, None, grove_version) .unwrap() - .expect("non-batch DontCheck should succeed"); + .expect("non-batch DontCheckWithNoCleanup should succeed"); assert!( db.get(EMPTY_PATH, b"nb_tree", None, grove_version)