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 storage::{Cow, Storage},
14 value::{Value, blob::Blob, container::varlen::VarlenContainer, value_type::ValueType},
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)
50 }
51}
52
53impl<'de> Deserialize<'de> for BlobContainer<Cow> {
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<Cow> {
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<S: Storage> BlobContainer<S> {
88 pub fn from_inner(inner: VarlenContainer<S>) -> Self {
89 Self {
90 inner,
91 }
92 }
93
94 pub fn from_storage_parts(data: S::Vec<u8>, offsets: S::Vec<u64>) -> Self {
95 Self {
96 inner: VarlenContainer::from_storage_parts(data, offsets),
97 }
98 }
99
100 pub fn data_storage(&self) -> &S::Vec<u8> {
101 self.inner.data()
102 }
103
104 pub fn offsets_storage(&self) -> &S::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 is_empty(&self) -> bool {
117 self.inner.is_empty()
118 }
119
120 pub fn clear(&mut self) {
121 self.inner.clear_generic();
122 }
123
124 pub fn get(&self, index: usize) -> Option<&[u8]> {
125 self.inner.get_bytes(index)
126 }
127
128 pub fn is_defined(&self, idx: usize) -> bool {
129 idx < self.len()
130 }
131
132 pub fn data_bytes(&self) -> &[u8] {
133 self.inner.data_bytes()
134 }
135
136 pub fn offsets(&self) -> &[u64] {
137 self.inner.offsets()
138 }
139
140 pub fn inner(&self) -> &VarlenContainer<S> {
141 &self.inner
142 }
143
144 pub fn as_string(&self, index: usize) -> String {
145 match self.get(index) {
146 Some(bytes) => Blob::new(bytes.to_vec()).to_string(),
147 None => "none".to_string(),
148 }
149 }
150
151 pub fn get_value(&self, index: usize) -> Value {
152 match self.get(index) {
153 Some(bytes) => Value::Blob(Blob::new(bytes.to_vec())),
154 None => Value::none_of(ValueType::Blob),
155 }
156 }
157
158 pub fn iter(&self) -> impl Iterator<Item = Option<&[u8]>> + '_ {
159 (0..self.len()).map(|i| self.get(i))
160 }
161
162 pub fn iter_bytes(&self) -> impl Iterator<Item = &[u8]> + '_ {
163 (0..self.len()).map(|i| self.get(i).unwrap_or(&[]))
164 }
165}
166
167impl BlobContainer<Cow> {
168 pub fn push(&mut self, value: Blob) {
169 self.inner.push_bytes(value.as_bytes());
170 }
171
172 pub fn push_bytes(&mut self, value: &[u8]) {
173 self.inner.push_bytes(value);
174 }
175
176 pub fn push_default(&mut self) {
177 self.inner.push_bytes(&[]);
178 }
179
180 pub fn extend(&mut self, other: &Self) -> Result<()> {
181 self.inner.extend_from(&other.inner);
182 Ok(())
183 }
184
185 pub fn slice(&self, start: usize, end: usize) -> Self {
186 Self {
187 inner: self.inner.slice(start, end),
188 }
189 }
190
191 pub fn filter(&mut self, mask: &<Cow as Storage>::BitVec) {
192 let bits: Vec<bool> = mask.iter().collect();
193 self.inner.filter_in_place(|i| bits.get(i).copied().unwrap_or(false));
194 }
195
196 pub fn reorder(&mut self, indices: &[usize]) {
197 self.inner.reorder_in_place(indices);
198 }
199
200 pub fn take(&self, num: usize) -> Self {
201 Self {
202 inner: self.inner.take_n(num),
203 }
204 }
205}
206
207impl Default for BlobContainer<Cow> {
208 fn default() -> Self {
209 Self::with_capacity(0)
210 }
211}
212
213#[cfg(test)]
214pub mod tests {
215 use postcard::to_allocvec as postcard_to_allocvec;
216
217 use super::*;
218
219 #[test]
220 fn test_new() {
221 let blob1 = Blob::new(vec![1, 2, 3]);
222 let blob2 = Blob::new(vec![4, 5, 6]);
223 let blobs = vec![blob1.clone(), blob2.clone()];
224 let container = BlobContainer::new(blobs);
225
226 assert_eq!(container.len(), 2);
227 assert_eq!(container.get(0), Some(blob1.as_bytes()));
228 assert_eq!(container.get(1), Some(blob2.as_bytes()));
229 }
230
231 #[test]
232 fn test_from_vec() {
233 let blob1 = Blob::new(vec![10, 20, 30]);
234 let blob2 = Blob::new(vec![40, 50]);
235 let blobs = vec![blob1.clone(), blob2.clone()];
236 let container = BlobContainer::from_vec(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 for i in 0..2 {
243 assert!(container.is_defined(i));
244 }
245 }
246
247 #[test]
248 fn test_with_capacity() {
249 let container = BlobContainer::with_capacity(10);
250 assert_eq!(container.len(), 0);
251 assert!(container.is_empty());
252 assert!(container.capacity() >= 10);
253 }
254
255 #[test]
256 fn test_push_with_default() {
257 let mut container = BlobContainer::with_capacity(3);
258 let blob1 = Blob::new(vec![1, 2, 3]);
259 let blob2 = Blob::new(vec![7, 8, 9]);
260
261 container.push(blob1.clone());
262 container.push_default();
263 container.push(blob2.clone());
264
265 assert_eq!(container.len(), 3);
266 assert_eq!(container.get(0), Some(blob1.as_bytes()));
267 assert_eq!(container.get(1), Some(b"".as_slice()));
268 assert_eq!(container.get(2), Some(blob2.as_bytes()));
269
270 assert!(container.is_defined(0));
271 assert!(container.is_defined(1));
272 assert!(container.is_defined(2));
273 }
274
275 #[test]
276 fn testault() {
277 let container = BlobContainer::default();
278 assert_eq!(container.len(), 0);
279 assert!(container.is_empty());
280 }
281
282 #[test]
283 fn test_data_bytes_and_offsets_match_zero_copy_layout() {
284 let container = BlobContainer::from_vec(vec![Blob::new(vec![0xAA, 0xBB]), Blob::new(vec![0xCC])]);
285 assert_eq!(container.data_bytes(), &[0xAAu8, 0xBB, 0xCC]);
286 assert_eq!(container.offsets(), &[0u64, 2, 3]);
287 }
288
289 #[test]
290 fn test_postcard_wire_compat() {
291 let blobs = vec![Blob::new(vec![1, 2, 3]), Blob::new(vec![4, 5])];
295 let blobs_bytes: Vec<u8> = postcard_to_allocvec(&blobs).unwrap();
296
297 let container = BlobContainer::from_vec(blobs.clone());
298 let container_bytes: Vec<u8> = postcard_to_allocvec(&container).unwrap();
299
300 assert_eq!(blobs_bytes, container_bytes);
301 }
302}