libblobd_direct/op/
delete_object.rs

1use 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  // Only useful if versioning is enabled.
39  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  // We can reap the object now, as there should only be other readers (it's committed, so there shouldn't be any writers), and readers will double check the state after reading and discard the read if necessary (the object metadata still exists in memory due to Arc, so it's safe to check).
56  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}