reth_db_api/models/
integer_list.rs1use crate::table::{Compress, Decompress};
4use bytes::BufMut;
5use core::{fmt, ops::RangeBounds};
6use derive_more::Deref;
7use reth_codecs::DecompressError;
8use roaring::RoaringTreemap;
9use serde::ser::SerializeSeq;
10
11#[derive(Clone, PartialEq, Eq, Default, Deref)]
22pub struct IntegerList(pub RoaringTreemap);
23
24impl fmt::Debug for IntegerList {
25 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
26 f.write_str("IntegerList")?;
27 f.debug_list().entries(self.0.iter()).finish()
28 }
29}
30
31impl IntegerList {
32 pub fn empty() -> Self {
34 Self(RoaringTreemap::new())
35 }
36
37 pub fn new(list: impl IntoIterator<Item = u64>) -> Result<Self, IntegerListError> {
41 RoaringTreemap::from_sorted_iter(list)
42 .map(Self)
43 .map_err(|_| IntegerListError::UnsortedInput)
44 }
45
46 #[inline]
52 #[track_caller]
53 pub fn new_pre_sorted(list: impl IntoIterator<Item = u64>) -> Self {
54 Self::new(list).expect("IntegerList must be pre-sorted and non-empty")
55 }
56
57 pub fn append(&mut self, list: impl IntoIterator<Item = u64>) -> Result<u64, IntegerListError> {
59 self.0.append(list).map_err(|_| IntegerListError::UnsortedInput)
60 }
61
62 pub fn push(&mut self, value: u64) -> Result<(), IntegerListError> {
64 self.0.try_push(value).map_err(|_| IntegerListError::UnsortedInput)
65 }
66
67 pub fn clear(&mut self) {
69 self.0.clear();
70 }
71
72 pub fn remove_range<R: RangeBounds<u64>>(&mut self, range: R) -> u64 {
74 self.0.remove_range(range)
75 }
76
77 pub fn to_bytes(&self) -> Vec<u8> {
79 let mut vec = Vec::with_capacity(self.0.serialized_size());
80 self.0.serialize_into(&mut vec).expect("not able to encode IntegerList");
81 vec
82 }
83
84 pub fn to_mut_bytes<B: bytes::BufMut>(&self, buf: &mut B) {
86 self.0.serialize_into(buf.writer()).unwrap();
87 }
88
89 pub fn from_bytes(data: &[u8]) -> Result<Self, IntegerListError> {
91 RoaringTreemap::deserialize_from(data)
92 .map(Self)
93 .map_err(|_| IntegerListError::FailedToDeserialize)
94 }
95}
96
97impl serde::Serialize for IntegerList {
98 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
99 where
100 S: serde::Serializer,
101 {
102 let mut seq = serializer.serialize_seq(Some(self.len() as usize))?;
103 for e in &self.0 {
104 seq.serialize_element(&e)?;
105 }
106 seq.end()
107 }
108}
109
110struct IntegerListVisitor;
111
112impl<'de> serde::de::Visitor<'de> for IntegerListVisitor {
113 type Value = IntegerList;
114
115 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
116 f.write_str("a usize array")
117 }
118
119 fn visit_seq<E>(self, mut seq: E) -> Result<Self::Value, E::Error>
120 where
121 E: serde::de::SeqAccess<'de>,
122 {
123 let mut list = IntegerList::empty();
124 while let Some(item) = seq.next_element()? {
125 list.push(item).map_err(serde::de::Error::custom)?;
126 }
127 Ok(list)
128 }
129}
130
131impl<'de> serde::Deserialize<'de> for IntegerList {
132 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
133 where
134 D: serde::Deserializer<'de>,
135 {
136 deserializer.deserialize_byte_buf(IntegerListVisitor)
137 }
138}
139
140#[cfg(any(test, feature = "arbitrary"))]
141use arbitrary::{Arbitrary, Unstructured};
142
143#[cfg(any(test, feature = "arbitrary"))]
144impl<'a> Arbitrary<'a> for IntegerList {
145 fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self, arbitrary::Error> {
146 let mut nums: Vec<u64> = Vec::arbitrary(u)?;
147 nums.sort_unstable();
148 Self::new(nums).map_err(|_| arbitrary::Error::IncorrectFormat)
149 }
150}
151
152#[derive(Debug, derive_more::Display, derive_more::Error)]
154pub enum IntegerListError {
155 #[display("the provided input is unsorted")]
157 UnsortedInput,
158 #[display("failed to deserialize data into type")]
160 FailedToDeserialize,
161}
162
163impl Compress for IntegerList {
164 type Compressed = Vec<u8>;
165
166 fn compress(self) -> Self::Compressed {
167 self.to_bytes()
168 }
169
170 fn compress_to_buf<B: bytes::BufMut + AsMut<[u8]>>(&self, buf: &mut B) {
171 self.to_mut_bytes(buf)
172 }
173}
174
175impl Decompress for IntegerList {
176 fn decompress(value: &[u8]) -> Result<Self, DecompressError> {
177 Self::from_bytes(value).map_err(DecompressError::new)
178 }
179}
180
181#[cfg(test)]
182mod tests {
183 use super::*;
184
185 #[test]
186 fn empty_list() {
187 assert_eq!(IntegerList::empty().len(), 0);
188 assert_eq!(IntegerList::new_pre_sorted(std::iter::empty()).len(), 0);
189 }
190
191 #[test]
192 fn test_integer_list() {
193 let original_list = [1, 2, 3];
194 let ef_list = IntegerList::new(original_list).unwrap();
195 assert_eq!(ef_list.iter().collect::<Vec<_>>(), original_list);
196 }
197
198 #[test]
199 fn test_integer_list_serialization() {
200 let original_list = [1, 2, 3];
201 let ef_list = IntegerList::new(original_list).unwrap();
202
203 let blist = ef_list.to_bytes();
204 assert_eq!(IntegerList::from_bytes(&blist).unwrap(), ef_list)
205 }
206}