Skip to main content

commonware_storage/qmdb/any/operation/
variable.rs

1use crate::{
2    merkle::Family,
3    qmdb::{
4        any::{
5            VariableValue,
6            operation::{
7                COMMIT_CONTEXT, DELETE_CONTEXT, Operation, OperationCodec, UPDATE_CONTEXT, Update,
8                update,
9            },
10            value::VariableEncoding,
11        },
12        operation::{
13            Key, commit_variable_payload_size, read_commit_variable, write_commit_variable,
14        },
15    },
16};
17use commonware_codec::{Buf, EncodeSize, Error as CodecError, Read, ReadExt as _, Write};
18use commonware_runtime::BufMut;
19
20impl<F, V, S> OperationCodec<F, S> for VariableEncoding<V>
21where
22    F: Family,
23    V: VariableValue,
24    S: Update<Value = V, ValueEncoding = Self>
25        + Write
26        + Read<Cfg = (<S::Key as Read>::Cfg, <V as Read>::Cfg)>,
27{
28    type ReadCfg = (<S::Key as Read>::Cfg, <V as Read>::Cfg);
29
30    fn write_operation(op: &Operation<F, S>, buf: &mut impl BufMut) {
31        match op {
32            Operation::Delete(k) => {
33                DELETE_CONTEXT.write(buf);
34                k.write(buf);
35            }
36            Operation::Update(p) => {
37                UPDATE_CONTEXT.write(buf);
38                p.write(buf);
39            }
40            Operation::CommitFloor(metadata, floor_loc) => {
41                COMMIT_CONTEXT.write(buf);
42                write_commit_variable(metadata, *floor_loc, buf);
43            }
44        }
45    }
46
47    fn read_operation(
48        buf: &mut impl Buf,
49        cfg: &Self::ReadCfg,
50    ) -> Result<Operation<F, S>, CodecError> {
51        match u8::read(buf)? {
52            DELETE_CONTEXT => {
53                let key = S::Key::read_cfg(buf, &cfg.0)?;
54                Ok(Operation::Delete(key))
55            }
56            UPDATE_CONTEXT => {
57                let payload = S::read_cfg(buf, cfg)?;
58                Ok(Operation::Update(payload))
59            }
60            COMMIT_CONTEXT => {
61                let (metadata, floor_loc) = read_commit_variable(buf, &cfg.1)?;
62                Ok(Operation::CommitFloor(metadata, floor_loc))
63            }
64            e => Err(CodecError::InvalidEnum(e)),
65        }
66    }
67}
68
69// EncodeSize for ordered variable operations.
70impl<F, K, V> EncodeSize for Operation<F, update::Ordered<K, VariableEncoding<V>>>
71where
72    F: Family,
73    K: Key,
74    V: VariableValue,
75    update::Ordered<K, VariableEncoding<V>>: EncodeSize,
76{
77    fn encode_size(&self) -> usize {
78        1 + match self {
79            Self::Delete(k) => k.encode_size(),
80            Self::Update(p) => p.encode_size(),
81            Self::CommitFloor(v, floor) => commit_variable_payload_size(v, *floor),
82        }
83    }
84}
85
86// EncodeSize for unordered variable operations.
87impl<F, K, V> EncodeSize for Operation<F, update::Unordered<K, VariableEncoding<V>>>
88where
89    F: Family,
90    K: Key,
91    V: VariableValue,
92    update::Unordered<K, VariableEncoding<V>>: EncodeSize,
93{
94    fn encode_size(&self) -> usize {
95        1 + match self {
96            Self::Delete(k) => k.encode_size(),
97            Self::Update(p) => p.encode_size(),
98            Self::CommitFloor(v, floor) => commit_variable_payload_size(v, *floor),
99        }
100    }
101}