Skip to main content

uqa_storage/key_value/
maintenance_records.rs

1//
2// Unified Query Algebra
3//
4// Copyright (c) 2023-2026 Cognica, Inc.
5//
6
7//! Key/Value encoding for typed statistics-maintenance records.
8
9use 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}