Skip to content

Commit f89b485

Browse files
Merge pull request #55 from triblespace/codex/implement-serialization-for-compactvector
Implement CompactVector serialization
2 parents c19b28c + 6ebb90d commit f89b485

File tree

4 files changed

+49
-1
lines changed

4 files changed

+49
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Changelog
22

33
## Unreleased
4+
- Added `CompactVector::to_bytes` and `from_bytes` for zero-copy serialization.
45
- Made `DacsByte` generic over its flag index type with a default of `Rank9SelIndex`.
56
- `DacsByte::from_slice` now accepts a generic index type, removing `from_slice_with_index`.
67
- Added `BitVectorBuilder` and zero-copy `BitVectorData` backed by `anybytes::View`.

INVENTORY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
- Investigate alternative dense-select index strategies to replace removed `DArrayIndex`.
1010
- Explore additional index implementations leveraging the new generic `DacsByte<I>`.
1111
- Demonstrate the generic `from_slice` usage in examples and docs.
12+
- Show `CompactVector::to_bytes` and `from_bytes` in examples.
1213

1314
## Discovered Issues
1415
- `katex.html` performs manual string replacements; consider DOM-based manipulation.

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ is backed by `anybytes::View`. The data can be serialized with
2929
`BitVectorData::to_bytes` and reconstructed using `BitVectorData::from_bytes`,
3030
allowing zero-copy loading from an mmap or any other source by passing the
3131
byte region to `Bytes::from_source`.
32+
`CompactVector` offers similar helpers: `CompactVector::to_bytes` returns a
33+
metadata struct along with the raw bytes, and `CompactVector::from_bytes`
34+
reconstructs the vector from that information.
3235

3336
## Examples
3437

src/int_vectors/compact_vector.rs

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@ use anyhow::{anyhow, Result};
55
use num_traits::ToPrimitive;
66

77
use crate::bit_vector::BitVectorBuilder;
8-
use crate::bit_vector::{BitVector, NoIndex};
8+
use crate::bit_vector::{BitVector, BitVectorData, NoIndex};
99
use crate::int_vectors::prelude::*;
1010
use crate::utils;
11+
use anybytes::Bytes;
1112

1213
/// Mutable builder for [`CompactVector`].
1314
///
@@ -184,6 +185,16 @@ impl Default for CompactVector {
184185
}
185186
}
186187

188+
/// Metadata returned by [`CompactVector::to_bytes`] and required by
189+
/// [`CompactVector::from_bytes`].
190+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
191+
pub struct CompactVectorMeta {
192+
/// Number of integers stored.
193+
pub len: usize,
194+
/// Bit width for each integer.
195+
pub width: usize,
196+
}
197+
187198
impl CompactVector {
188199
/// Creates a new empty builder storing integers within `width` bits each.
189200
///
@@ -411,6 +422,30 @@ impl CompactVector {
411422
pub const fn width(&self) -> usize {
412423
self.width
413424
}
425+
426+
/// Serializes the vector into a [`Bytes`] buffer and accompanying metadata.
427+
pub fn to_bytes(&self) -> (CompactVectorMeta, Bytes) {
428+
let (_, bytes) = self.chunks.data.to_bytes();
429+
(
430+
CompactVectorMeta {
431+
len: self.len,
432+
width: self.width,
433+
},
434+
bytes,
435+
)
436+
}
437+
438+
/// Reconstructs the vector from zero-copy [`Bytes`] and its metadata.
439+
pub fn from_bytes(meta: CompactVectorMeta, bytes: Bytes) -> Result<Self> {
440+
let data_len = meta.len * meta.width;
441+
let data = BitVectorData::from_bytes(data_len, bytes)?;
442+
let chunks = BitVector::new(data, NoIndex);
443+
Ok(Self {
444+
chunks,
445+
len: meta.len,
446+
width: meta.width,
447+
})
448+
}
414449
}
415450

416451
impl Build for CompactVector {
@@ -656,4 +691,12 @@ mod tests {
656691
let cv = CompactVector::from_slice(&[1, 2, 3]).unwrap();
657692
assert_eq!(cv.to_vec(), vec![1, 2, 3]);
658693
}
694+
695+
#[test]
696+
fn from_bytes_roundtrip() {
697+
let cv = CompactVector::from_slice(&[4, 5, 6]).unwrap();
698+
let (meta, bytes) = cv.to_bytes();
699+
let other = CompactVector::from_bytes(meta, bytes).unwrap();
700+
assert_eq!(cv, other);
701+
}
659702
}

0 commit comments

Comments
 (0)