diff --git a/go/cpossum/c-possum.go b/go/cpossum/c-possum.go index 151e125..580fa02 100644 --- a/go/cpossum/c-possum.go +++ b/go/cpossum/c-possum.go @@ -264,3 +264,7 @@ func WriterRename(w Writer, v Value, newKey []byte) { func HandleMovePrefix(h *Handle, from, to []byte) error { return mapError(C.possum_handle_move_prefix(h, BufFromBytes(from), BufFromBytes(to))) } + +func HandleDeletePrefix(h *Handle, prefix []byte) error { + return mapError(C.possum_handle_delete_prefix(h, BufFromBytes(prefix))) +} diff --git a/go/cpossum/possum.h b/go/cpossum/possum.h index 0208536..bb1d6f4 100644 --- a/go/cpossum/possum.h +++ b/go/cpossum/possum.h @@ -129,3 +129,5 @@ PossumError possum_single_delete(const Handle *handle, PossumBuf key, PossumStat PossumError possum_reader_new(const Handle *handle, PossumReader **reader); PossumError possum_handle_move_prefix(Handle *handle, PossumBuf from, PossumBuf to); + +PossumError possum_handle_delete_prefix(Handle *handle, PossumBuf prefix); diff --git a/go/handle.go b/go/handle.go index ae6f758..3ae6160 100644 --- a/go/handle.go +++ b/go/handle.go @@ -83,3 +83,7 @@ func (me Handle) CleanupSnapshots() error { func (me Handle) MovePrefix(from, to []byte) error { return possumC.HandleMovePrefix(me.cHandle, from, to) } + +func (me Handle) DeletePrefix(prefix []byte) error { + return possumC.HandleDeletePrefix(me.cHandle, prefix) +} diff --git a/go/justfile b/go/justfile new file mode 100644 index 0000000..0d4e71c --- /dev/null +++ b/go/justfile @@ -0,0 +1,4 @@ +test: + cargo build + make -C .. + CGO_LDFLAGS=../target/debug/libpossum.a go test -race ./... diff --git a/go/resource/resource.go b/go/resource/resource.go index 7fa0a36..678880c 100644 --- a/go/resource/resource.go +++ b/go/resource/resource.go @@ -21,6 +21,10 @@ func (p Provider) NewInstance(s string) (resource.Instance, error) { }, nil } +func (p Provider) DeletePrefix(prefix string) error { + return p.Handle.DeletePrefix([]byte(prefix)) +} + var _ resource.Provider = Provider{} type instance struct { diff --git a/src/c_api/ext_fns/handle.rs b/src/c_api/ext_fns/handle.rs index 8183cfc..39aca40 100644 --- a/src/c_api/ext_fns/handle.rs +++ b/src/c_api/ext_fns/handle.rs @@ -173,3 +173,16 @@ pub extern "C" fn possum_handle_move_prefix( .map_err(Into::into) }) } + +#[no_mangle] +pub extern "C" fn possum_handle_delete_prefix( + handle: *mut Handle, + prefix: PossumBuf, +) -> PossumError { + let handle = unsafe { &mut *handle }; + with_residual(|| { + handle + .delete_prefix(prefix.as_ref()) + .map_err(Into::into) + }) +} \ No newline at end of file diff --git a/src/handle.rs b/src/handle.rs index 9ddeaf1..2861670 100644 --- a/src/handle.rs +++ b/src/handle.rs @@ -304,7 +304,7 @@ impl Handle { // Maybe it's okay just to commit anyway, since we have a deferred transaction and sqlite // might know nothing has changed. if deleted.is_some() { - tx.commit(())?.complete()?; + tx.commit(())?.complete(); } Ok(deleted) } @@ -321,7 +321,7 @@ impl Handle { pub fn rename_item(&mut self, from: &[u8], to: &[u8]) -> PubResult { let mut tx = self.start_immediate_transaction()?; let last_used = tx.rename_item(from, to)?; - Ok(tx.commit(last_used)?.complete()?) + Ok(tx.commit(last_used)?.complete()) } /// Walks the underlying files in the possum directory. @@ -455,7 +455,17 @@ impl Handle { to_vec.extend_from_slice(item.key.strip_prefix(from).unwrap()); tx.rename_item(&item.key, &to_vec)?; } - tx.commit(())?.complete() + tx.commit(())?.complete(); + Ok(()) + } + + pub fn delete_prefix(&self, prefix: &[u8]) -> PubResult<()> { + let mut tx = self.start_deferred_transaction()?; + for item in tx.read().list_items(prefix)? { + tx.delete_key(&item.key)?; + } + tx.commit(())?.complete(); + Ok(()) } } diff --git a/src/lib.rs b/src/lib.rs index fed4843..07208af 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -349,7 +349,7 @@ impl<'handle> BatchWriter<'handle> { .context("commit transaction")?; self.flush_exclusive_files(); - work.complete() + Ok(work.complete()) } /// Flush Writer's exclusive files and return them to the Handle pool. diff --git a/src/reader.rs b/src/reader.rs index b22aa14..96fa5fe 100644 --- a/src/reader.rs +++ b/src/reader.rs @@ -18,7 +18,7 @@ impl<'a> Reader<'a> { file_offset, length, file_id, - }) = value.location.clone() + }) = value.location { let file = self.reads.entry(file_id); file.or_default().insert(ReadExtent { @@ -39,7 +39,7 @@ impl<'a> Reader<'a> { self.owned_tx .commit(()) .context("committing transaction")? - .complete()?; + .complete(); Ok(Snapshot { file_clones }) } diff --git a/src/testing/torrent_storage.rs b/src/testing/torrent_storage.rs index fb8bde9..970b85f 100644 --- a/src/testing/torrent_storage.rs +++ b/src/testing/torrent_storage.rs @@ -154,7 +154,7 @@ fn torrent_storage_inner_run(inner: &TorrentStorageInner) -> anyhow::Result<()> |offset| format!("verified/{piece_data_hash:016x}/{offset}").into_bytes(); if opts.rename_values { for (offset, value) in values { - snapshot.value(value.clone()).view(|bytes| { + snapshot.value(value).view(|bytes| { stored_hash.write(bytes); compare_reads(bytes, io::repeat(byte).take(chunk_size as u64)).unwrap(); writer.rename_value(value, make_verified_key(offset)) diff --git a/src/tx.rs b/src/tx.rs index 72f5a0d..2b2c241 100644 --- a/src/tx.rs +++ b/src/tx.rs @@ -147,7 +147,7 @@ where } impl<'h, T> PostCommitWork<'h, T> { - pub fn complete(self) -> Result { + pub fn complete(self) -> T { // This has to happen after exclusive files are flushed or there's a tendency for hole // punches to not persist. It doesn't fix the problem, but it significantly reduces it. if !self.handle.instance_limits.disable_hole_punching { @@ -157,7 +157,7 @@ impl<'h, T> PostCommitWork<'h, T> { for file_id in self.altered_files { self.handle.clones.lock().unwrap().remove(&file_id); } - Ok(self.reward) + self.reward } }