harmos_storage/
object_admissions.rs1use std::num::NonZeroUsize;
18
19use sha2::{Digest, Sha256};
21
22use super::admissions::Mutation;
24use super::objects::invalid;
25use super::{ObjectReceipt, ObjectValue, StorageManager};
26use crate::Result;
27use crate::storage::MutationId;
28
29impl<C> StorageManager<C> {
44 #[tracing::instrument(name = "storage.object_admissions.write_objects_once", level = "debug", skip_all)]
45 pub async fn write_objects_once(&self, mutation: &MutationId, objects: Vec<ObjectValue>) -> Result<Vec<ObjectReceipt>> {
46 let count = NonZeroUsize::new(objects.len()).ok_or_else(|| invalid("object batch must not be empty"))?;
47 let mut hash = Sha256::new();
48 part(&mut hash, b"storage.write_objects:v1");
49 hash.update((objects.len() as u64).to_le_bytes());
50 for object in &objects {
51 part(&mut hash, object.schema.id.as_str().as_bytes());
52 hash.update(object.schema.version.get().to_le_bytes());
53 part(&mut hash, object.item.as_str().as_bytes());
54 part(&mut hash, &object.payload);
55 }
56 self.admit_object_group(
57 self.object_admission_bytes(),
58 count,
59 Some(Mutation {
60 id: mutation,
61 fingerprint: hash.finalize().into(),
62 }),
63 |group| {
64 for object in objects {
65 group.write_value(object)?;
66 }
67 Ok(())
68 },
69 )
70 .await
71 }
72}
73
74fn part(hash: &mut Sha256, bytes: &[u8]) {
79 hash.update((bytes.len() as u64).to_le_bytes());
80 hash.update(bytes);
81}
82
83