libblobd_direct/op/
delete_object.rs1use super::OpError;
2use super::OpResult;
3use crate::ctx::Ctx;
4use crate::object::calc_object_layout;
5use crate::object::Object;
6use off64::usz;
7use std::sync::atomic::Ordering::Relaxed;
8use std::sync::Arc;
9use tinybuf::TinyBuf;
10
11pub(crate) async fn reap_object(ctx: &Ctx, obj: &Object) {
12 let tuple = ctx.tuples.delete_object(obj.id()).await;
13
14 let layout = calc_object_layout(&ctx.pages, obj.size);
15
16 {
17 let mut allocator = ctx.heap_allocator.lock();
18
19 for &page_dev_offset in obj.lpage_dev_offsets.iter() {
20 allocator.release(page_dev_offset, ctx.pages.lpage_size_pow2);
21 }
22 for (i, tail_page_size_pow2) in layout.tail_page_sizes_pow2 {
23 let page_dev_offset = obj.tail_page_dev_offsets[usz!(i)];
24 allocator.release(page_dev_offset, tail_page_size_pow2);
25 }
26 allocator.release(tuple.metadata_dev_offset, tuple.metadata_page_size_pow2);
27 };
28
29 ctx
30 .metrics
31 .0
32 .object_metadata_bytes
33 .fetch_sub(obj.metadata_size(), Relaxed);
34 ctx.metrics.0.object_data_bytes.fetch_sub(obj.size, Relaxed);
35}
36
37pub struct OpDeleteObjectInput {
38 pub key: TinyBuf,
39 pub id: Option<u64>,
41}
42
43pub struct OpDeleteObjectOutput {}
44
45pub(crate) async fn op_delete_object(
46 ctx: Arc<Ctx>,
47 req: OpDeleteObjectInput,
48) -> OpResult<OpDeleteObjectOutput> {
49 let Some((_, obj)) = ctx.committed_objects.remove_if(&req.key, |_, o| req.id.is_none() || Some(o.id()) == req.id) else {
50 return Err(OpError::ObjectNotFound);
51 };
52
53 reap_object(&ctx, &obj).await;
55
56 ctx.metrics.0.delete_op_count.fetch_add(1, Relaxed);
57 ctx.metrics.0.committed_object_count.fetch_sub(1, Relaxed);
58
59 Ok(OpDeleteObjectOutput {})
60}