reifydb_codec/frame/encoding/
rle.rs1use crate::error::DecodeError;
5
6pub fn try_rle_encode<T: PartialEq + Copy>(
7 slice: &[T],
8 elem_size: usize,
9 encode_value: fn(T, &mut Vec<u8>),
10) -> Option<Vec<u8>> {
11 if slice.is_empty() {
12 return None;
13 }
14
15 let mut run_count = 1usize;
16 let mut prev = slice[0];
17 for &v in &slice[1..] {
18 if v != prev {
19 run_count += 1;
20 prev = v;
21 }
22 }
23
24 let rle_size = run_count * (elem_size + 4);
25 let plain_size = slice.len() * elem_size;
26
27 if rle_size >= plain_size {
28 return None;
29 }
30
31 let mut buf = Vec::with_capacity(rle_size);
32 let mut current = slice[0];
33 let mut count: u32 = 1;
34
35 for &v in &slice[1..] {
36 if v == current {
37 count += 1;
38 } else {
39 encode_value(current, &mut buf);
40 buf.extend_from_slice(&count.to_le_bytes());
41 current = v;
42 count = 1;
43 }
44 }
45
46 encode_value(current, &mut buf);
47 buf.extend_from_slice(&count.to_le_bytes());
48
49 Some(buf)
50}
51
52pub fn decode_rle<T: Copy>(
53 data: &[u8],
54 row_count: usize,
55 elem_size: usize,
56 decode_value: fn(&[u8]) -> T,
57) -> Result<Vec<T>, DecodeError> {
58 let mut values = Vec::with_capacity(row_count);
59 let mut pos = 0;
60 let run_size = elem_size + 4;
61
62 while pos + run_size <= data.len() && values.len() < row_count {
63 let value = decode_value(&data[pos..]);
64 pos += elem_size;
65 let count = u32::from_le_bytes([data[pos], data[pos + 1], data[pos + 2], data[pos + 3]]) as usize;
66 pos += 4;
67
68 for _ in 0..count {
69 if values.len() >= row_count {
70 break;
71 }
72 values.push(value);
73 }
74 }
75
76 if values.len() != row_count {
77 return Err(DecodeError::InvalidData(format!(
78 "RLE decoded {} values but expected {}",
79 values.len(),
80 row_count
81 )));
82 }
83
84 Ok(values)
85}
86
87pub fn try_rle_encode_varlen(serialized: &[Vec<u8>]) -> Option<Vec<u8>> {
88 if serialized.is_empty() {
89 return None;
90 }
91
92 let mut rle_size = 4 + serialized[0].len() + 4;
93 let mut prev = &serialized[0];
94
95 for v in &serialized[1..] {
96 if v != prev {
97 rle_size += 4 + v.len() + 4;
98 prev = v;
99 }
100 }
101
102 let total_data: usize = serialized.iter().map(|v| v.len()).sum();
103 let plain_size = (serialized.len() + 1) * 4 + total_data;
104
105 if rle_size >= plain_size {
106 return None;
107 }
108
109 let mut buf = Vec::with_capacity(rle_size);
110 let mut current = &serialized[0];
111 let mut count: u32 = 1;
112
113 for v in &serialized[1..] {
114 if v == current {
115 count += 1;
116 } else {
117 buf.extend_from_slice(&(current.len() as u32).to_le_bytes());
118 buf.extend_from_slice(current);
119 buf.extend_from_slice(&count.to_le_bytes());
120 current = v;
121 count = 1;
122 }
123 }
124
125 buf.extend_from_slice(&(current.len() as u32).to_le_bytes());
126 buf.extend_from_slice(current);
127 buf.extend_from_slice(&count.to_le_bytes());
128
129 Some(buf)
130}
131
132pub fn decode_rle_varlen(data: &[u8], row_count: usize) -> Result<Vec<Vec<u8>>, DecodeError> {
133 let mut values = Vec::with_capacity(row_count);
134 let mut pos = 0;
135
136 while values.len() < row_count && pos + 4 <= data.len() {
137 let value_len = u32::from_le_bytes([data[pos], data[pos + 1], data[pos + 2], data[pos + 3]]) as usize;
138 pos += 4;
139
140 if pos + value_len + 4 > data.len() {
141 return Err(DecodeError::InvalidData("varlen RLE data truncated".to_string()));
142 }
143
144 let value = data[pos..pos + value_len].to_vec();
145 pos += value_len;
146
147 let count = u32::from_le_bytes([data[pos], data[pos + 1], data[pos + 2], data[pos + 3]]) as usize;
148 pos += 4;
149
150 for _ in 0..count {
151 if values.len() >= row_count {
152 break;
153 }
154 values.push(value.clone());
155 }
156 }
157
158 if values.len() != row_count {
159 return Err(DecodeError::InvalidData(format!(
160 "varlen RLE decoded {} values but expected {}",
161 values.len(),
162 row_count
163 )));
164 }
165
166 Ok(values)
167}
168
169pub fn try_rle_i32(slice: &[i32]) -> Option<Vec<u8>> {
170 try_rle_encode(slice, 4, |v, buf| buf.extend_from_slice(&v.to_le_bytes()))
171}
172
173pub fn try_rle_i64(slice: &[i64]) -> Option<Vec<u8>> {
174 try_rle_encode(slice, 8, |v, buf| buf.extend_from_slice(&v.to_le_bytes()))
175}
176
177pub fn try_rle_u64(slice: &[u64]) -> Option<Vec<u8>> {
178 try_rle_encode(slice, 8, |v, buf| buf.extend_from_slice(&v.to_le_bytes()))
179}
180
181pub fn decode_rle_i32(data: &[u8], row_count: usize) -> Result<Vec<i32>, DecodeError> {
182 decode_rle(data, row_count, 4, |b| i32::from_le_bytes([b[0], b[1], b[2], b[3]]))
183}
184
185pub fn decode_rle_i64(data: &[u8], row_count: usize) -> Result<Vec<i64>, DecodeError> {
186 decode_rle(data, row_count, 8, |b| i64::from_le_bytes([b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]]))
187}
188
189pub fn decode_rle_u64(data: &[u8], row_count: usize) -> Result<Vec<u64>, DecodeError> {
190 decode_rle(data, row_count, 8, |b| u64::from_le_bytes([b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]]))
191}