Skip to content

Commit

Permalink
Merge branch 'tomas/delete-prefix' (#1632)
Browse files Browse the repository at this point in the history
* tomas/delete-prefix:
  changelog: add #1632
  storage_api/lazy_map: remove entries by prefixed key
  test/core/wl_storage: extend prefix iter test to include delete prefix
  core/storage_api: add `StorageWrite::delete_prefix`
  changelog: add #1642
  test/storage/rocksdb: check that prefix_iter matches only full segments
  ledger/db: ensure that prefix iter only matches full key segments
  • Loading branch information
brentstone committed Jul 5, 2023
2 parents 6e49486 + d9b6dd9 commit 93ac8b2
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 5 deletions.
2 changes: 2 additions & 0 deletions .changelog/unreleased/features/1632-delete-prefix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Storage: Add a function to delete key-vals matching a given prefix.
([\#1632](https://github.com/anoma/namada/pull/1632))
8 changes: 8 additions & 0 deletions core/proptest-regressions/ledger/storage/wl_storage.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Seeds for failure cases proptest has generated in the past. It is
# automatically read and these particular cases re-run before any
# novel cases are generated.
#
# It is recommended to check this file in to source control so that
# everyone who runs the test benefits from these saved cases.
cc dda57e313536d5b8da109e808f0ea8af87981e843db9907ab75adcf58c3ad7a0 # shrinks to key_vals = [(Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, Storage(0)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, Storage(0)), (Key { segments: [StringSeg("_"), StringSeg("0")] }, Storage(0)), (Key { segments: [StringSeg("_"), StringSeg("_")] }, Storage(0)), (Key { segments: [StringSeg("_A"), StringSeg("A")] }, Storage(0)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, Storage(0)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, Storage(0)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, Storage(0)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, Storage(0)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, Storage(0)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, Storage(0)), (Key { segments: [StringSeg("_"), StringSeg("0")] }, Storage(0)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, BlockWriteLog(Write(0))), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, BlockWriteLog(Write(0))), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, BlockWriteLog(Write(0))), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, BlockWriteLog(Write(0))), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, BlockWriteLog(Write(0))), (Key { segments: [StringSeg("_"), StringSeg("0")] }, BlockWriteLog(Write(0))), (Key { segments: [StringSeg("_"), StringSeg("0")] }, BlockWriteLog(Delete)), (Key { segments: [StringSeg("_"), StringSeg("0")] }, BlockWriteLog(Delete)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu)] }, BlockWriteLog(DeletePrefix)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu)] }, BlockWriteLog(DeletePrefix)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu)] }, BlockWriteLog(DeletePrefix)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu)] }, BlockWriteLog(DeletePrefix)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu)] }, BlockWriteLog(DeletePrefix)), (Key { segments: [StringSeg("_")] }, BlockWriteLog(DeletePrefix))]
cc be5b2533eaa2312359cefbe482c60fa93524e9decae0905af2b9aec936c05a56 # shrinks to key_vals = [(Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, Storage(0)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, Storage(0)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, Storage(0)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, Storage(0)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, Storage(0)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, Storage(0)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, Storage(0)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, Storage(0)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, Storage(0)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, Storage(0)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, Storage(0)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, Storage(0)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, Storage(0)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, Storage(0)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, Storage(0)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, Storage(0)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, Storage(0)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, Storage(0)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, Storage(0)), (Key { segments: [StringSeg("a"), StringSeg("0")] }, Storage(0)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, Storage(0)), (Key { segments: [StringSeg("_"), StringSeg("_")] }, Storage(0)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, Storage(0)), (Key { segments: [StringSeg("a"), StringSeg("A")] }, Storage(0)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, Storage(0)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, Storage(0)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, Storage(0)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, Storage(0)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, Storage(0)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, Storage(0)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, Storage(0)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, Storage(0)), (Key { segments: [StringSeg("_0"), StringSeg("_")] }, Storage(0)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, Storage(0)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, Storage(0)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, BlockWriteLog(Write(0))), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, BlockWriteLog(Write(0))), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, BlockWriteLog(Write(0))), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, BlockWriteLog(Write(0))), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, BlockWriteLog(Write(0))), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, BlockWriteLog(Write(0))), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, BlockWriteLog(Write(0))), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, BlockWriteLog(Write(0))), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, BlockWriteLog(Write(0))), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, BlockWriteLog(Write(0))), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, BlockWriteLog(Write(0))), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, BlockWriteLog(Write(0))), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, BlockWriteLog(Write(0))), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, BlockWriteLog(Write(0))), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu), StringSeg("?")] }, BlockWriteLog(Write(0))), (Key { segments: [StringSeg("_"), StringSeg("_")] }, BlockWriteLog(Delete)), (Key { segments: [StringSeg("a"), StringSeg("0")] }, BlockWriteLog(Delete)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu)] }, BlockWriteLog(DeletePrefix)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu)] }, BlockWriteLog(DeletePrefix)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu)] }, BlockWriteLog(DeletePrefix)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu)] }, BlockWriteLog(DeletePrefix)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu)] }, BlockWriteLog(DeletePrefix)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu)] }, BlockWriteLog(DeletePrefix)), (Key { segments: [AddressSeg(Established: atest1v4ehgw36gym52vfnxqmrjdp3xcmyx3zz8y65yv29x9pyys69xdrryv29x3zyy3pkxdrrgdjylcyclu)] }, BlockWriteLog(DeletePrefix)), (Key { segments: [StringSeg("_")] }, TxWriteLog(DeletePrefix))]
85 changes: 80 additions & 5 deletions core/src/ledger/storage/wl_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,12 @@ mod tests {
// Deletes have to be applied last
if let Level::BlockWriteLog(WlMod::Delete) = val {
expected_pre.remove(key);
} else if let Level::BlockWriteLog(WlMod::DeletePrefix) = val {
expected_pre.retain(|expected_key, _val| {
// Remove matching prefixes except for VPs
expected_key.is_validity_predicate().is_some()
|| expected_key.split_prefix(key).is_none()
})
}
}

Expand Down Expand Up @@ -582,6 +588,12 @@ mod tests {
// Deletes have to be applied last
if let Level::TxWriteLog(WlMod::Delete) = val {
expected_post.remove(key);
} else if let Level::TxWriteLog(WlMod::DeletePrefix) = val {
expected_post.retain(|expected_key, _val| {
// Remove matching prefixes except for VPs
expected_key.is_validity_predicate().is_some()
|| expected_key.split_prefix(key).is_none()
})
}
}

Expand All @@ -602,10 +614,12 @@ mod tests {
}

fn apply_to_wl_storage(s: &mut TestWlStorage, kvs: &[KeyVal<i8>]) {
// Apply writes first
for (key, val) in kvs {
match val {
Level::TxWriteLog(WlMod::Delete)
| Level::BlockWriteLog(WlMod::Delete) => {}
Level::TxWriteLog(WlMod::Delete | WlMod::DeletePrefix)
| Level::BlockWriteLog(WlMod::Delete | WlMod::DeletePrefix) => {
}
Level::TxWriteLog(WlMod::Write(val)) => {
s.write_log.write(key, val.try_to_vec().unwrap()).unwrap();
}
Expand All @@ -620,13 +634,34 @@ mod tests {
}
}
}
// Then apply deletions
for (key, val) in kvs {
match val {
Level::TxWriteLog(WlMod::Delete) => {
s.write_log.delete(key).unwrap();
}
Level::BlockWriteLog(WlMod::Delete) => {
s.write_log.protocol_delete(key).unwrap();
s.delete(key).unwrap();
}
Level::TxWriteLog(WlMod::DeletePrefix) => {
// Find keys matching the prefix
let keys = storage_api::iter_prefix_bytes(s, key)
.unwrap()
.map(|res| {
let (key, _val) = res.unwrap();
key
})
.collect::<Vec<storage::Key>>();
// Delete the matching keys
for key in keys {
// Skip validity predicates which cannot be deleted
if key.is_validity_predicate().is_none() {
s.write_log.delete(&key).unwrap();
}
}
}
Level::BlockWriteLog(WlMod::DeletePrefix) => {
s.delete_prefix(key).unwrap();
}
_ => {}
}
Expand All @@ -649,6 +684,7 @@ mod tests {
enum WlMod<VAL> {
Write(VAL),
Delete,
DeletePrefix,
}

fn arb_key_vals(len: usize) -> impl Strategy<Value = Vec<KeyVal<i8>>> {
Expand All @@ -675,9 +711,22 @@ mod tests {
1..len / 3,
);

// Select some indices to delete prefix
let delete_prefix = prop::collection::vec(
(
any::<prop::sample::Index>(),
any::<bool>(),
// An arbitrary number of key segments to drop from a selected
// key to obtain the prefix. Because `arb_key` generates `2..5`
// segments, we can drop one less of its upper bound.
(2_usize..4),
),
1..len / 4,
);

// Combine them all together
(storage_kvs, overrides, deletes).prop_map(
|(mut kvs, overrides, deletes)| {
(storage_kvs, overrides, deletes, delete_prefix).prop_map(
|(mut kvs, overrides, deletes, delete_prefix)| {
for (ix, val, is_tx) in overrides {
let (key, _) = ix.get(&kvs);
let wl_mod = WlMod::Write(val);
Expand All @@ -703,6 +752,32 @@ mod tests {
};
kvs.push((key.clone(), lvl));
}
for (ix, is_tx, num_of_seg_to_drop) in delete_prefix {
let (key, _) = ix.get(&kvs);
let wl_mod = WlMod::DeletePrefix;
let lvl = if is_tx {
Level::TxWriteLog(wl_mod)
} else {
Level::BlockWriteLog(wl_mod)
};
// Keep at least one segment
let num_of_seg_to_keep = std::cmp::max(
1,
key.segments
.len()
.checked_sub(num_of_seg_to_drop)
.unwrap_or_default(),
);
let prefix = storage::Key {
segments: key
.segments
.iter()
.take(num_of_seg_to_keep)
.cloned()
.collect(),
};
kvs.push((prefix, lvl));
}
kvs
},
)
Expand Down
Loading

0 comments on commit 93ac8b2

Please sign in to comment.