1use std::collections::VecDeque;
3use std::io::Read;
4use std::marker::PhantomData;
5use std::time::Instant;
6use funty::Integral;
7use crate::byte_decode::partial::Partial;
8use crate::fastutils::State;
9use super::bytestream_transform::{IntoU16Transform, IntoU8Transform, U32BytesToU16, U32BytesToU8, U64BytesToU16, U64BytesToU8};
10use super::partial::number_plus_partial;
11use super::u64_fibdecoder_refactor;
13use once_cell::sync::Lazy;
14
15
16#[derive(Debug)]
17pub struct LookupVecNew<T> {
20 table_state0: Vec<(Vec<u64>, Partial)>,
21 table_state1: Vec<(Vec<u64>, Partial)>,
22 dummy: PhantomData<T>,
23}
24impl <T:Integral>LookupVecNew<T> { pub fn new() -> Self {
27 let segment_size = T::BITS as usize;
28
29 let max = usize::pow(2, segment_size as u32);
30
31 let mut table_state0 = Vec::with_capacity(max);
32 let mut table_state1 = Vec::with_capacity(max);
33
34 for lastbit in [true, false]{
35 for s in 0..max {
36
37 let s_tmp: T = match s.try_into() {
40 Ok(i) => i,
41 Err(_) => panic!("cant convert segment to proper u8/u16.."),
42 };
43 let t = s_tmp;
49
50 let mut dd = u64_fibdecoder_refactor::DirtyGenericSingle::new(t);
69 dd.partial = Partial::new(0, 0, lastbit as u64); let numbers = dd.decode_all_from_partial(); if lastbit {
74 table_state1.push((numbers, dd.partial));
75 }
76 else{
77 table_state0.push((numbers, dd.partial));
78 }
79 }
80 }
81 LookupVecNew { table_state0, table_state1, dummy: PhantomData}
82 }
83}
84
85pub trait LookupTableNew<T> {
89 fn lookup(&self, s: State, segment: T) -> (&[u64], &Partial);
92}
93
94impl <T:Integral> LookupTableNew<T> for LookupVecNew<T> {
95 fn lookup(&self, s: State, segment: T) -> (&[u64], &Partial) {
97
98 let idx: usize = match segment.try_into(){
100 Ok(i) => i,
101 Err(_) => panic!("couldnt convert vec index to usize"),
102 };
103
104 let (numbers, partial) = match s {
105 State(false) => self.table_state0.get(idx).unwrap(),
106 State(true) => self.table_state1.get(idx).unwrap(),
107 };
108 (numbers, partial)
109 }
110}
111
112#[cfg(test)]
113mod testing_lookups {
114 use bitvec::prelude::*;
115 use crate::utils::create_bitvector;
116 use super::*;
117 #[test]
120 fn test_vec8_lookup() {
121 let t: LookupVecNew<u8> = LookupVecNew::new();
123 let i = create_bitvector(vec![ 1,0,1,1,0,1,0,1]).load_be::<u8>();
124
125 assert_eq!(
126 t.lookup(State(false), i),
127 (vec![4].as_slice(), &Partial { num:7, i_fibo: 4, last_bit: 1})
128 );
129
130 let i = create_bitvector(vec![ 1,0,1,1,0,1,0,1]).load_be::<u8>();
131 assert_eq!(
132 t.lookup(State(true), i),
133 (vec![0,2].as_slice(), &Partial { num:7, i_fibo: 4, last_bit: 1})
134 );
135
136 let i = create_bitvector(vec![ 0,1,1,1,0,0,1,0]).load_be::<u8>();
137 assert_eq!(
138 t.lookup(State(true), i),
139 (vec![2].as_slice(), &Partial { num:6, i_fibo: 5, last_bit: 0})
140 );
141 assert_eq!(
142 t.lookup(State(false), i),
143 (vec![2].as_slice(), &Partial { num:6, i_fibo: 5, last_bit: 0})
144 );
145 }
146}
147
148
149pub static FB_LOOKUP_NEW_U8: Lazy<LookupVecNew<u8>> = Lazy::new(|| {
152 println!("initializing fibonacci lookup");
153 let now = Instant::now();
154 let lookup = LookupVecNew::new();
155 let elapsed_time: std::time::Duration = now.elapsed();
156 println!("FB_LOOKUP_NEW_U8: done initializing fibonacci lookup in {}us", elapsed_time.as_micros());
157 lookup
158});
159
160pub static FB_LOOKUP_NEW_U16: Lazy<LookupVecNew<u16>> = Lazy::new(|| {
163 println!("initializing fibonacci lookup");
164 let now = Instant::now();
165 let lookup = LookupVecNew::new();
166 let elapsed_time: std::time::Duration = now.elapsed();
167
168 println!("FB_LOOKUP_NEW_U16: done initializing fibonacci lookup in {}us", elapsed_time.as_micros());
169 lookup
170});
171
172pub fn fast_decode_new<T:Integral>(stream: &[T], shifted_by_one: bool, table: &impl LookupTableNew<T>) -> Vec<u64> {
177
178 let mut partial = Partial::new(0, 0, 0);
179 let mut decoded_numbers= Vec::new();
180
181 for &segment_int in stream { let segment_int_pad = segment_int;
189
190 let (numbers, p) = table.lookup(State(partial.last_bit == 1), segment_int_pad);
191 if !numbers.is_empty() {
198 let new_x = number_plus_partial(numbers[0], &partial);
202 decoded_numbers.push(new_x);
204
205 decoded_numbers.extend(&numbers[1..]);
206
207
208 partial = p.clone();
210 } else {
211 let mut newp = p.clone();
214 newp.combine_partial(&partial);
215 partial = newp;
216 }
217 }
218
219 if shifted_by_one{
222 decoded_numbers.iter().map(|x| x - 1).collect::<Vec<u64>>()
223 } else {
224 decoded_numbers
225 }
226}
227
228
229#[cfg(test)]
230mod test {
231 use crate::{byte_decode::byte_manipulation::bits_to_fibonacci_generic_array_u64, utils::create_bitvector};
232 use super::*;
233 #[test]
234 fn test_fast_decode() {
235
236 let bits = create_bitvector(vec![
238 1,0,1,1,0,1,0,1,
239 1,0,1,0,0,1,0,1,
240 0,1,1,1,0,0,1,0]).to_bitvec();
241
242 let bytes = bits_to_fibonacci_generic_array_u64(&bits);
243 let x_u8: Vec<u8> = U64BytesToU8::new(bytes.as_slice()).collect();
244 let x_u16: Vec<u16> = U64BytesToU16::new(bytes.as_slice()).collect();
245
246 let t: LookupVecNew<u8> = LookupVecNew::new();
247 let r = fast_decode_new(&x_u8,false, &t);
248 assert_eq!(r, vec![4,7, 86]);
249
250 let t: LookupVecNew<u16> = LookupVecNew::new();
251 let r = fast_decode_new(&x_u16,false, &t);
252 assert_eq!(r, vec![4,7, 86]);
253 }
254}
255
256
257pub enum StreamType {
259 U64,
261 U32
263}
264pub struct FastFibonacciDecoderNewU8<'a, R:Read> {
271 stream: Box<dyn IntoU8Transform<R> +'a>, lookup_table: &'a LookupVecNew<u8>,
274 current_buffer: VecDeque<Option<u64>>,
276 shifted_by_one: bool,
277 partial: Partial,
278}
279
280impl<'a, R:Read+'a> FastFibonacciDecoderNewU8<'a, R> {
281 pub fn new(stream: R, lookup_table: &'a LookupVecNew<u8>, shifted_by_one: bool, streamtype: StreamType) ->Self {
283 let chunked_u8_stream: Box<dyn IntoU8Transform<R>> = match streamtype {
284 StreamType::U64 => {
285 Box::new(U64BytesToU8::new(stream))
289 },
290 StreamType::U32 => {
291 Box::new(U32BytesToU8::new(stream))
292 },
293 };
294 Self {
295 stream: chunked_u8_stream,
296 lookup_table,
297 current_buffer: VecDeque::with_capacity(8),
298 shifted_by_one,
299 partial: Default::default(),
300 }
301 }
302
303 pub fn load_segment(&mut self) {
305
306 match self.stream.next_u8() {
307 Some(segment_int) => {
308 let segment_int_pad = segment_int;
314 let (numbers, p) = self.lookup_table.lookup(State(self.partial.last_bit == 1), segment_int_pad);
315
316 match numbers.split_first() {
326 Some((first, tail)) => {
327 let new_x = number_plus_partial(*first, &self.partial);
331 self.current_buffer.push_back(Some(new_x));
332 self.current_buffer.extend(tail.iter().map(|&x| Some(x)));
333 self.partial = p.clone();
334 },
335 None => {
336 let mut newp = p.clone();
338 newp.combine_partial(&self.partial);
339 self.partial = newp;
340 },
341 }
342 }
343 None => {
344 assert!(self.partial.is_clean());
348 self.current_buffer.push_back(None);
349 }
350 }
351 }
352
353 pub fn get_consumed_bytes(&self) -> usize {
355 self.stream.get_consumed_bytes()
356 }
357
358 pub fn is_clean(&self) -> bool {
360 self.current_buffer.is_empty() && self.partial.is_clean()
361 }
362}
363
364impl<'a, R:Read+'a> Iterator for FastFibonacciDecoderNewU8<'a, R> {
365 type Item=u64;
366
367 fn next(&mut self) -> Option<Self::Item> {
368
369 while self.current_buffer.is_empty() {
371 self.load_segment()
372 }
373
374 let el = self.current_buffer.pop_front().unwrap(); if self.shifted_by_one {
377 el.map(|x| x - 1)
378 } else {
379 el
380 }
381 }
382}
383
384#[test]
385fn test_fixed_(){
386 let bytes =vec![0,0,0,0,0,0,0,88];
389 let t: LookupVecNew<u8> = LookupVecNew::new();
390 let mut dd = FastFibonacciDecoderNewU8::new(bytes.as_slice(), &t, false, StreamType::U64);
391 assert_eq!(dd.next(), Some(7));
392 assert_eq!(dd.next(), None);
393
394 let bytes =vec![0,0,0,0,0,0,192,90];
395 let t: LookupVecNew<u8> = LookupVecNew::new();
396 let mut dd = FastFibonacciDecoderNewU8::new(bytes.as_slice(), &t, false, StreamType::U64);
397 let x = dd.next();
398 assert_eq!(x, Some(7));
399 let x = dd.next();
400 assert_eq!(x, Some(7));
401 let x = dd.next();
402 assert_eq!(x, None);
403
404 let bytes =vec![0,0,0,88,0,0,0,0];
406 let t: LookupVecNew<u8> = LookupVecNew::new();
407 let mut dd = FastFibonacciDecoderNewU8::new(bytes.as_slice(), &t, false, StreamType::U32);
408 assert_eq!(dd.next(), Some(7));
409 assert_eq!(dd.next(), None);
410
411 let bytes =vec![0,0,192,90,0,0,0,0];
413 let t: LookupVecNew<u8> = LookupVecNew::new();
414 let mut dd = FastFibonacciDecoderNewU8::new(bytes.as_slice(), &t, false, StreamType::U32);
415 assert_eq!(dd.next(), Some(7));
416 assert_eq!(dd.next(), Some(7));
417 assert_eq!(dd.next(), None);
418}
419
420#[test]
421fn test_bytes_consumed_u8() {
422 let bytes =vec![0,0,0,0,0,0,0,88];
425 let t: LookupVecNew<u8> = LookupVecNew::new();
426 let mut dd = FastFibonacciDecoderNewU8::new(bytes.as_slice(), &t, false, StreamType::U64);
427 let x = dd.next();
428 assert_eq!(x, Some(7));
429 assert_eq!(dd.get_consumed_bytes(), 8);
430
431 let bytes =vec![0,0,0,0,0,0,0,88, 0,0,0,0,0,0,0,88];
432 let mut dd = FastFibonacciDecoderNewU8::new(bytes.as_slice(), &t, false, StreamType::U64);
433
434 assert_eq!(dd.next(), Some(7));
435 assert_eq!(dd.get_consumed_bytes(), 8);
436
437 dd.next();
439 assert_eq!(dd.get_consumed_bytes(), 16);
440
441 dd.next();
442 assert_eq!(dd.get_consumed_bytes(), 16);
443
444 assert_eq!(dd.next(), None);
445
446
447 let bytes =vec![0,0,0,88,0,0,0,88, 0,0,0,0, 0,0,0,88];
448
449 let mut dd = FastFibonacciDecoderNewU8::new(bytes.as_slice(), &t, false, StreamType::U32);
450 let x = dd.next();
451 assert_eq!(x, Some(7));
452 assert_eq!(dd.get_consumed_bytes(), 4);
453 dd.next();
454 assert_eq!(x, Some(7));
455 assert_eq!(dd.get_consumed_bytes(), 8);
456 dd.next();
457 assert_eq!(dd.get_consumed_bytes(), 16);
459
460
461}
462
463pub struct FastFibonacciDecoderNewU16<'a, R:Read> {
465 stream: Box<dyn IntoU16Transform<R> +'a>, lookup_table: &'a LookupVecNew<u16>,
468 current_buffer: VecDeque<Option<u64>>,
470 shifted_by_one: bool,
471 partial: Partial,
472}
473
474impl<'a, R:Read+'a> FastFibonacciDecoderNewU16<'a, R> {
475 pub fn new(stream: R, lookup_table: &'a LookupVecNew<u16>, shifted_by_one: bool, streamtype: StreamType) ->Self {
477 let chunked_u16_stream: Box<dyn IntoU16Transform<R>> = match streamtype {
478 StreamType::U64 => {
479 Box::new(U64BytesToU16::new(stream))
483 },
484 StreamType::U32 => {
485 Box::new(U32BytesToU16::new(stream))
486 },
487 };
488 Self {
489 stream: chunked_u16_stream,
490 lookup_table,
491 current_buffer: VecDeque::with_capacity(8), shifted_by_one,
493 partial: Default::default(),
494 }
495 }
496
497 pub fn load_segment(&mut self) {
499
500 match self.stream.next_u16() {
504 Some(segment_int) => {
505 let segment_int_pad = segment_int;
511 let (numbers, p) = self.lookup_table.lookup(State(self.partial.last_bit ==1), segment_int_pad);
512
513 match numbers.split_first() {
523 Some((first, tail)) => {
524 let new_x = number_plus_partial(*first, &self.partial);
528 self.current_buffer.push_back(Some(new_x));
529 self.current_buffer.extend(tail.iter().map(|&x| Some(x)));
530 self.partial = p.clone();
531 },
532 None => {
533 let mut newp = p.clone();
535 newp.combine_partial(&self.partial);
536 self.partial = newp;
537 },
538 }
539 }
540 None => {
541 assert!(self.partial.is_clean());
545 self.current_buffer.push_back(None);
546 }
547 }
548 }
549
550 pub fn get_consumed_bytes(&self) -> usize {
552 self.stream.get_consumed_bytes()
553 }
554
555 pub fn is_clean(&self) -> bool {
557 self.current_buffer.is_empty() && self.partial.is_clean()
558 }
559}
560
561
562impl<'a, R:Read+'a> Iterator for FastFibonacciDecoderNewU16<'a, R> {
563 type Item=u64;
564
565 fn next(&mut self) -> Option<Self::Item> {
566
567
568 while self.current_buffer.is_empty() {
570 self.load_segment()
571 }
572
573 let el = self.current_buffer.pop_front().unwrap(); if self.shifted_by_one {
576 el.map(|x| x - 1)
577 } else {
578 el
579 }
580 }
581}
582
583#[test]
584fn test_fixed_u16(){
585 let bytes =vec![0,0,0,0,0,0,0,88];
588 let t: LookupVecNew<u16> = LookupVecNew::new();
589 let mut dd = FastFibonacciDecoderNewU16::new(bytes.as_slice(), &t, false, StreamType::U64);
590 let x = dd.next();
591
592 assert_eq!(x, Some(7));
593
594
595 let bytes =vec![0,0,0,0,0,0,192,90];
596 let t: LookupVecNew<u16> = LookupVecNew::new();
597 let mut dd = FastFibonacciDecoderNewU16::new(bytes.as_slice(), &t, false, StreamType::U64);
598 let x = dd.next();
599
600 assert_eq!(x, Some(7));
601 let x = dd.next();
602 assert_eq!(x, Some(7));
603
604 let x = dd.next();
605 assert_eq!(x, None);
606}
607
608#[test]
609fn test_bytes_consumed_u16() {
610 let bytes =vec![0,0,0,0,0,0,0,88];
613 let t: LookupVecNew<u16> = LookupVecNew::new();
614 let mut dd = FastFibonacciDecoderNewU16::new(bytes.as_slice(), &t, false, StreamType::U64);
615 assert_eq!(dd.next(), Some(7));
616 assert_eq!(dd.get_consumed_bytes(), 8);
617
618 let bytes =vec![0,0,0,0,0,0,0,88, 0,0,0,0,0,0,0,88];
619 let mut dd = FastFibonacciDecoderNewU16::new(bytes.as_slice(), &t, false, StreamType::U64);
620
621 assert_eq!(dd.next(), Some(7));
622 assert_eq!(dd.get_consumed_bytes(), 8);
623
624 dd.next();
626 assert_eq!(dd.get_consumed_bytes(), 16);
627
628 dd.next();
629 assert_eq!(dd.get_consumed_bytes(), 16);
630
631 assert_eq!(dd.next(), None);
632
633 let bytes =vec![0,0,0,88,0,0,0,88, 0,0,0,0,0,0,0,88];
634 let mut dd = FastFibonacciDecoderNewU16::new(bytes.as_slice(), &t, false, StreamType::U32);
635 assert_eq!(dd.next(), Some(7));
636 assert_eq!(dd.get_consumed_bytes(), 4);
637 dd.next();
638 assert_eq!(dd.get_consumed_bytes(), 8);
639 dd.next();
640 assert_eq!(dd.get_consumed_bytes(), 16);
641
642}