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