uqa_storage/key_value/
maintenance_records.rs1use crate::{
10 mvcc::{MaintenanceRecordLayout, VersionError, VersionResult},
11 read_control::StorageReadControl,
12 statistics_maintenance::StatisticsMaintenance,
13};
14use uqa_core::memory::BudgetedVec;
15
16pub struct KeyValueMaintenanceRecords;
17
18fn validate_key(key: &[u8]) -> VersionResult<()> {
19 let length = key
20 .get(1..5)
21 .and_then(|bytes| <[u8; 4]>::try_from(bytes).ok())
22 .map(u32::from_be_bytes)
23 .and_then(|length| usize::try_from(length).ok());
24 if key.first() != Some(&super::TAG_METADATA)
25 || length != key.len().checked_sub(5)
26 || !key
27 .get(5..)
28 .is_some_and(|name| name.starts_with(StatisticsMaintenance::KEY_PREFIX.as_bytes()))
29 {
30 return Err(VersionError::InvalidEncoding(
31 "invalid statistics-maintenance key",
32 ));
33 }
34 Ok(())
35}
36
37impl MaintenanceRecordLayout for KeyValueMaintenanceRecords {
38 fn decode(
39 &self,
40 key: &[u8],
41 value: &[u8],
42 control: &StorageReadControl,
43 ) -> VersionResult<StatisticsMaintenance> {
44 control.cancellation().check()?;
45 validate_key(key)?;
46 serde_json::from_slice(value)
47 .map_err(crate::StorageBackendError::from)
48 .map_err(Into::into)
49 }
50
51 fn encode(
52 &self,
53 key: &[u8],
54 _template: &[u8],
55 state: &StatisticsMaintenance,
56 control: &StorageReadControl,
57 ) -> VersionResult<BudgetedVec<u8>> {
58 validate_key(key)?;
59 state.encode(control)
60 }
61}