Skip to main content

reifydb_codec/frame/encoding/
delta.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2026 ReifyDB
3
4use crate::error::DecodeError;
5
6pub fn try_delta_i32(slice: &[i32]) -> Option<Vec<u8>> {
7	if slice.len() < 2 {
8		return None;
9	}
10
11	let deltas: Vec<i64> = slice.windows(2).map(|w| w[1] as i64 - w[0] as i64).collect();
12	let width = delta_width(&deltas);
13
14	let delta_size = 1 + 4 + (slice.len() - 1) * width;
15	let plain_size = slice.len() * 4;
16
17	if delta_size >= plain_size {
18		return None;
19	}
20
21	let mut buf = Vec::with_capacity(delta_size);
22	buf.push(width as u8);
23	buf.extend_from_slice(&slice[0].to_le_bytes());
24	encode_deltas(&deltas, width, &mut buf);
25	Some(buf)
26}
27
28pub fn try_delta_i64(slice: &[i64]) -> Option<Vec<u8>> {
29	if slice.len() < 2 {
30		return None;
31	}
32
33	let deltas: Vec<i64> = slice.windows(2).map(|w| w[1].wrapping_sub(w[0])).collect();
34	let width = delta_width(&deltas);
35
36	let delta_size = 1 + 8 + (slice.len() - 1) * width;
37	let plain_size = slice.len() * 8;
38
39	if delta_size >= plain_size {
40		return None;
41	}
42
43	let mut buf = Vec::with_capacity(delta_size);
44	buf.push(width as u8);
45	buf.extend_from_slice(&slice[0].to_le_bytes());
46	encode_deltas(&deltas, width, &mut buf);
47	Some(buf)
48}
49
50pub fn try_delta_u64(slice: &[u64]) -> Option<Vec<u8>> {
51	if slice.len() < 2 {
52		return None;
53	}
54
55	let deltas: Vec<i64> = slice.windows(2).map(|w| w[1] as i64 - w[0] as i64).collect();
56	let width = delta_width(&deltas);
57
58	let delta_size = 1 + 8 + (slice.len() - 1) * width;
59	let plain_size = slice.len() * 8;
60
61	if delta_size >= plain_size {
62		return None;
63	}
64
65	let mut buf = Vec::with_capacity(delta_size);
66	buf.push(width as u8);
67	buf.extend_from_slice(&slice[0].to_le_bytes());
68	encode_deltas(&deltas, width, &mut buf);
69	Some(buf)
70}
71
72pub fn try_delta_rle_i32(slice: &[i32]) -> Option<Vec<u8>> {
73	if slice.len() < 2 {
74		return None;
75	}
76
77	let deltas: Vec<i64> = slice.windows(2).map(|w| w[1] as i64 - w[0] as i64).collect();
78	let width = delta_width(&deltas);
79	let runs = rle_runs(&deltas);
80
81	let drle_size = 1 + 4 + runs.len() * (width + 4);
82	let plain_size = slice.len() * 4;
83
84	if drle_size >= plain_size {
85		return None;
86	}
87
88	let mut buf = Vec::with_capacity(drle_size);
89	buf.push(width as u8);
90	buf.extend_from_slice(&slice[0].to_le_bytes());
91	encode_delta_rle_runs(&runs, width, &mut buf);
92	Some(buf)
93}
94
95pub fn try_delta_rle_i64(slice: &[i64]) -> Option<Vec<u8>> {
96	if slice.len() < 2 {
97		return None;
98	}
99
100	let deltas: Vec<i64> = slice.windows(2).map(|w| w[1].wrapping_sub(w[0])).collect();
101	let width = delta_width(&deltas);
102	let runs = rle_runs(&deltas);
103
104	let drle_size = 1 + 8 + runs.len() * (width + 4);
105	let plain_size = slice.len() * 8;
106
107	if drle_size >= plain_size {
108		return None;
109	}
110
111	let mut buf = Vec::with_capacity(drle_size);
112	buf.push(width as u8);
113	buf.extend_from_slice(&slice[0].to_le_bytes());
114	encode_delta_rle_runs(&runs, width, &mut buf);
115	Some(buf)
116}
117
118pub fn try_delta_rle_u64(slice: &[u64]) -> Option<Vec<u8>> {
119	if slice.len() < 2 {
120		return None;
121	}
122
123	let deltas: Vec<i64> = slice.windows(2).map(|w| w[1] as i64 - w[0] as i64).collect();
124	let width = delta_width(&deltas);
125	let runs = rle_runs(&deltas);
126
127	let drle_size = 1 + 8 + runs.len() * (width + 4);
128	let plain_size = slice.len() * 8;
129
130	if drle_size >= plain_size {
131		return None;
132	}
133
134	let mut buf = Vec::with_capacity(drle_size);
135	buf.push(width as u8);
136	buf.extend_from_slice(&slice[0].to_le_bytes());
137	encode_delta_rle_runs(&runs, width, &mut buf);
138	Some(buf)
139}
140
141pub fn decode_delta_i32(data: &[u8], row_count: usize) -> Result<Vec<i32>, DecodeError> {
142	if row_count == 0 {
143		return Ok(vec![]);
144	}
145	if data.len() < 5 {
146		return Err(DecodeError::InvalidData("delta i32 data too short".into()));
147	}
148
149	let width = data[0] as usize;
150	let baseline = i32::from_le_bytes([data[1], data[2], data[3], data[4]]);
151
152	let mut values = Vec::with_capacity(row_count);
153	values.push(baseline);
154
155	let mut pos = 5;
156	for _ in 1..row_count {
157		let delta = read_signed_delta(&data[pos..], width);
158		pos += width;
159		let prev = *values.last().unwrap();
160		values.push(prev.wrapping_add(delta as i32));
161	}
162
163	Ok(values)
164}
165
166pub fn decode_delta_i64(data: &[u8], row_count: usize) -> Result<Vec<i64>, DecodeError> {
167	if row_count == 0 {
168		return Ok(vec![]);
169	}
170	if data.len() < 9 {
171		return Err(DecodeError::InvalidData("delta i64 data too short".into()));
172	}
173
174	let width = data[0] as usize;
175	let baseline = i64::from_le_bytes([data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8]]);
176
177	let mut values = Vec::with_capacity(row_count);
178	values.push(baseline);
179
180	let mut pos = 9;
181	for _ in 1..row_count {
182		let delta = read_signed_delta(&data[pos..], width);
183		pos += width;
184		let prev = *values.last().unwrap();
185		values.push(prev.wrapping_add(delta));
186	}
187
188	Ok(values)
189}
190
191pub fn decode_delta_u64(data: &[u8], row_count: usize) -> Result<Vec<u64>, DecodeError> {
192	if row_count == 0 {
193		return Ok(vec![]);
194	}
195	if data.len() < 9 {
196		return Err(DecodeError::InvalidData("delta u64 data too short".into()));
197	}
198
199	let width = data[0] as usize;
200	let baseline = u64::from_le_bytes([data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8]]);
201
202	let mut values = Vec::with_capacity(row_count);
203	values.push(baseline);
204
205	let mut pos = 9;
206	for _ in 1..row_count {
207		let delta = read_signed_delta(&data[pos..], width);
208		pos += width;
209		let prev = *values.last().unwrap();
210		values.push((prev as i64).wrapping_add(delta) as u64);
211	}
212
213	Ok(values)
214}
215
216pub fn decode_delta_rle_i32(data: &[u8], row_count: usize) -> Result<Vec<i32>, DecodeError> {
217	if row_count == 0 {
218		return Ok(vec![]);
219	}
220	if data.len() < 5 {
221		return Err(DecodeError::InvalidData("delta_rle i32 data too short".into()));
222	}
223
224	let width = data[0] as usize;
225	let baseline = i32::from_le_bytes([data[1], data[2], data[3], data[4]]);
226
227	let mut values = Vec::with_capacity(row_count);
228	values.push(baseline);
229
230	let mut pos = 5;
231	while values.len() < row_count && pos + width + 4 <= data.len() {
232		let delta = read_signed_delta(&data[pos..], width);
233		pos += width;
234		let count = u32::from_le_bytes([data[pos], data[pos + 1], data[pos + 2], data[pos + 3]]) as usize;
235		pos += 4;
236
237		for _ in 0..count {
238			if values.len() >= row_count {
239				break;
240			}
241			let prev = *values.last().unwrap();
242			values.push(prev.wrapping_add(delta as i32));
243		}
244	}
245
246	if values.len() != row_count {
247		return Err(DecodeError::InvalidData(format!(
248			"delta_rle decoded {} values but expected {}",
249			values.len(),
250			row_count
251		)));
252	}
253
254	Ok(values)
255}
256
257pub fn decode_delta_rle_i64(data: &[u8], row_count: usize) -> Result<Vec<i64>, DecodeError> {
258	if row_count == 0 {
259		return Ok(vec![]);
260	}
261	if data.len() < 9 {
262		return Err(DecodeError::InvalidData("delta_rle i64 data too short".into()));
263	}
264
265	let width = data[0] as usize;
266	let baseline = i64::from_le_bytes([data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8]]);
267
268	let mut values = Vec::with_capacity(row_count);
269	values.push(baseline);
270
271	let mut pos = 9;
272	while values.len() < row_count && pos + width + 4 <= data.len() {
273		let delta = read_signed_delta(&data[pos..], width);
274		pos += width;
275		let count = u32::from_le_bytes([data[pos], data[pos + 1], data[pos + 2], data[pos + 3]]) as usize;
276		pos += 4;
277
278		for _ in 0..count {
279			if values.len() >= row_count {
280				break;
281			}
282			let prev = *values.last().unwrap();
283			values.push(prev.wrapping_add(delta));
284		}
285	}
286
287	if values.len() != row_count {
288		return Err(DecodeError::InvalidData(format!(
289			"delta_rle decoded {} values but expected {}",
290			values.len(),
291			row_count
292		)));
293	}
294
295	Ok(values)
296}
297
298pub fn decode_delta_rle_u64(data: &[u8], row_count: usize) -> Result<Vec<u64>, DecodeError> {
299	if row_count == 0 {
300		return Ok(vec![]);
301	}
302	if data.len() < 9 {
303		return Err(DecodeError::InvalidData("delta_rle u64 data too short".into()));
304	}
305
306	let width = data[0] as usize;
307	let baseline = u64::from_le_bytes([data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8]]);
308
309	let mut values = Vec::with_capacity(row_count);
310	values.push(baseline);
311
312	let mut pos = 9;
313	while values.len() < row_count && pos + width + 4 <= data.len() {
314		let delta = read_signed_delta(&data[pos..], width);
315		pos += width;
316		let count = u32::from_le_bytes([data[pos], data[pos + 1], data[pos + 2], data[pos + 3]]) as usize;
317		pos += 4;
318
319		for _ in 0..count {
320			if values.len() >= row_count {
321				break;
322			}
323			let prev = *values.last().unwrap();
324			values.push((prev as i64).wrapping_add(delta) as u64);
325		}
326	}
327
328	if values.len() != row_count {
329		return Err(DecodeError::InvalidData(format!(
330			"delta_rle decoded {} values but expected {}",
331			values.len(),
332			row_count
333		)));
334	}
335
336	Ok(values)
337}
338
339macro_rules! impl_delta_int128 {
340	($ty:ident, $try_fn:ident, $try_rle_fn:ident, $dec_fn:ident, $dec_rle_fn:ident, $width:expr) => {
341		pub fn $try_fn(slice: &[$ty]) -> Option<Vec<u8>> {
342			if slice.len() < 2 {
343				return None;
344			}
345			let deltas: Vec<i128> =
346				slice.windows(2).map(|w| (w[1] as i128).wrapping_sub(w[0] as i128)).collect();
347			let width = delta_width_i128(&deltas);
348			let delta_size = 1 + $width + (slice.len() - 1) * width;
349			if delta_size >= slice.len() * $width {
350				return None;
351			}
352			let mut buf = Vec::with_capacity(delta_size);
353			buf.push(width as u8);
354			buf.extend_from_slice(&slice[0].to_le_bytes());
355			encode_deltas_i128(&deltas, width, &mut buf);
356			Some(buf)
357		}
358		pub fn $try_rle_fn(slice: &[$ty]) -> Option<Vec<u8>> {
359			if slice.len() < 2 {
360				return None;
361			}
362			let deltas: Vec<i128> =
363				slice.windows(2).map(|w| (w[1] as i128).wrapping_sub(w[0] as i128)).collect();
364			let width = delta_width_i128(&deltas);
365			let runs = rle_runs_i128(&deltas);
366			let drle_size = 1 + $width + runs.len() * (width + 4);
367			if drle_size >= slice.len() * $width {
368				return None;
369			}
370			let mut buf = Vec::with_capacity(drle_size);
371			buf.push(width as u8);
372			buf.extend_from_slice(&slice[0].to_le_bytes());
373			encode_delta_rle_runs_i128(&runs, width, &mut buf);
374			Some(buf)
375		}
376		pub fn $dec_fn(data: &[u8], row_count: usize) -> Result<Vec<$ty>, DecodeError> {
377			if row_count == 0 {
378				return Ok(vec![]);
379			}
380			if data.len() < 1 + $width {
381				return Err(DecodeError::InvalidData("delta data too short".into()));
382			}
383			let width = data[0] as usize;
384			let mut array = [0u8; $width];
385			array.copy_from_slice(&data[1..1 + $width]);
386			let baseline = $ty::from_le_bytes(array);
387			let mut values = Vec::with_capacity(row_count);
388			values.push(baseline);
389			let mut pos = 1 + $width;
390			for _ in 1..row_count {
391				let delta = read_signed_delta_i128(&data[pos..], width);
392				pos += width;
393				let prev = *values.last().unwrap();
394				values.push((prev as i128).wrapping_add(delta) as $ty);
395			}
396			Ok(values)
397		}
398		pub fn $dec_rle_fn(data: &[u8], row_count: usize) -> Result<Vec<$ty>, DecodeError> {
399			if row_count == 0 {
400				return Ok(vec![]);
401			}
402			if data.len() < 1 + $width {
403				return Err(DecodeError::InvalidData("delta rle data too short".into()));
404			}
405			let width = data[0] as usize;
406			let mut array = [0u8; $width];
407			array.copy_from_slice(&data[1..1 + $width]);
408			let baseline = $ty::from_le_bytes(array);
409			let mut values = Vec::with_capacity(row_count);
410			values.push(baseline);
411			let mut pos = 1 + $width;
412			while values.len() < row_count && pos + width + 4 <= data.len() {
413				let delta = read_signed_delta_i128(&data[pos..], width);
414				pos += width;
415				let mut count_arr = [0u8; 4];
416				count_arr.copy_from_slice(&data[pos..pos + 4]);
417				let count = u32::from_le_bytes(count_arr) as usize;
418				pos += 4;
419				for _ in 0..count {
420					if values.len() >= row_count {
421						break;
422					}
423					let prev = *values.last().unwrap();
424					values.push((prev as i128).wrapping_add(delta) as $ty);
425				}
426			}
427			if values.len() != row_count {
428				return Err(DecodeError::InvalidData("delta rle count mismatch".into()));
429			}
430			Ok(values)
431		}
432	};
433}
434
435impl_delta_int128!(i128, try_delta_i128, try_delta_rle_i128, decode_delta_i128, decode_delta_rle_i128, 16);
436impl_delta_int128!(u128, try_delta_u128, try_delta_rle_u128, decode_delta_u128, decode_delta_rle_u128, 16);
437
438fn delta_width(deltas: &[i64]) -> usize {
439	let min = deltas.iter().copied().min().unwrap_or(0);
440	let max = deltas.iter().copied().max().unwrap_or(0);
441
442	if min >= i8::MIN as i64 && max <= i8::MAX as i64 {
443		1
444	} else if min >= i16::MIN as i64 && max <= i16::MAX as i64 {
445		2
446	} else if min >= i32::MIN as i64 && max <= i32::MAX as i64 {
447		4
448	} else {
449		8
450	}
451}
452
453fn encode_deltas(deltas: &[i64], width: usize, buf: &mut Vec<u8>) {
454	for &d in deltas {
455		write_signed_delta(d, width, buf);
456	}
457}
458
459fn rle_runs(deltas: &[i64]) -> Vec<(i64, u32)> {
460	if deltas.is_empty() {
461		return vec![];
462	}
463	let mut runs = Vec::new();
464	let mut current = deltas[0];
465	let mut count: u32 = 1;
466
467	for &d in &deltas[1..] {
468		if d == current {
469			count += 1;
470		} else {
471			runs.push((current, count));
472			current = d;
473			count = 1;
474		}
475	}
476	runs.push((current, count));
477	runs
478}
479
480fn encode_delta_rle_runs(runs: &[(i64, u32)], width: usize, buf: &mut Vec<u8>) {
481	for &(delta, count) in runs {
482		write_signed_delta(delta, width, buf);
483		buf.extend_from_slice(&count.to_le_bytes());
484	}
485}
486
487fn write_signed_delta(delta: i64, width: usize, buf: &mut Vec<u8>) {
488	match width {
489		1 => buf.push(delta as i8 as u8),
490		2 => buf.extend_from_slice(&(delta as i16).to_le_bytes()),
491		4 => buf.extend_from_slice(&(delta as i32).to_le_bytes()),
492		8 => buf.extend_from_slice(&delta.to_le_bytes()),
493		_ => unreachable!(),
494	}
495}
496
497fn read_signed_delta(data: &[u8], width: usize) -> i64 {
498	match width {
499		1 => data[0] as i8 as i64,
500		2 => i16::from_le_bytes([data[0], data[1]]) as i64,
501		4 => i32::from_le_bytes([data[0], data[1], data[2], data[3]]) as i64,
502		8 => i64::from_le_bytes([data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]]),
503		_ => unreachable!(),
504	}
505}
506
507fn delta_width_i128(deltas: &[i128]) -> usize {
508	let min = deltas.iter().copied().min().unwrap_or(0);
509	let max = deltas.iter().copied().max().unwrap_or(0);
510
511	if min >= i8::MIN as i128 && max <= i8::MAX as i128 {
512		1
513	} else if min >= i16::MIN as i128 && max <= i16::MAX as i128 {
514		2
515	} else if min >= i32::MIN as i128 && max <= i32::MAX as i128 {
516		4
517	} else if min >= i64::MIN as i128 && max <= i64::MAX as i128 {
518		8
519	} else {
520		16
521	}
522}
523
524fn encode_deltas_i128(deltas: &[i128], width: usize, buf: &mut Vec<u8>) {
525	for &d in deltas {
526		write_signed_delta_i128(d, width, buf);
527	}
528}
529
530fn rle_runs_i128(deltas: &[i128]) -> Vec<(i128, u32)> {
531	if deltas.is_empty() {
532		return vec![];
533	}
534	let mut runs = Vec::new();
535	let mut current = deltas[0];
536	let mut count: u32 = 1;
537
538	for &d in &deltas[1..] {
539		if d == current {
540			count += 1;
541		} else {
542			runs.push((current, count));
543			current = d;
544			count = 1;
545		}
546	}
547	runs.push((current, count));
548	runs
549}
550
551fn encode_delta_rle_runs_i128(runs: &[(i128, u32)], width: usize, buf: &mut Vec<u8>) {
552	for &(delta, count) in runs {
553		write_signed_delta_i128(delta, width, buf);
554		buf.extend_from_slice(&count.to_le_bytes());
555	}
556}
557
558fn write_signed_delta_i128(delta: i128, width: usize, buf: &mut Vec<u8>) {
559	match width {
560		1 => buf.push(delta as i8 as u8),
561		2 => buf.extend_from_slice(&(delta as i16).to_le_bytes()),
562		4 => buf.extend_from_slice(&(delta as i32).to_le_bytes()),
563		8 => buf.extend_from_slice(&(delta as i64).to_le_bytes()),
564		16 => buf.extend_from_slice(&delta.to_le_bytes()),
565		_ => unreachable!(),
566	}
567}
568
569fn read_signed_delta_i128(data: &[u8], width: usize) -> i128 {
570	match width {
571		1 => data[0] as i8 as i128,
572		2 => i16::from_le_bytes([data[0], data[1]]) as i128,
573		4 => i32::from_le_bytes([data[0], data[1], data[2], data[3]]) as i128,
574		8 => i64::from_le_bytes([data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]])
575			as i128,
576		16 => i128::from_le_bytes([
577			data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9],
578			data[10], data[11], data[12], data[13], data[14], data[15],
579		]),
580		_ => unreachable!(),
581	}
582}
583
584macro_rules! impl_delta_int {
585	($ty:ident, $try_fn:ident, $try_rle_fn:ident, $dec_fn:ident, $dec_rle_fn:ident, $width:expr) => {
586		pub fn $try_fn(slice: &[$ty]) -> Option<Vec<u8>> {
587			if slice.len() < 2 {
588				return None;
589			}
590			let deltas: Vec<i64> =
591				slice.windows(2).map(|w| (w[1] as i64).wrapping_sub(w[0] as i64)).collect();
592			let width = delta_width(&deltas);
593			let delta_size = 1 + $width + (slice.len() - 1) * width;
594			if delta_size >= slice.len() * $width {
595				return None;
596			}
597			let mut buf = Vec::with_capacity(delta_size);
598			buf.push(width as u8);
599			buf.extend_from_slice(&slice[0].to_le_bytes());
600			encode_deltas(&deltas, width, &mut buf);
601			Some(buf)
602		}
603		pub fn $try_rle_fn(slice: &[$ty]) -> Option<Vec<u8>> {
604			if slice.len() < 2 {
605				return None;
606			}
607			let deltas: Vec<i64> =
608				slice.windows(2).map(|w| (w[1] as i64).wrapping_sub(w[0] as i64)).collect();
609			let width = delta_width(&deltas);
610			let runs = rle_runs(&deltas);
611			let drle_size = 1 + $width + runs.len() * (width + 4);
612			if drle_size >= slice.len() * $width {
613				return None;
614			}
615			let mut buf = Vec::with_capacity(drle_size);
616			buf.push(width as u8);
617			buf.extend_from_slice(&slice[0].to_le_bytes());
618			encode_delta_rle_runs(&runs, width, &mut buf);
619			Some(buf)
620		}
621		pub fn $dec_fn(data: &[u8], row_count: usize) -> Result<Vec<$ty>, DecodeError> {
622			if row_count == 0 {
623				return Ok(vec![]);
624			}
625			if data.len() < 1 + $width {
626				return Err(DecodeError::InvalidData("delta data too short".into()));
627			}
628			let width = data[0] as usize;
629			let mut array = [0u8; $width];
630			array.copy_from_slice(&data[1..1 + $width]);
631			let baseline = $ty::from_le_bytes(array);
632			let mut values = Vec::with_capacity(row_count);
633			values.push(baseline);
634			let mut pos = 1 + $width;
635			for _ in 1..row_count {
636				let delta = read_signed_delta(&data[pos..], width);
637				pos += width;
638				let prev = *values.last().unwrap();
639				values.push((prev as i64).wrapping_add(delta) as $ty);
640			}
641			Ok(values)
642		}
643		pub fn $dec_rle_fn(data: &[u8], row_count: usize) -> Result<Vec<$ty>, DecodeError> {
644			if row_count == 0 {
645				return Ok(vec![]);
646			}
647			if data.len() < 1 + $width {
648				return Err(DecodeError::InvalidData("delta rle data too short".into()));
649			}
650			let width = data[0] as usize;
651			let mut array = [0u8; $width];
652			array.copy_from_slice(&data[1..1 + $width]);
653			let baseline = $ty::from_le_bytes(array);
654			let mut values = Vec::with_capacity(row_count);
655			values.push(baseline);
656			let mut pos = 1 + $width;
657			while values.len() < row_count && pos + width + 4 <= data.len() {
658				let delta = read_signed_delta(&data[pos..], width);
659				pos += width;
660				let mut count_arr = [0u8; 4];
661				count_arr.copy_from_slice(&data[pos..pos + 4]);
662				let count = u32::from_le_bytes(count_arr) as usize;
663				pos += 4;
664				for _ in 0..count {
665					if values.len() >= row_count {
666						break;
667					}
668					let prev = *values.last().unwrap();
669					values.push((prev as i64).wrapping_add(delta) as $ty);
670				}
671			}
672			if values.len() != row_count {
673				return Err(DecodeError::InvalidData("delta rle count mismatch".into()));
674			}
675			Ok(values)
676		}
677	};
678}
679
680macro_rules! impl_delta_float {
681	($ty:ident, $uint_ty:ident, $try_fn:ident, $try_rle_fn:ident, $dec_fn:ident, $dec_rle_fn:ident, $width:expr) => {
682		pub fn $try_fn(slice: &[$ty]) -> Option<Vec<u8>> {
683			if slice.len() < 2 {
684				return None;
685			}
686			let deltas: Vec<i64> = slice
687				.windows(2)
688				.map(|w| (w[1].to_bits() as i64).wrapping_sub(w[0].to_bits() as i64))
689				.collect();
690			let width = delta_width(&deltas);
691			let delta_size = 1 + $width + (slice.len() - 1) * width;
692			if delta_size >= slice.len() * $width {
693				return None;
694			}
695			let mut buf = Vec::with_capacity(delta_size);
696			buf.push(width as u8);
697			buf.extend_from_slice(&slice[0].to_bits().to_le_bytes());
698			encode_deltas(&deltas, width, &mut buf);
699			Some(buf)
700		}
701		pub fn $try_rle_fn(slice: &[$ty]) -> Option<Vec<u8>> {
702			if slice.len() < 2 {
703				return None;
704			}
705			let deltas: Vec<i64> = slice
706				.windows(2)
707				.map(|w| (w[1].to_bits() as i64).wrapping_sub(w[0].to_bits() as i64))
708				.collect();
709			let width = delta_width(&deltas);
710			let runs = rle_runs(&deltas);
711			let drle_size = 1 + $width + runs.len() * (width + 4);
712			if drle_size >= slice.len() * $width {
713				return None;
714			}
715			let mut buf = Vec::with_capacity(drle_size);
716			buf.push(width as u8);
717			buf.extend_from_slice(&slice[0].to_bits().to_le_bytes());
718			encode_delta_rle_runs(&runs, width, &mut buf);
719			Some(buf)
720		}
721		pub fn $dec_fn(data: &[u8], row_count: usize) -> Result<Vec<$ty>, DecodeError> {
722			if row_count == 0 {
723				return Ok(vec![]);
724			}
725			if data.len() < 1 + $width {
726				return Err(DecodeError::InvalidData("delta data too short".into()));
727			}
728			let width = data[0] as usize;
729			let mut array = [0u8; $width];
730			array.copy_from_slice(&data[1..1 + $width]);
731			let baseline = $uint_ty::from_le_bytes(array);
732			let mut values = Vec::with_capacity(row_count);
733			values.push($ty::from_bits(baseline));
734			let mut pos = 1 + $width;
735			for _ in 1..row_count {
736				let delta = read_signed_delta(&data[pos..], width);
737				pos += width;
738				let prev = values.last().unwrap().to_bits();
739				values.push($ty::from_bits((prev as i64).wrapping_add(delta) as $uint_ty));
740			}
741			Ok(values)
742		}
743		pub fn $dec_rle_fn(data: &[u8], row_count: usize) -> Result<Vec<$ty>, DecodeError> {
744			if row_count == 0 {
745				return Ok(vec![]);
746			}
747			if data.len() < 1 + $width {
748				return Err(DecodeError::InvalidData("delta rle data too short".into()));
749			}
750			let width = data[0] as usize;
751			let mut array = [0u8; $width];
752			array.copy_from_slice(&data[1..1 + $width]);
753			let baseline = $uint_ty::from_le_bytes(array);
754			let mut values = Vec::with_capacity(row_count);
755			values.push($ty::from_bits(baseline));
756			let mut pos = 1 + $width;
757			while values.len() < row_count && pos + width + 4 <= data.len() {
758				let delta = read_signed_delta(&data[pos..], width);
759				pos += width;
760				let mut count_arr = [0u8; 4];
761				count_arr.copy_from_slice(&data[pos..pos + 4]);
762				let count = u32::from_le_bytes(count_arr) as usize;
763				pos += 4;
764				for _ in 0..count {
765					if values.len() >= row_count {
766						break;
767					}
768					let prev = values.last().unwrap().to_bits();
769					values.push($ty::from_bits((prev as i64).wrapping_add(delta) as $uint_ty));
770				}
771			}
772			if values.len() != row_count {
773				return Err(DecodeError::InvalidData("delta rle count mismatch".into()));
774			}
775			Ok(values)
776		}
777	};
778}
779
780impl_delta_int!(i8, try_delta_i8, try_delta_rle_i8, decode_delta_i8, decode_delta_rle_i8, 1);
781impl_delta_int!(u8, try_delta_u8, try_delta_rle_u8, decode_delta_u8, decode_delta_rle_u8, 1);
782impl_delta_int!(i16, try_delta_i16, try_delta_rle_i16, decode_delta_i16, decode_delta_rle_i16, 2);
783impl_delta_int!(u16, try_delta_u16, try_delta_rle_u16, decode_delta_u16, decode_delta_rle_u16, 2);
784impl_delta_int!(u32, try_delta_u32, try_delta_rle_u32, decode_delta_u32, decode_delta_rle_u32, 4);
785
786impl_delta_float!(f32, u32, try_delta_f32, try_delta_rle_f32, decode_delta_f32, decode_delta_rle_f32, 4);
787impl_delta_float!(f64, u64, try_delta_f64, try_delta_rle_f64, decode_delta_f64, decode_delta_rle_f64, 8);