Skip to content

Commit 5f89ade

Browse files
Merge pull request #61 from triblespace/codex/add-bytes-field-to-rank9selindex
Store bytes in Rank9SelIndex
2 parents 7a874d0 + 365af00 commit 5f89ade

File tree

2 files changed

+53
-48
lines changed

2 files changed

+53
-48
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
- `DacsByte::from_slice` now accepts a generic index type, removing `from_slice_with_index`.
99
- Added `BitVectorBuilder` and zero-copy `BitVectorData` backed by `anybytes::View`.
1010
- Introduced `IndexBuilder` trait with a `Built` type and adjusted serialization helpers.
11+
- `Rank9SelIndex` now stores its serialized bytes internally and `to_bytes` returns this buffer.
1112
- Rename crate to `succdisk` to reflect on-disk succinct data structures.
1213
- Rename crate from `succdisk` to `jerky`.
1314
- Replaced the old `BitVector` with the generic `BitVector<I>` and renamed the

src/bit_vector/rank9sel/inner.rs

Lines changed: 52 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ const SELECT_ZEROS_PER_HINT: usize = SELECT_ONES_PER_HINT;
1515
/// The index implementation separated from the bit vector.
1616
#[derive(Debug, Clone, PartialEq, Eq)]
1717
pub struct Rank9SelIndex<const SELECT1: bool = true, const SELECT0: bool = true> {
18+
bytes: Bytes,
1819
len: usize,
1920
block_rank_pairs: View<[usize]>,
2021
select1_hints: Option<View<[usize]>>,
@@ -48,16 +49,43 @@ impl<const SELECT1: bool, const SELECT0: bool> Rank9SelIndexBuilder<SELECT1, SEL
4849

4950
/// Freezes and returns [`Rank9SelIndex`].
5051
pub fn build(self) -> Rank9SelIndex<SELECT1, SELECT0> {
51-
let block_rank_pairs = Bytes::from_source(self.block_rank_pairs)
52-
.view::<[usize]>()
53-
.unwrap();
54-
let select1_hints = self
55-
.select1_hints
56-
.map(|v| Bytes::from_source(v).view::<[usize]>().unwrap());
57-
let select0_hints = self
58-
.select0_hints
59-
.map(|v| Bytes::from_source(v).view::<[usize]>().unwrap());
52+
let mut store = Vec::new();
53+
store.push(self.len);
54+
store.push(self.block_rank_pairs.len());
55+
store.extend_from_slice(&self.block_rank_pairs);
56+
57+
if SELECT1 {
58+
let hints = self.select1_hints.unwrap_or_default();
59+
store.push(hints.len());
60+
store.extend_from_slice(&hints);
61+
}
62+
63+
if SELECT0 {
64+
let hints = self.select0_hints.unwrap_or_default();
65+
store.push(hints.len());
66+
store.extend_from_slice(&hints);
67+
}
68+
69+
let bytes = Bytes::from_source(store);
70+
let mut parser = bytes.clone();
71+
let _len = *parser.view_prefix::<usize>().unwrap();
72+
let brp_len = *parser.view_prefix::<usize>().unwrap();
73+
let block_rank_pairs = parser.view_prefix_with_elems::<[usize]>(brp_len).unwrap();
74+
let select1_hints = if SELECT1 {
75+
let l = *parser.view_prefix::<usize>().unwrap();
76+
Some(parser.view_prefix_with_elems::<[usize]>(l).unwrap())
77+
} else {
78+
None
79+
};
80+
let select0_hints = if SELECT0 {
81+
let l = *parser.view_prefix::<usize>().unwrap();
82+
Some(parser.view_prefix_with_elems::<[usize]>(l).unwrap())
83+
} else {
84+
None
85+
};
86+
6087
Rank9SelIndex::<SELECT1, SELECT0> {
88+
bytes,
6189
len: self.len,
6290
block_rank_pairs,
6391
select1_hints,
@@ -441,52 +469,46 @@ impl<const SELECT1: bool, const SELECT0: bool> Rank9SelIndex<SELECT1, SELECT0> {
441469

442470
impl<const SELECT1: bool, const SELECT0: bool> Rank9SelIndex<SELECT1, SELECT0> {
443471
/// Reconstructs the index from zero-copy [`Bytes`].
444-
pub fn from_bytes(mut bytes: Bytes) -> Result<Self> {
445-
let len = *bytes
472+
pub fn from_bytes(bytes: Bytes) -> Result<Self> {
473+
let mut parser = bytes.clone();
474+
let len = *parser
446475
.view_prefix::<usize>()
447476
.map_err(|e| anyhow::anyhow!(e))?;
448-
let brp_len = *bytes
477+
let brp_len = *parser
449478
.view_prefix::<usize>()
450479
.map_err(|e| anyhow::anyhow!(e))?;
451-
let block_rank_pairs = bytes
480+
let block_rank_pairs = parser
452481
.view_prefix_with_elems::<[usize]>(brp_len)
453482
.map_err(|e| anyhow::anyhow!(e))?;
454-
let has_select1 = *bytes
455-
.view_prefix::<usize>()
456-
.map_err(|e| anyhow::anyhow!(e))?
457-
!= 0;
458-
let select1_hints = if has_select1 {
459-
let l = *bytes
483+
let select1_hints = if SELECT1 {
484+
let l = *parser
460485
.view_prefix::<usize>()
461486
.map_err(|e| anyhow::anyhow!(e))?;
462487
Some(
463-
bytes
488+
parser
464489
.view_prefix_with_elems::<[usize]>(l)
465490
.map_err(|e| anyhow::anyhow!(e))?,
466491
)
467492
} else {
468493
None
469494
};
470-
let has_select0 = *bytes
471-
.view_prefix::<usize>()
472-
.map_err(|e| anyhow::anyhow!(e))?
473-
!= 0;
474-
let select0_hints = if has_select0 {
475-
let l = *bytes
495+
let select0_hints = if SELECT0 {
496+
let l = *parser
476497
.view_prefix::<usize>()
477498
.map_err(|e| anyhow::anyhow!(e))?;
478499
Some(
479-
bytes
500+
parser
480501
.view_prefix_with_elems::<[usize]>(l)
481502
.map_err(|e| anyhow::anyhow!(e))?,
482503
)
483504
} else {
484505
None
485506
};
486-
if has_select1 != SELECT1 || has_select0 != SELECT0 {
487-
return Err(anyhow::anyhow!("mismatched hint flags"));
507+
if !parser.as_ref().is_empty() {
508+
return Err(anyhow::anyhow!("extra bytes"));
488509
}
489510
Ok(Self {
511+
bytes,
490512
len,
491513
block_rank_pairs,
492514
select1_hints,
@@ -496,25 +518,7 @@ impl<const SELECT1: bool, const SELECT0: bool> Rank9SelIndex<SELECT1, SELECT0> {
496518

497519
/// Serializes the index metadata and data into a [`Bytes`] buffer.
498520
pub fn to_bytes(&self) -> Bytes {
499-
let mut store: Vec<usize> = Vec::new();
500-
store.push(self.len);
501-
store.push(self.block_rank_pairs.len());
502-
store.extend_from_slice(self.block_rank_pairs.as_ref());
503-
if let Some(ref v) = self.select1_hints {
504-
store.push(1);
505-
store.push(v.len());
506-
store.extend_from_slice(v.as_ref());
507-
} else {
508-
store.push(0);
509-
}
510-
if let Some(ref v) = self.select0_hints {
511-
store.push(1);
512-
store.push(v.len());
513-
store.extend_from_slice(v.as_ref());
514-
} else {
515-
store.push(0);
516-
}
517-
Bytes::from_source(store)
521+
self.bytes.clone()
518522
}
519523
}
520524

0 commit comments

Comments
 (0)