harmos_storage/manager/
encoding.rs1use super::*;
22
23impl RecordWriteBytes for RecordWrite<'_> {
38 fn encoded_bytes(&self, history: &crate::StoreHistory) -> Result<usize> {
39 let value = StoredRecord {
40 position: StorageCursor {
41 history: history.clone(),
42 sequence: u64::MAX,
43 },
44 schema: self.schema.clone(),
45 scope: self.scope.cloned(),
46 item: self.item.clone(),
47 source: self.source.cloned(),
48 source_time: self.source_time,
49 payload: self.payload,
50 };
51 encoded_size(&value)
52 }
53}
54
55impl RecordWriteBytes for RecordInput {
56 fn encoded_bytes(&self, history: &crate::StoreHistory) -> Result<usize> {
57 self.borrowed().encoded_bytes(history)
58 }
59}
60
61impl Drop for WriteWaiter {
62 fn drop(&mut self) {
63 let counter = if self.measurement { &self.inner.measurement_waiting } else { &self.inner.control_waiting };
64 counter.fetch_sub(1, std::sync::atomic::Ordering::SeqCst);
65 self.inner.notify();
66 }
67}
68
69impl Drop for Admission {
70 fn drop(&mut self) {
71 if self.active {
72 {
73 let mut state = self.inner.state.lock().unwrap();
74 state.reserved = 0;
75 state.reserved_batches = 0;
76 state.collect();
77 }
78 self.inner.notify();
79 }
80 }
81}
82
83impl Write for Counter {
84 fn write(&mut self, bytes: &[u8]) -> io::Result<usize> {
85 self.0 = self.0.checked_add(bytes.len()).ok_or_else(|| io::Error::other("encoded size overflow"))?;
86 Ok(bytes.len())
87 }
88
89 fn flush(&mut self) -> io::Result<()> {
90 Ok(())
91 }
92}
93
94pub fn encoded_size<T: Serialize + ?Sized>(value: &T) -> Result<usize> {
97 let mut counter = Counter(0);
98 serde_json::to_writer(&mut counter, value).map_err(|_| Error::InvalidInput {
99 field: "storage payload",
100 reason: "cannot measure encoded size",
101 })?;
102 Ok(counter.0)
103}
104
105pub(crate) fn recovery_encoded_bound(payload: usize, history: &crate::StoreHistory, data_history: &crate::StoreHistory) -> Result<usize> {
106 let entry = RecoveryEntry {
107 required_data: StorageCursor {
108 history: data_history.clone(),
109 sequence: u64::MAX,
110 },
111 position: RecoveryPosition {
112 history: history.clone(),
113 sequence: u64::MAX,
114 },
115 payload: Vec::new(),
116 };
117 let encoded = payload
118 .checked_div(3)
119 .and_then(|groups| groups.checked_mul(4))
120 .and_then(|bytes| {
121 bytes.checked_add(match payload % 3 {
122 0 => 0,
123 1 => 2,
124 _ => 3,
125 })
126 })
127 .ok_or(Error::InvalidInput {
128 field: "managed recovery",
129 reason: "encoded size overflow",
130 })?;
131 let snapshot = RecoverySnapshot {
132 required_data: entry.required_data.clone(),
133 through: entry.position.clone(),
134 payload: Vec::new(),
135 };
136 let header = encoded_size(&entry)?.max(encoded_size(&snapshot)?);
137 header.checked_add(encoded).ok_or(Error::InvalidInput {
138 field: "managed recovery",
139 reason: "encoded size overflow",
140 })
141}
142
143