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