commonware_storage/qmdb/any/operation/
variable.rs1use 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
69impl<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
86impl<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}