@@ -30,12 +30,36 @@ use super::{
3030
3131const MAX_RUN_LENGTH : usize = 130 ;
3232
33+ #[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash ) ]
34+ // TODO: put header data in here, e.g. base value, len, etc.
35+ enum EncodingType {
36+ Run { length : usize } ,
37+ Literals { length : usize } ,
38+ }
39+
40+ impl EncodingType {
41+ /// Decode header byte to determine sub-encoding.
42+ /// Runs start with a positive byte, and literals with a negative byte.
43+ #[ inline]
44+ fn from_header ( header : u8 ) -> Self {
45+ let header = header as i8 ;
46+ if header < 0 {
47+ let length = header. unsigned_abs ( ) as usize ;
48+ Self :: Literals { length }
49+ } else {
50+ // Technically +3 but we subtract 1 for the base
51+ let length = header as u8 as usize + 2 ;
52+ Self :: Run { length }
53+ }
54+ }
55+ }
56+
3357/// Decodes a stream of Integer Run Length Encoded version 1 bytes.
3458pub struct RleReaderV1 < N : NInt , R : Read , S : EncodingSign > {
3559 reader : R ,
3660 decoded_ints : Vec < N > ,
3761 current_head : usize ,
38- phantom : PhantomData < S > ,
62+ sign : PhantomData < S > ,
3963}
4064
4165impl < N : NInt , R : Read , S : EncodingSign > RleReaderV1 < N , R , S > {
@@ -44,56 +68,71 @@ impl<N: NInt, R: Read, S: EncodingSign> RleReaderV1<N, R, S> {
4468 reader,
4569 decoded_ints : Vec :: with_capacity ( MAX_RUN_LENGTH ) ,
4670 current_head : 0 ,
47- phantom : Default :: default ( ) ,
71+ sign : Default :: default ( ) ,
4872 }
4973 }
5074
5175 fn decode_batch ( & mut self ) -> Result < ( ) > {
5276 self . current_head = 0 ;
5377 self . decoded_ints . clear ( ) ;
54- match try_read_u8 ( & mut self . reader ) ?. map ( |byte| byte as i8 ) {
55- // Literals
56- Some ( byte) if byte < 0 => {
57- let length = byte. unsigned_abs ( ) ;
58- for _ in 0 ..length {
59- let lit = read_varint_zigzagged :: < _ , _ , S > ( & mut self . reader ) ?;
60- self . decoded_ints . push ( lit) ;
61- }
62- Ok ( ( ) )
78+ let header = match try_read_u8 ( & mut self . reader ) ? {
79+ Some ( byte) => byte,
80+ None => return Ok ( ( ) ) ,
81+ } ;
82+
83+ match EncodingType :: from_header ( header) {
84+ EncodingType :: Literals { length } => {
85+ read_literals :: < _ , _ , S > ( & mut self . reader , & mut self . decoded_ints , length)
6386 }
64- // Run
65- Some ( byte) => {
66- let byte = byte as u8 ;
67- let length = byte + 2 ; // Technically +3, but we subtract 1 for the base
68- let delta = read_u8 ( & mut self . reader ) ? as i8 ;
69- let mut base = read_varint_zigzagged :: < _ , _ , S > ( & mut self . reader ) ?;
70- self . decoded_ints . push ( base) ;
71- if delta < 0 {
72- let delta = delta. unsigned_abs ( ) ;
73- let delta = N :: from_u8 ( delta) ;
74- for _ in 0 ..length {
75- base = base. checked_sub ( & delta) . context ( OutOfSpecSnafu {
76- msg : "over/underflow when decoding patched base integer" ,
77- } ) ?;
78- self . decoded_ints . push ( base) ;
79- }
80- } else {
81- let delta = delta as u8 ;
82- let delta = N :: from_u8 ( delta) ;
83- for _ in 0 ..length {
84- base = base. checked_add ( & delta) . context ( OutOfSpecSnafu {
85- msg : "over/underflow when decoding patched base integer" ,
86- } ) ?;
87- self . decoded_ints . push ( base) ;
88- }
89- }
90- Ok ( ( ) )
87+ EncodingType :: Run { length } => {
88+ read_run :: < _ , _ , S > ( & mut self . reader , & mut self . decoded_ints , length)
9189 }
92- None => Ok ( ( ) ) ,
9390 }
9491 }
9592}
9693
94+ fn read_literals < N : NInt , R : Read , S : EncodingSign > (
95+ reader : & mut R ,
96+ out_ints : & mut Vec < N > ,
97+ length : usize ,
98+ ) -> Result < ( ) > {
99+ for _ in 0 ..length {
100+ let lit = read_varint_zigzagged :: < _ , _ , S > ( reader) ?;
101+ out_ints. push ( lit) ;
102+ }
103+ Ok ( ( ) )
104+ }
105+
106+ fn read_run < N : NInt , R : Read , S : EncodingSign > (
107+ reader : & mut R ,
108+ out_ints : & mut Vec < N > ,
109+ length : usize ,
110+ ) -> Result < ( ) > {
111+ let delta = read_u8 ( reader) ? as i8 ;
112+ let mut base = read_varint_zigzagged :: < _ , _ , S > ( reader) ?;
113+ out_ints. push ( base) ;
114+ if delta < 0 {
115+ let delta = delta. unsigned_abs ( ) ;
116+ let delta = N :: from_u8 ( delta) ;
117+ for _ in 0 ..length {
118+ base = base. checked_sub ( & delta) . context ( OutOfSpecSnafu {
119+ msg : "over/underflow when decoding patched base integer" ,
120+ } ) ?;
121+ out_ints. push ( base) ;
122+ }
123+ } else {
124+ let delta = delta as u8 ;
125+ let delta = N :: from_u8 ( delta) ;
126+ for _ in 0 ..length {
127+ base = base. checked_add ( & delta) . context ( OutOfSpecSnafu {
128+ msg : "over/underflow when decoding patched base integer" ,
129+ } ) ?;
130+ out_ints. push ( base) ;
131+ }
132+ }
133+ Ok ( ( ) )
134+ }
135+
97136impl < N : NInt , R : Read , S : EncodingSign > PrimitiveValueDecoder < N > for RleReaderV1 < N , R , S > {
98137 // TODO: this is exact duplicate from RLEv2 version; deduplicate it
99138 fn decode ( & mut self , out : & mut [ N ] ) -> Result < ( ) > {
0 commit comments