commonware_storage/qmdb/any/operation/
variable.rs1use crate::{
2 merkle::{Family, Location},
3 qmdb::{
4 any::{
5 operation::{
6 update, Operation, OperationCodec, Update, COMMIT_CONTEXT, DELETE_CONTEXT,
7 UPDATE_CONTEXT,
8 },
9 value::VariableEncoding,
10 VariableValue,
11 },
12 operation::Key,
13 },
14};
15use commonware_codec::{varint::UInt, EncodeSize, Error as CodecError, Read, ReadExt as _, Write};
16use commonware_runtime::{Buf, BufMut};
17
18impl<F, V, S> OperationCodec<F, S> for VariableEncoding<V>
19where
20 F: Family,
21 S::Key: Write + Read,
22 V: VariableValue,
23 S: Update<Value = V, ValueEncoding = Self>
24 + Write
25 + Read<Cfg = (<S::Key as Read>::Cfg, <V as Read>::Cfg)>,
26{
27 type ReadCfg = (<S::Key as Read>::Cfg, <V as Read>::Cfg);
28
29 fn write_operation(op: &Operation<F, S>, buf: &mut impl BufMut) {
30 match op {
31 Operation::Delete(k) => {
32 DELETE_CONTEXT.write(buf);
33 k.write(buf);
34 }
35 Operation::Update(p) => {
36 UPDATE_CONTEXT.write(buf);
37 p.write(buf);
38 }
39 Operation::CommitFloor(metadata, floor_loc) => {
40 COMMIT_CONTEXT.write(buf);
41 metadata.write(buf);
42 UInt(**floor_loc).write(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 = Option::<V>::read_cfg(buf, &cfg.1)?;
62 let floor_loc = Location::read(buf)?;
63 Ok(Operation::CommitFloor(metadata, floor_loc))
64 }
65 e => Err(CodecError::InvalidEnum(e)),
66 }
67 }
68}
69
70impl<F, K, V> EncodeSize for Operation<F, update::Ordered<K, VariableEncoding<V>>>
72where
73 F: Family,
74 K: Key + EncodeSize,
75 V: VariableValue,
76 update::Ordered<K, VariableEncoding<V>>: EncodeSize,
77{
78 fn encode_size(&self) -> usize {
79 1 + match self {
80 Self::Delete(k) => k.encode_size(),
81 Self::Update(p) => p.encode_size(),
82 Self::CommitFloor(v, floor) => v.encode_size() + UInt(**floor).encode_size(),
83 }
84 }
85}
86
87impl<F, K, V> EncodeSize for Operation<F, update::Unordered<K, VariableEncoding<V>>>
89where
90 F: Family,
91 K: Key + EncodeSize,
92 V: VariableValue,
93 update::Unordered<K, VariableEncoding<V>>: EncodeSize,
94{
95 fn encode_size(&self) -> usize {
96 1 + match self {
97 Self::Delete(k) => k.encode_size(),
98 Self::Update(p) => p.encode_size(),
99 Self::CommitFloor(v, floor) => v.encode_size() + UInt(**floor).encode_size(),
100 }
101 }
102}