reifydb_value/value/container/
blob.rs1use std::{
5 fmt::{self, Debug},
6 result::Result as StdResult,
7};
8
9use serde::{Deserialize, Deserializer, Serialize, Serializer};
10
11use crate::{
12 Result,
13 util::bitvec::BitVec,
14 value::{Value, blob::Blob, container::varlen::VarlenContainer, value_type::ValueType},
15};
16
17pub struct BlobContainer {
18 inner: VarlenContainer,
19}
20
21impl Clone for BlobContainer {
22 fn clone(&self) -> Self {
23 Self {
24 inner: self.inner.clone(),
25 }
26 }
27}
28
29impl Debug for BlobContainer
30where
31 VarlenContainer: Debug,
32{
33 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
34 f.debug_struct("BlobContainer").field("inner", &self.inner).finish()
35 }
36}
37
38impl PartialEq for BlobContainer
39where
40 VarlenContainer: PartialEq,
41{
42 fn eq(&self, other: &Self) -> bool {
43 self.inner == other.inner
44 }
45}
46
47impl Serialize for BlobContainer {
48 fn serialize<Ser: Serializer>(&self, serializer: Ser) -> StdResult<Ser::Ok, Ser::Error> {
49 self.inner.serialize(serializer)
50 }
51}
52
53impl<'de> Deserialize<'de> for BlobContainer {
54 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> StdResult<Self, D::Error> {
55 let inner = VarlenContainer::deserialize(deserializer)?;
56 Ok(Self {
57 inner,
58 })
59 }
60}
61
62impl BlobContainer {
63 pub fn new(data: Vec<Blob>) -> Self {
64 Self::from_vec(data)
65 }
66
67 pub fn from_vec(data: Vec<Blob>) -> Self {
68 let inner = VarlenContainer::from_byte_slices(data.iter().map(|b| b.as_bytes()));
69 Self {
70 inner,
71 }
72 }
73
74 pub fn with_capacity(capacity: usize) -> Self {
75 Self {
76 inner: VarlenContainer::with_capacity(capacity, capacity * 32),
77 }
78 }
79
80 pub fn from_bytes_offsets(data: Vec<u8>, offsets: Vec<u64>) -> Self {
81 Self {
82 inner: VarlenContainer::from_raw_parts(data, offsets),
83 }
84 }
85}
86
87impl BlobContainer {
88 pub fn from_inner(inner: VarlenContainer) -> Self {
89 Self {
90 inner,
91 }
92 }
93
94 pub fn from_storage_parts(data: Vec<u8>, offsets: Vec<u64>) -> Self {
95 Self {
96 inner: VarlenContainer::from_storage_parts(data, offsets),
97 }
98 }
99
100 pub fn data_storage(&self) -> &Vec<u8> {
101 self.inner.data()
102 }
103
104 pub fn offsets_storage(&self) -> &Vec<u64> {
105 self.inner.offsets_data()
106 }
107
108 pub fn len(&self) -> usize {
109 self.inner.len()
110 }
111
112 pub fn capacity(&self) -> usize {
113 self.inner.capacity()
114 }
115
116 pub fn heap_size(&self) -> usize {
117 self.inner.heap_size()
118 }
119
120 pub fn is_empty(&self) -> bool {
121 self.inner.is_empty()
122 }
123
124 pub fn clear(&mut self) {
125 self.inner.clear_generic();
126 }
127
128 pub fn get(&self, index: usize) -> Option<&[u8]> {
129 self.inner.get_bytes(index)
130 }
131
132 pub fn is_defined(&self, idx: usize) -> bool {
133 idx < self.len()
134 }
135
136 pub fn data_bytes(&self) -> &[u8] {
137 self.inner.data_bytes()
138 }
139
140 pub fn offsets(&self) -> &[u64] {
141 self.inner.offsets()
142 }
143
144 pub fn inner(&self) -> &VarlenContainer {
145 &self.inner
146 }
147
148 pub fn as_string(&self, index: usize) -> String {
149 match self.get(index) {
150 Some(bytes) => Blob::new(bytes.to_vec()).to_string(),
151 None => "none".to_string(),
152 }
153 }
154
155 pub fn get_value(&self, index: usize) -> Value {
156 match self.get(index) {
157 Some(bytes) => Value::Blob(Blob::new(bytes.to_vec())),
158 None => Value::none_of(ValueType::Blob),
159 }
160 }
161
162 pub fn iter(&self) -> impl Iterator<Item = Option<&[u8]>> + '_ {
163 (0..self.len()).map(|i| self.get(i))
164 }
165
166 pub fn iter_bytes(&self) -> impl Iterator<Item = &[u8]> + '_ {
167 (0..self.len()).map(|i| self.get(i).unwrap_or(&[]))
168 }
169}
170
171impl BlobContainer {
172 pub fn push(&mut self, value: Blob) {
173 self.inner.push_bytes(value.as_bytes());
174 }
175
176 pub fn push_bytes(&mut self, value: &[u8]) {
177 self.inner.push_bytes(value);
178 }
179
180 pub fn push_default(&mut self) {
181 self.inner.push_bytes(&[]);
182 }
183
184 pub fn extend(&mut self, other: &Self) -> Result<()> {
185 self.inner.extend_from(&other.inner);
186 Ok(())
187 }
188
189 pub fn slice(&self, start: usize, end: usize) -> Self {
190 Self {
191 inner: self.inner.slice(start, end),
192 }
193 }
194
195 pub fn filter(&mut self, mask: &BitVec) {
196 let bits: Vec<bool> = mask.iter().collect();
197 self.inner.filter_in_place(|i| bits.get(i).copied().unwrap_or(false));
198 }
199
200 pub fn reorder(&mut self, indices: &[usize]) {
201 self.inner.reorder_in_place(indices);
202 }
203
204 pub fn take(&self, num: usize) -> Self {
205 Self {
206 inner: self.inner.take_n(num),
207 }
208 }
209}
210
211impl Default for BlobContainer {
212 fn default() -> Self {
213 Self::with_capacity(0)
214 }
215}
216
217#[cfg(test)]
218pub mod tests {
219 use postcard::to_allocvec as postcard_to_allocvec;
220
221 use super::*;
222
223 #[test]
224 fn test_new() {
225 let blob1 = Blob::new(vec![1, 2, 3]);
226 let blob2 = Blob::new(vec![4, 5, 6]);
227 let blobs = vec![blob1.clone(), blob2.clone()];
228 let container = BlobContainer::new(blobs);
229
230 assert_eq!(container.len(), 2);
231 assert_eq!(container.get(0), Some(blob1.as_bytes()));
232 assert_eq!(container.get(1), Some(blob2.as_bytes()));
233 }
234
235 #[test]
236 fn test_from_vec() {
237 let blob1 = Blob::new(vec![10, 20, 30]);
238 let blob2 = Blob::new(vec![40, 50]);
239 let blobs = vec![blob1.clone(), blob2.clone()];
240 let container = BlobContainer::from_vec(blobs);
241
242 assert_eq!(container.len(), 2);
243 assert_eq!(container.get(0), Some(blob1.as_bytes()));
244 assert_eq!(container.get(1), Some(blob2.as_bytes()));
245
246 for i in 0..2 {
247 assert!(container.is_defined(i));
248 }
249 }
250
251 #[test]
252 fn test_with_capacity() {
253 let container = BlobContainer::with_capacity(10);
254 assert_eq!(container.len(), 0);
255 assert!(container.is_empty());
256 assert!(container.capacity() >= 10);
257 }
258
259 #[test]
260 fn test_push_with_default() {
261 let mut container = BlobContainer::with_capacity(3);
262 let blob1 = Blob::new(vec![1, 2, 3]);
263 let blob2 = Blob::new(vec![7, 8, 9]);
264
265 container.push(blob1.clone());
266 container.push_default();
267 container.push(blob2.clone());
268
269 assert_eq!(container.len(), 3);
270 assert_eq!(container.get(0), Some(blob1.as_bytes()));
271 assert_eq!(container.get(1), Some(b"".as_slice()));
272 assert_eq!(container.get(2), Some(blob2.as_bytes()));
273
274 assert!(container.is_defined(0));
275 assert!(container.is_defined(1));
276 assert!(container.is_defined(2));
277 }
278
279 #[test]
280 fn testault() {
281 let container = BlobContainer::default();
282 assert_eq!(container.len(), 0);
283 assert!(container.is_empty());
284 }
285
286 #[test]
287 fn test_data_bytes_and_offsets_match_zero_copy_layout() {
288 let container = BlobContainer::from_vec(vec![Blob::new(vec![0xAA, 0xBB]), Blob::new(vec![0xCC])]);
289 assert_eq!(container.data_bytes(), &[0xAAu8, 0xBB, 0xCC]);
290 assert_eq!(container.offsets(), &[0u64, 2, 3]);
291 }
292
293 #[test]
294 fn test_postcard_wire_compat() {
295 let blobs = vec![Blob::new(vec![1, 2, 3]), Blob::new(vec![4, 5])];
299 let blobs_bytes: Vec<u8> = postcard_to_allocvec(&blobs).unwrap();
300
301 let container = BlobContainer::from_vec(blobs.clone());
302 let container_bytes: Vec<u8> = postcard_to_allocvec(&container).unwrap();
303
304 assert_eq!(blobs_bytes, container_bytes);
305 }
306}