Skip to main content

s2_common/record/
metering.rs

1pub trait MeteredSize {
2    /// Return the metered size of a record or batch of records.
3    fn metered_size(&self) -> usize;
4}
5
6impl<T> MeteredSize for &T
7where
8    T: MeteredSize,
9{
10    fn metered_size(&self) -> usize {
11        (**self).metered_size()
12    }
13}
14
15impl<T: MeteredSize> MeteredSize for &[T] {
16    fn metered_size(&self) -> usize {
17        self.iter().fold(0, |acc, item| acc + item.metered_size())
18    }
19}
20
21impl<T: MeteredSize> MeteredSize for Vec<T> {
22    fn metered_size(&self) -> usize {
23        self.as_slice().metered_size()
24    }
25}
26
27pub trait MeteredExt: MeteredSize + Sized {
28    fn metered(self) -> Metered<Self> {
29        Metered::from(self)
30    }
31}
32
33impl<T> MeteredExt for T where T: MeteredSize {}
34
35pub struct Metered<T> {
36    size: usize,
37    inner: T,
38}
39
40impl<T> Metered<T> {
41    /// Construct a value with an already-known metered size.
42    ///
43    /// This is primarily for decoding persisted storage records, where the
44    /// encoded metered-size prefix is authoritative and must be preserved.
45    pub const fn with_size(size: usize, inner: T) -> Self {
46        Self { size, inner }
47    }
48
49    pub fn into_inner(self) -> T {
50        self.inner
51    }
52
53    pub const fn as_ref(&self) -> Metered<&T> {
54        Metered::with_size(self.size, &self.inner)
55    }
56}
57
58impl<T> std::fmt::Debug for Metered<T>
59where
60    T: std::fmt::Debug,
61{
62    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
63        f.debug_struct("Metered")
64            .field("size", &self.size)
65            .field("inner", &self.inner)
66            .finish()
67    }
68}
69
70impl<T> PartialEq for Metered<T>
71where
72    T: PartialEq,
73{
74    fn eq(&self, other: &Metered<T>) -> bool {
75        self.size == other.size && self.inner == other.inner
76    }
77}
78
79impl<T> Eq for Metered<T> where T: Eq {}
80
81impl<T> std::ops::Deref for Metered<T> {
82    type Target = T;
83
84    fn deref(&self) -> &Self::Target {
85        &self.inner
86    }
87}
88
89impl<T> From<T> for Metered<T>
90where
91    T: MeteredSize,
92{
93    fn from(inner: T) -> Self {
94        Self::with_size(inner.metered_size(), inner)
95    }
96}
97
98impl<T> Default for Metered<T>
99where
100    T: Default + MeteredSize,
101{
102    fn default() -> Self {
103        T::default().into()
104    }
105}
106
107impl<T> Clone for Metered<T>
108where
109    T: Clone,
110{
111    fn clone(&self) -> Self {
112        Self::with_size(self.size, self.inner.clone())
113    }
114}
115
116impl<T> MeteredSize for Metered<T> {
117    fn metered_size(&self) -> usize {
118        self.size
119    }
120}
121
122impl<T> Metered<Vec<T>>
123where
124    T: MeteredSize,
125{
126    pub fn with_capacity(capacity: usize) -> Self {
127        Self {
128            size: 0,
129            inner: Vec::with_capacity(capacity),
130        }
131    }
132
133    pub fn push(&mut self, item: Metered<T>) {
134        self.inner.push(item.inner);
135        self.size += item.size;
136    }
137
138    pub fn append(&mut self, other: Self) {
139        self.inner.extend(other.inner);
140        self.size += other.size;
141    }
142}
143
144impl<T> FromIterator<Metered<T>> for Metered<Vec<T>>
145where
146    T: MeteredSize,
147{
148    fn from_iter<I: IntoIterator<Item = Metered<T>>>(iterable: I) -> Self {
149        let it = iterable.into_iter();
150        let (cap_lower, cap_upper) = it.size_hint();
151        let mut buf = Self::with_capacity(cap_upper.unwrap_or(cap_lower));
152        for item in it {
153            buf.push(item);
154        }
155        buf
156    }
157}
158
159impl<T> IntoIterator for Metered<Vec<T>> {
160    type Item = T;
161    type IntoIter = std::vec::IntoIter<Self::Item>;
162
163    fn into_iter(self) -> Self::IntoIter {
164        self.inner.into_iter()
165    }
166}