@@ -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 ) ]
1717pub 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
442470impl < 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