1#![cfg(feature = "ram")]
2
3use crate::{Chunk, ToChunkIncr, ChunkIncr};
12
13#[derive(Debug, Clone, PartialEq, Eq)]
17pub struct Ram {
18 w: u64,
22}
23
24impl Ram {
25 pub fn with_w(w: u64) -> Self {
29 Self {
30 w,
31 }
32 }
33}
34
35impl Chunk for Ram {
36 type SearchState = RamState;
37
38 fn to_search_state(&self) -> Self::SearchState {
39 Default::default()
40 }
41
42 fn find_chunk_edge(&self, state: &mut Self::SearchState, data: &[u8]) -> (Option<usize>, usize) {
43 match state.push(self, data) {
44 Some(i) => (Some(i + 1), i + 1),
45 None => (None, data.len())
46 }
47 }
48}
49
50#[derive(Default, Debug, PartialEq, Eq, Clone)]
51pub struct RamState {
52 i: u64,
54
55 max_val: u8,
57}
58
59impl RamState {
60 fn push(&mut self, params: &Ram, data: &[u8]) -> Option<usize> {
61 let i = self.i;
62
63 for (l_i, b) in data.iter().cloned().enumerate() {
64 if b >= self.max_val {
65 let ri = l_i as u64 + i;
67 if ri > params.w {
68 self.i = 0;
69 self.max_val = 0;
70 return Some(l_i);
71 }
72
73 self.max_val = b;
74 }
75 }
76
77 self.i += data.len() as u64;
78 None
79 }
80}
81
82impl ToChunkIncr for Ram {
83 type Incr = RamIncr;
84
85 fn to_chunk_incr(&self) -> Self::Incr {
86 self.into()
87 }
88}
89
90impl From<&Ram> for RamIncr {
91 fn from(params: &Ram) -> Self {
92 Self {
93 params: params.clone(),
94 state: Default::default(),
95 }
96 }
97}
98
99#[derive(Debug, PartialEq, Eq, Clone)]
100pub struct RamIncr {
101 params: Ram,
102 state: RamState,
103}
104
105impl ChunkIncr for RamIncr {
106 fn push(&mut self, data: &[u8]) -> Option<usize> {
107 self.state.push(&self.params, data)
108 }
109}