1use std::cmp::min;
2use std::io::{Read, Seek, SeekFrom};
3
4use bytes::Bytes;
5use more_asserts::{debug_assert_ge, debug_assert_le};
6
7use super::Chunk;
8use super::constants::{MAXIMUM_CHUNK_MULTIPLIER, MINIMUM_CHUNK_DIVISOR, TARGET_CHUNK_SIZE};
9
10pub struct Chunker {
13 hash: gearhash::Hasher<'static>,
15 minimum_chunk: usize,
16 maximum_chunk: usize,
17 mask: u64,
18
19 chunkbuf: Vec<u8>,
21}
22
23impl Default for Chunker {
24 fn default() -> Self {
25 Self::new(*TARGET_CHUNK_SIZE)
26 }
27}
28
29impl Chunker {
30 pub fn new(target_chunk_size: usize) -> Self {
31 assert_eq!(target_chunk_size.count_ones(), 1);
32
33 assert!(target_chunk_size > 64);
36
37 assert!(target_chunk_size < u32::MAX as usize);
40
41 let mask = (target_chunk_size - 1) as u64;
42
43 let mask = mask << mask.leading_zeros();
47 let minimum_chunk = target_chunk_size / *MINIMUM_CHUNK_DIVISOR;
48 let maximum_chunk = target_chunk_size * *MAXIMUM_CHUNK_MULTIPLIER;
49
50 assert!(maximum_chunk > minimum_chunk);
51
52 let hash = gearhash::Hasher::default();
53
54 Chunker {
55 hash,
56 minimum_chunk,
57 maximum_chunk,
58 mask,
59 chunkbuf: Vec::with_capacity(maximum_chunk),
61 }
62 }
63
64 fn new_with_min(target_chunk_size: usize, min_chunk_size: usize) -> Self {
67 let mut chunker = Self::new(target_chunk_size);
68 chunker.minimum_chunk = min_chunk_size;
69 chunker
70 }
71
72 #[inline]
76 pub fn next_boundary(&mut self, data: &[u8]) -> Option<usize> {
77 const HASH_WINDOW_SIZE: usize = 64;
78 let n_bytes = data.len();
79
80 if n_bytes == 0 {
81 return None;
82 }
83
84 let previous_len = self.chunkbuf.len();
85 let mut cur_index = 0;
86 let mut create_chunk = false;
87
88 if previous_len + HASH_WINDOW_SIZE < self.minimum_chunk {
92 let skip = min(self.minimum_chunk - previous_len - HASH_WINDOW_SIZE - 1, n_bytes);
93 cur_index += skip;
94 }
95
96 let read_end = n_bytes.min(cur_index + self.maximum_chunk - previous_len);
99
100 loop {
101 if let Some(next_match) = self.hash.next_match(&data[cur_index..read_end], self.mask) {
102 cur_index += next_match;
103
104 if cur_index + previous_len < self.minimum_chunk {
114 continue;
115 }
116
117 create_chunk = true;
118 } else {
119 cur_index = read_end;
120 }
121
122 break;
123 }
124
125 if cur_index + previous_len >= self.maximum_chunk {
127 cur_index = self.maximum_chunk - previous_len;
128 create_chunk = true;
129 }
130
131 if create_chunk {
132 self.hash.set_hash(0); debug_assert_ge!(cur_index + previous_len, self.minimum_chunk);
134 debug_assert_le!(cur_index + previous_len, self.maximum_chunk);
135 Some(cur_index)
136 } else {
137 None
138 }
139 }
140
141 fn reset_state(&mut self) {
142 self.hash.set_hash(0);
146 debug_assert!(self.chunkbuf.is_empty());
147 }
148
149 pub fn next(&mut self, data: &[u8], is_final: bool) -> (Option<Chunk>, usize) {
156 let (chunk_data, consume): (Bytes, usize) = {
157 if let Some(next_boundary) = self.next_boundary(data) {
158 if self.chunkbuf.is_empty() {
159 (Bytes::copy_from_slice(&data[..next_boundary]), next_boundary)
160 } else {
161 self.chunkbuf.extend_from_slice(&data[..next_boundary]);
162 (std::mem::take(&mut self.chunkbuf).into(), next_boundary)
163 }
164 } else if is_final {
165 let r = if self.chunkbuf.is_empty() {
167 (Bytes::copy_from_slice(data), data.len())
168 } else {
169 self.chunkbuf.extend_from_slice(data);
170 (std::mem::take(&mut self.chunkbuf).into(), data.len())
171 };
172
173 if is_final {
174 self.reset_state();
175 }
176
177 r
178 } else {
179 self.chunkbuf.extend_from_slice(data);
180 return (None, data.len());
181 }
182 };
183
184 if chunk_data.is_empty() {
186 return (None, 0);
187 }
188
189 (Some(Chunk::new(chunk_data)), consume)
190 }
191
192 pub fn next_block(&mut self, data: &[u8], is_final: bool) -> Vec<Chunk> {
195 let mut ret = Vec::new();
196
197 let mut pos = 0;
198 loop {
199 debug_assert!(pos <= data.len());
200 if pos == data.len() {
201 if is_final {
202 self.reset_state();
203 }
204
205 return ret;
206 }
207
208 let (maybe_chunk, bytes_consumed) = self.next(&data[pos..], is_final);
209
210 if let Some(chunk) = maybe_chunk {
211 ret.push(chunk);
212 }
213
214 pos += bytes_consumed;
215 }
216 }
217
218 pub fn next_block_bytes(&mut self, data: &Bytes, is_final: bool) -> Vec<Chunk> {
226 let mut ret = Vec::new();
227
228 let mut pos = 0;
229
230 if !self.chunkbuf.is_empty() {
233 let (maybe_chunk, skip_idx) = self.next(data, is_final);
234 if let Some(chunk) = maybe_chunk {
235 ret.push(chunk);
236 }
237 pos = skip_idx;
238 }
239
240 while pos < data.len() {
241 let maybe_next_boundary = self.next_boundary(&data[pos..]);
242
243 if let Some(chunk_size) = maybe_next_boundary {
244 let next_pos = pos + chunk_size;
245 ret.push(Chunk::new(data.slice(pos..next_pos)));
246 pos = next_pos;
247 } else {
248 if is_final {
250 ret.push(Chunk::new(data.slice(pos..)));
251 } else {
252 self.chunkbuf.extend_from_slice(&data[pos..]);
253 }
254 break;
255 }
256 }
257
258 if is_final {
259 self.reset_state();
260 }
261
262 ret
263 }
264
265 pub fn finish(&mut self) -> Option<Chunk> {
267 self.next(&[], true).0
268 }
269}
270
271pub fn find_partitions<R: Read + Seek>(
290 reader: &mut R,
291 file_size: usize,
292 target_chunk_size: usize,
293 min_partition_size: usize,
294 partition_scan_bytes: usize,
295) -> std::io::Result<Vec<usize>> {
296 assert!(min_partition_size > 0);
297 let mut partitions: Vec<usize> = Vec::new();
298 partitions.push(0);
299 let minimum_chunk = target_chunk_size / *MINIMUM_CHUNK_DIVISOR;
303 let maximum_chunk = target_chunk_size * *MAXIMUM_CHUNK_MULTIPLIER;
304
305 assert!(minimum_chunk > 64);
306
307 if maximum_chunk >= min_partition_size {
308 return Ok(partitions);
309 }
310 let mut buf = vec![0u8; partition_scan_bytes];
311 let mut curpos: usize = 0;
312 while curpos < file_size {
320 curpos += min_partition_size;
321 if curpos + min_partition_size >= file_size || curpos + partition_scan_bytes >= file_size {
324 break;
325 }
326 reader.seek(SeekFrom::Start(curpos as u64))?;
328 reader.read_exact(&mut buf)?;
329 let mut chunker = Chunker::new_with_min(target_chunk_size, 0);
330 let chunks = chunker.next_block(&buf, false);
333 if chunks.is_empty() {
334 continue;
335 }
336 let mut offset = chunks[0].data.len();
338 offset += chunks[1].data.len();
339 for i in 2..chunks.len() {
340 let cprev = chunks[i - 1].data.len();
341 let c = chunks[i].data.len();
342 offset += chunks[i].data.len();
343 if cprev > minimum_chunk
344 && cprev < maximum_chunk - minimum_chunk
345 && c > minimum_chunk
346 && c < maximum_chunk - minimum_chunk
347 {
348 partitions.push(curpos + offset);
350 break;
351 }
352 }
353 }
354 Ok(partitions)
355}
356
357pub use xet_core_structures::xorb_object::constants::next_stable_chunk_boundary;
361
362#[cfg(test)]
363mod tests {
364 use std::collections::HashSet;
365 use std::io::Cursor;
366
367 use rand::rngs::StdRng;
368 use rand::{RngExt, SeedableRng};
369
370 use super::*;
371
372 fn make_test_data(seed: u64, len: usize) -> Vec<u8> {
375 let mut rng = StdRng::seed_from_u64(seed);
376 let mut data = vec![0; len];
377 rng.fill(&mut data[..]);
378 data
379 }
380
381 fn check_chunks_equal(chunks: &[Chunk], data: &[u8]) {
382 let mut new_vec = Vec::with_capacity(10000);
384 for c in chunks.iter() {
385 new_vec.extend_from_slice(&c.data[..]);
386 }
387
388 assert!(new_vec == data);
389 }
390
391 #[derive(Default)]
395 struct ChunkerTestWrapper {
396 chunker_chunks: Chunker,
397 chunker_bytes: Chunker,
398 }
399
400 impl ChunkerTestWrapper {
401 fn new(target_chunk_size: usize) -> Self {
402 ChunkerTestWrapper {
403 chunker_chunks: Chunker::new(target_chunk_size),
404 chunker_bytes: Chunker::new(target_chunk_size),
405 }
406 }
407
408 fn next_block(&mut self, data: &[u8], is_final: bool) -> Vec<Chunk> {
409 let chunks = self.chunker_chunks.next_block(data, is_final);
410 let bytes_chunks = self.chunker_bytes.next_block_bytes(&Bytes::copy_from_slice(data), is_final);
411
412 assert_eq!(chunks.len(), bytes_chunks.len());
414 for (c1, c2) in chunks.iter().zip(bytes_chunks.iter()) {
415 assert_eq!(c1.data, c2.data);
416 }
417
418 chunks
419 }
420
421 fn next_chunk(&mut self, data: &[u8], is_final: bool) -> (Option<Chunk>, usize) {
422 let (chunk, consumed) = self.chunker_chunks.next(data, is_final);
423 let (bytes_chunk, bytes_consumed) = self.chunker_bytes.next(&Bytes::copy_from_slice(data), is_final);
424
425 if let Some(c) = &chunk {
427 assert_eq!(c.data, bytes_chunk.unwrap().data);
428 } else {
429 assert!(bytes_chunk.is_none());
430 }
431
432 (chunk, consumed.max(bytes_consumed))
433 }
434 }
435
436 #[test]
437 fn test_empty_data_no_chunk_until_final() {
438 let mut chunker = ChunkerTestWrapper::new(128);
439
440 let (chunk, consumed) = chunker.next_chunk(&[], false);
442 assert!(chunk.is_none());
443 assert_eq!(consumed, 0);
444
445 let (chunk, consumed) = chunker.next_chunk(&[], true);
447 assert!(chunk.is_none());
448 assert_eq!(consumed, 0);
449 }
450
451 #[test]
452 fn test_data_smaller_than_minimum_no_boundary() {
453 let mut chunker = ChunkerTestWrapper::new(128);
454
455 let data = make_test_data(0, 63);
457
458 let (chunk, consumed) = chunker.next_chunk(&data, false);
461 assert!(chunk.is_none());
462 assert_eq!(consumed, data.len());
463
464 let (chunk, consumed) = chunker.next_chunk(&[], true);
466 assert!(chunk.is_some());
467 assert_eq!(consumed, 0);
468
469 let chunk = chunk.unwrap();
470 assert_eq!(chunk.data.len(), 63);
471 assert_eq!(&chunk.data[..], &data[..], "Chunk should contain exactly what was passed in");
472 }
473
474 #[test]
475 fn test_multiple_chunks_produced() {
476 let mut chunker = ChunkerTestWrapper::new(128);
477
478 let data = make_test_data(42, 10000);
480
481 let chunks = chunker.next_block(&data, true);
483 assert!(!chunks.is_empty());
484
485 check_chunks_equal(&chunks, &data);
486 }
487
488 #[test]
489 fn test_repeated_calls_partial_consumption() {
490 let data = make_test_data(42, 10000);
493
494 let mut chunks_1 = Vec::new();
495
496 let mut pos = 0;
497 let mut chunker = ChunkerTestWrapper::new(128);
498
499 while pos < data.len() {
500 for i in 0..16 {
501 let next_pos = (pos + i).min(data.len());
502 chunks_1.append(&mut chunker.next_block(&data[pos..next_pos], next_pos == data.len()));
503 pos = next_pos;
504 }
505 }
506
507 check_chunks_equal(&chunks_1, &data);
508
509 let chunks_2 = ChunkerTestWrapper::new(128).next_block(&data, true);
511
512 assert_eq!(chunks_1, chunks_2);
513 }
514
515 #[test]
516 fn test_exact_maximum_chunk() {
517 let mut chunker = ChunkerTestWrapper::new(512);
521
522 let data = vec![0; 8 * *MAXIMUM_CHUNK_MULTIPLIER * 512];
524
525 let chunks = chunker.next_block(&data, true);
526
527 assert_eq!(chunks.len(), 8);
528
529 for c in chunks.iter() {
530 assert_eq!(c.data.len(), *MAXIMUM_CHUNK_MULTIPLIER * 512);
531 }
532 }
533
534 #[test]
535 fn test_partition() {
536 for _i in 1..5 {
537 let data = make_test_data(42, 1000000);
538 let mut chunker = Chunker::new(1024);
539 let chunks = chunker.next_block(&data, true);
540 let mut chunk_offsets = HashSet::new();
541 let mut offset = 0;
542 eprintln!("{:?}", chunker.minimum_chunk);
543 for i in 0..chunks.len() {
544 chunk_offsets.insert(offset);
545 offset += chunks[i].data.len();
546 }
547
548 let partitions =
549 find_partitions(&mut Cursor::new(&mut data.as_slice()), data.len(), 1024, 100000, 10000).unwrap();
550 assert!(partitions.len() > 1);
551 for i in 0..partitions.len() {
552 assert!(chunk_offsets.contains(&partitions[i]));
553 }
554 }
555 }
556
557 fn splitmix64_next(state: &mut u64) -> u64 {
560 *state = state.wrapping_add(0x9E3779B97F4A7C15);
561 let mut z = *state;
562 z = (z ^ (z >> 30)).wrapping_mul(0xBF58476D1CE4E5B9);
563 z = (z ^ (z >> 27)).wrapping_mul(0x94D049BB133111EB);
564 z ^ (z >> 31)
565 }
566
567 fn create_random_data(n: usize, seed: u64) -> Vec<u8> {
568 let mut ret = Vec::with_capacity(n + 7);
572
573 let mut state = seed;
574
575 while ret.len() < n {
576 let next_u64 = splitmix64_next(&mut state);
577 ret.extend_from_slice(&next_u64.to_le_bytes());
578 }
579
580 ret.resize(n, 0);
582
583 ret
584 }
585
586 fn get_chunk_boundaries(chunks: &[Chunk]) -> Vec<usize> {
587 chunks
588 .iter()
589 .scan(0, |state, chunk| {
590 *state += chunk.data.len();
591 Some(*state)
592 })
593 .collect()
594 }
595
596 #[test]
597 fn test_chunk_boundaries() {
598 let data = create_random_data(256000, 1);
599
600 let chunks = ChunkerTestWrapper::default().next_block(&data, true);
602
603 let ref_chunk_boundaries: Vec<usize> = get_chunk_boundaries(&chunks);
605
606 for add_size in [1, 37, 255] {
608 let mut chunker = Chunker::default();
609
610 let mut alt_chunks = Vec::with_capacity(chunks.len());
612
613 let mut pos = 0;
614 while pos < data.len() {
615 let next_pos = (pos + add_size).min(data.len());
616 let next_chunk = chunker.next_block(&data[pos..next_pos], next_pos == data.len());
617 alt_chunks.extend(next_chunk);
618 pos = next_pos;
619 }
620
621 let alt_boundaries = get_chunk_boundaries(&alt_chunks);
622
623 assert_eq!(alt_boundaries, ref_chunk_boundaries);
624 }
625 }
626
627 #[test]
628 fn test_correctness_1mb_random_data() {
629 let data = create_random_data(1000000, 0);
631
632 assert_eq!(data[0], 175);
638 assert_eq!(data[127], 132);
639 assert_eq!(data[111111], 118);
640
641 let chunks = ChunkerTestWrapper::default().next_block(&data, true);
643
644 let chunk_boundaries: Vec<usize> = get_chunk_boundaries(&chunks);
646
647 assert_eq!(
650 chunk_boundaries,
651 vec![
652 84493, 134421, 144853, 243318, 271793, 336457, 467529, 494581, 582000, 596735, 616815, 653164, 678202,
653 724510, 815591, 827760, 958832, 991092, 1000000
654 ]
655 );
656 }
657
658 #[test]
659 fn test_correctness_1mb_const_data() {
660 let data = vec![59u8; 1000000];
662
663 let chunks = ChunkerTestWrapper::default().next_block(&data, true);
665
666 let chunk_boundaries: Vec<usize> = get_chunk_boundaries(&chunks);
668
669 assert_eq!(chunk_boundaries, vec![131072, 262144, 393216, 524288, 655360, 786432, 917504, 1000000])
672 }
673
674 fn get_triggering_base_data(n: usize, padding: usize) -> Vec<u8> {
675 let mut data = vec![
678 154, 52, 42, 34, 159, 75, 126, 224, 70, 236, 12, 196, 79, 236, 178, 124, 127, 50, 99, 178, 44, 176, 174,
679 126, 250, 235, 205, 174, 252, 122, 35, 10, 20, 101, 214, 69, 193, 8, 115, 105, 158, 228, 120, 111, 136,
680 162, 198, 251, 211, 183, 253, 252, 164, 147, 63, 16, 186, 162, 117, 23, 170, 36, 205, 187, 174, 76, 210,
681 174, 211, 175, 12, 173, 145, 59, 2, 70, 222, 181, 159, 227, 182, 156, 189, 51, 226, 106, 24, 50, 183, 157,
682 140, 10, 8, 23, 212, 70, 10, 234, 23, 33, 219, 254, 39, 236, 70, 49, 191, 116, 9, 115, 15, 101, 26, 159,
683 165, 220, 15, 170, 56, 125, 92, 163, 94, 235, 38, 40, 49, 81,
684 ];
685
686 data.resize(data.len() + padding, 0u8);
688
689 while data.len() < n {
691 let n_take = (n - data.len()).min(data.len());
692 data.extend_from_within(0..n_take);
693 }
694
695 data
696 }
697
698 #[test]
699 fn test_correctness_100kb_hitting_data() {
700 let mut data_sample_at_11111 = [0u8; 128];
706 let mut ref_cb = vec![Vec::new(); 128];
707
708 data_sample_at_11111[0] = 236;
709 ref_cb[0] = vec![8256, 16448, 24640, 32832, 41024, 49216, 57408, 65536];
710 data_sample_at_11111[1] = 50;
711 ref_cb[1] = vec![8320, 16576, 24832, 33088, 41344, 49600, 57856, 65536];
712 data_sample_at_11111[2] = 36;
713 ref_cb[2] = vec![8254, 16574, 24894, 33214, 41534, 49854, 58174, 65536];
714 data_sample_at_11111[3] = 116;
715 ref_cb[3] = vec![8317, 16570, 24823, 33076, 41329, 49582, 57835, 65536];
716 data_sample_at_11111[4] = 126;
717 ref_cb[4] = vec![8248, 16564, 24880, 33196, 41512, 49828, 58144, 65536];
718 data_sample_at_11111[5] = 145;
719 ref_cb[5] = vec![8310, 16556, 24802, 33048, 41294, 49540, 57786, 65536];
720 data_sample_at_11111[6] = 235;
721 ref_cb[6] = vec![8238, 16546, 24854, 33162, 41470, 49778, 58086, 65536];
722 data_sample_at_11111[7] = 228;
723 ref_cb[7] = vec![8299, 16534, 24769, 33004, 41239, 49474, 57709, 65536];
724 data_sample_at_11111[8] = 70;
725 ref_cb[8] = vec![8224, 16520, 24816, 33112, 41408, 49704, 58000, 65536];
726 data_sample_at_11111[9] = 178;
727 ref_cb[9] = vec![8284, 16504, 24724, 32944, 41164, 49384, 57604, 65536];
728 data_sample_at_11111[10] = 173;
729 ref_cb[10] = vec![8206, 16486, 24766, 33046, 41326, 49606, 57886, 65536];
730 data_sample_at_11111[11] = 0;
731 ref_cb[11] = vec![8265, 16466, 24667, 32868, 41069, 49270, 57471, 65536];
732 data_sample_at_11111[12] = 252;
733 ref_cb[12] = vec![8324, 16584, 24844, 33104, 41364, 49624, 57884, 65536];
734 data_sample_at_11111[13] = 159;
735 ref_cb[13] = vec![8242, 16561, 24880, 33199, 41518, 49837, 58156, 65536];
736 data_sample_at_11111[14] = 69;
737 ref_cb[14] = vec![8300, 16536, 24772, 33008, 41244, 49480, 57716, 65536];
738 data_sample_at_11111[15] = 219;
739 ref_cb[15] = vec![8215, 16509, 24803, 33097, 41391, 49685, 57979, 65536];
740 data_sample_at_11111[16] = 126;
741 ref_cb[16] = vec![8272, 16480, 24688, 32896, 41104, 49312, 57520, 65536];
742 data_sample_at_11111[17] = 10;
743 ref_cb[17] = vec![8329, 16594, 24859, 33124, 41389, 49654, 57919, 65536];
744 data_sample_at_11111[18] = 124;
745 ref_cb[18] = vec![8240, 16562, 24884, 33206, 41528, 49850, 58172, 65536];
746 data_sample_at_11111[19] = 24;
747 ref_cb[19] = vec![8296, 16528, 24760, 32992, 41224, 49456, 57688, 65536];
748 data_sample_at_11111[20] = 196;
749 ref_cb[20] = vec![8204, 16492, 24780, 33068, 41356, 49644, 57932, 65536];
750 data_sample_at_11111[21] = 106;
751 ref_cb[21] = vec![8259, 16454, 24649, 32844, 41039, 49234, 57429, 65536];
752 data_sample_at_11111[22] = 196;
753 ref_cb[22] = vec![8314, 16564, 24814, 33064, 41314, 49564, 57814, 65536];
754 data_sample_at_11111[23] = 183;
755 ref_cb[23] = vec![8218, 16523, 24828, 33133, 41438, 49743, 58048, 65536];
756 data_sample_at_11111[24] = 124;
757 ref_cb[24] = vec![8272, 16480, 24688, 32896, 41104, 49312, 57520, 65536];
758 data_sample_at_11111[25] = 70;
759 ref_cb[25] = vec![8326, 16588, 24850, 33112, 41374, 49636, 57898, 65536];
760 data_sample_at_11111[26] = 126;
761 ref_cb[26] = vec![8226, 16542, 24858, 33174, 41490, 49806, 58122, 65536];
762 data_sample_at_11111[27] = 191;
763 ref_cb[27] = vec![8279, 16494, 24709, 32924, 41139, 49354, 57569, 65536];
764 data_sample_at_11111[28] = 69;
765 ref_cb[28] = vec![8332, 16600, 24868, 33136, 41404, 49672, 57940, 65536];
766 data_sample_at_11111[29] = 163;
767 ref_cb[29] = vec![8228, 16549, 24870, 33191, 41512, 49833, 58154, 65536];
768 data_sample_at_11111[30] = 252;
769 ref_cb[30] = vec![8280, 16496, 24712, 32928, 41144, 49360, 57576, 65536];
770 data_sample_at_11111[31] = 0;
771 ref_cb[31] = vec![8332, 16600, 24868, 33136, 41404, 49672, 57940, 65536];
772 data_sample_at_11111[32] = 173;
773 ref_cb[32] = vec![8224, 16544, 24864, 33184, 41504, 49824, 58144, 65536];
774 data_sample_at_11111[33] = 42;
775 ref_cb[33] = vec![8275, 16486, 24697, 32908, 41119, 49330, 57541, 65536];
776 data_sample_at_11111[34] = 70;
777 ref_cb[34] = vec![8326, 16588, 24850, 33112, 41374, 49636, 57898, 65536];
778 data_sample_at_11111[35] = 174;
779 ref_cb[35] = vec![8214, 16527, 24840, 33153, 41466, 49779, 58092, 65536];
780 data_sample_at_11111[36] = 235;
781 ref_cb[36] = vec![8264, 16464, 24664, 32864, 41064, 49264, 57464, 65536];
782 data_sample_at_11111[37] = 186;
783 ref_cb[37] = vec![8314, 16564, 24814, 33064, 41314, 49564, 57814, 65536];
784 data_sample_at_11111[38] = 0;
785 ref_cb[38] = vec![8198, 16498, 24798, 33098, 41398, 49698, 57998, 65536];
786 data_sample_at_11111[39] = 157;
787 ref_cb[39] = vec![8247, 16597, 24947, 33297, 41647, 49997, 58347, 65536];
788 data_sample_at_11111[40] = 126;
789 ref_cb[40] = vec![8296, 16528, 24760, 32992, 41224, 49456, 57688, 65536];
790 data_sample_at_11111[41] = 49;
791 ref_cb[41] = vec![8345, 16626, 24907, 33188, 41469, 49750, 58031, 65536];
792 data_sample_at_11111[42] = 36;
793 ref_cb[42] = vec![8224, 16554, 24884, 33214, 41544, 49874, 58204, 65536];
794 data_sample_at_11111[43] = 0;
795 ref_cb[43] = vec![8272, 16480, 24688, 32896, 41104, 49312, 57520, 65536];
796 data_sample_at_11111[44] = 236;
797 ref_cb[44] = vec![8320, 16576, 24832, 33088, 41344, 49600, 57856, 65536];
798 data_sample_at_11111[45] = 105;
799 ref_cb[45] = vec![8195, 16499, 24803, 33107, 41411, 49715, 58019, 65536];
800 data_sample_at_11111[46] = 0;
801 ref_cb[46] = vec![8242, 16594, 24946, 33298, 41650, 50002, 58354, 65536];
802 data_sample_at_11111[47] = 24;
803 ref_cb[47] = vec![8289, 16514, 24739, 32964, 41189, 49414, 57639, 65536];
804 data_sample_at_11111[48] = 126;
805 ref_cb[48] = vec![8336, 16608, 24880, 33152, 41424, 49696, 57968, 65536];
806 data_sample_at_11111[49] = 0;
807 ref_cb[49] = vec![8206, 16525, 24844, 33163, 41482, 49801, 58120, 65536];
808 data_sample_at_11111[50] = 70;
809 ref_cb[50] = vec![8252, 16618, 24984, 33350, 41716, 50082, 58448, 65536];
810 data_sample_at_11111[51] = 236;
811 ref_cb[51] = vec![8298, 16532, 24766, 33000, 41234, 49468, 57702, 65536];
812 data_sample_at_11111[52] = 0;
813 ref_cb[52] = vec![8344, 16624, 24904, 33184, 41464, 49744, 58024, 65536];
814 data_sample_at_11111[53] = 12;
815 ref_cb[53] = vec![8209, 16535, 24861, 33187, 41513, 49839, 58165, 65536];
816 data_sample_at_11111[54] = 236;
817 ref_cb[54] = vec![8254, 16626, 24998, 33370, 41742, 50114, 58486, 65536];
818 data_sample_at_11111[55] = 0;
819 ref_cb[55] = vec![8299, 16534, 24769, 33004, 41239, 49474, 57709, 65536];
820 data_sample_at_11111[56] = 173;
821 ref_cb[56] = vec![8344, 16624, 24904, 33184, 41464, 49744, 58024, 65536];
822 data_sample_at_11111[57] = 196;
823 ref_cb[57] = vec![8204, 16529, 24854, 33179, 41504, 49829, 58154, 65536];
824 data_sample_at_11111[58] = 0;
825 ref_cb[58] = vec![8248, 16618, 24988, 33358, 41728, 50098, 58468, 65536];
826 data_sample_at_11111[59] = 159;
827 ref_cb[59] = vec![8292, 16520, 24748, 32976, 41204, 49432, 57660, 65536];
828 data_sample_at_11111[60] = 178;
829 ref_cb[60] = vec![8336, 16608, 24880, 33152, 41424, 49696, 57968, 65536];
830 data_sample_at_11111[61] = 0;
831 ref_cb[61] = vec![8380, 16696, 25012, 33328, 41644, 49960, 58276, 65536];
832 data_sample_at_11111[62] = 10;
833 ref_cb[62] = vec![8234, 16594, 24954, 33314, 41674, 50034, 58394, 65536];
834 data_sample_at_11111[63] = 101;
835 ref_cb[63] = vec![8277, 16490, 24703, 32916, 41129, 49342, 57555, 65536];
836 data_sample_at_11111[64] = 0;
837 ref_cb[64] = vec![8320, 16576, 24832, 33088, 41344, 49600, 57856, 65536];
838 data_sample_at_11111[65] = 15;
839 ref_cb[65] = vec![8363, 16662, 24961, 33260, 41559, 49858, 58157, 65536];
840 data_sample_at_11111[66] = 147;
841 ref_cb[66] = vec![8212, 16554, 24896, 33238, 41580, 49922, 58264, 65536];
842 data_sample_at_11111[67] = 0;
843 ref_cb[67] = vec![8254, 16639, 25024, 33409, 41794, 50179, 58564, 65536];
844 data_sample_at_11111[68] = 0;
845 ref_cb[68] = vec![8296, 16528, 24760, 32992, 41224, 49456, 57688, 65536];
846 data_sample_at_11111[69] = 227;
847 ref_cb[69] = vec![8338, 16612, 24886, 33160, 41434, 49708, 57982, 65536];
848 data_sample_at_11111[70] = 126;
849 ref_cb[70] = vec![8380, 16696, 25012, 33328, 41644, 49960, 58276, 65536];
850 data_sample_at_11111[71] = 0;
851 ref_cb[71] = vec![8223, 16581, 24939, 33297, 41655, 50013, 58371, 65536];
852 data_sample_at_11111[72] = 101;
853 ref_cb[72] = vec![8264, 16464, 24664, 32864, 41064, 49264, 57464, 65536];
854 data_sample_at_11111[73] = 186;
855 ref_cb[73] = vec![8305, 16546, 24787, 33028, 41269, 49510, 57751, 65536];
856 data_sample_at_11111[74] = 52;
857 ref_cb[74] = vec![8346, 16628, 24910, 33192, 41474, 49756, 58038, 65536];
858 data_sample_at_11111[75] = 0;
859 ref_cb[75] = vec![8387, 16710, 25033, 33356, 41679, 50002, 58325, 65536];
860 data_sample_at_11111[76] = 70;
861 ref_cb[76] = vec![8224, 16588, 24952, 33316, 41680, 50044, 58408, 65536];
862 data_sample_at_11111[77] = 228;
863 ref_cb[77] = vec![8264, 16464, 24664, 32864, 41064, 49264, 57464, 65536];
864 data_sample_at_11111[78] = 0;
865 ref_cb[78] = vec![8304, 16544, 24784, 33024, 41264, 49504, 57744, 65536];
866 data_sample_at_11111[79] = 0;
867 ref_cb[79] = vec![8344, 16624, 24904, 33184, 41464, 49744, 58024, 65536];
868 data_sample_at_11111[80] = 50;
869 ref_cb[80] = vec![8384, 16704, 25024, 33344, 41664, 49984, 58304, 65536];
870 data_sample_at_11111[81] = 214;
871 ref_cb[81] = vec![8215, 16575, 24935, 33295, 41655, 50015, 58375, 65536];
872 data_sample_at_11111[82] = 0;
873 ref_cb[82] = vec![8254, 16654, 25054, 33454, 41854, 50254, 58654, 65536];
874 data_sample_at_11111[83] = 0;
875 ref_cb[83] = vec![8293, 16522, 24751, 32980, 41209, 49438, 57667, 65536];
876 data_sample_at_11111[84] = 50;
877 ref_cb[84] = vec![8332, 16600, 24868, 33136, 41404, 49672, 57940, 65536];
878 data_sample_at_11111[85] = 69;
879 ref_cb[85] = vec![8371, 16678, 24985, 33292, 41599, 49906, 58213, 65536];
880 data_sample_at_11111[86] = 0;
881 ref_cb[86] = vec![8196, 16542, 24888, 33234, 41580, 49926, 58272, 65536];
882 data_sample_at_11111[87] = 0;
883 ref_cb[87] = vec![8234, 16619, 25004, 33389, 41774, 50159, 58544, 65536];
884 data_sample_at_11111[88] = 70;
885 ref_cb[88] = vec![8272, 16480, 24688, 32896, 41104, 49312, 57520, 65536];
886 data_sample_at_11111[89] = 136;
887 ref_cb[89] = vec![8310, 16556, 24802, 33048, 41294, 49540, 57786, 65536];
888 data_sample_at_11111[90] = 0;
889 ref_cb[90] = vec![8348, 16632, 24916, 33200, 41484, 49768, 58052, 65536];
890 data_sample_at_11111[91] = 0;
891 ref_cb[91] = vec![8386, 16708, 25030, 33352, 41674, 49996, 58318, 65536];
892 data_sample_at_11111[92] = 101;
893 ref_cb[92] = vec![8204, 16564, 24924, 33284, 41644, 50004, 58364, 65536];
894 data_sample_at_11111[93] = 36;
895 ref_cb[93] = vec![8241, 16639, 25037, 33435, 41833, 50231, 58629, 65536];
896 data_sample_at_11111[94] = 196;
897 ref_cb[94] = vec![8278, 16492, 24706, 32920, 41134, 49348, 57562, 65536];
898 data_sample_at_11111[95] = 0;
899 ref_cb[95] = vec![8315, 16566, 24817, 33068, 41319, 49570, 57821, 65536];
900 data_sample_at_11111[96] = 0;
901 ref_cb[96] = vec![8352, 16640, 24928, 33216, 41504, 49792, 58080, 65536];
902 data_sample_at_11111[97] = 24;
903 ref_cb[97] = vec![8389, 16714, 25039, 33364, 41689, 50014, 58339, 65536];
904 data_sample_at_11111[98] = 8;
905 ref_cb[98] = vec![8200, 16562, 24924, 33286, 41648, 50010, 58372, 65536];
906 data_sample_at_11111[99] = 0;
907 ref_cb[99] = vec![8236, 16635, 25034, 33433, 41832, 50231, 58630, 65536];
908 data_sample_at_11111[100] = 0;
909 ref_cb[100] = vec![8272, 16480, 24688, 32896, 41104, 49312, 57520, 65536];
910 data_sample_at_11111[101] = 125;
911 ref_cb[101] = vec![8308, 16552, 24796, 33040, 41284, 49528, 57772, 65536];
912 data_sample_at_11111[102] = 173;
913 ref_cb[102] = vec![8344, 16624, 24904, 33184, 41464, 49744, 58024, 65536];
914 data_sample_at_11111[103] = 126;
915 ref_cb[103] = vec![8380, 16696, 25012, 33328, 41644, 49960, 58276, 65536];
916 data_sample_at_11111[104] = 0;
917 ref_cb[104] = vec![8416, 16768, 25120, 33472, 41824, 50176, 58528, 65536];
918 data_sample_at_11111[105] = 0;
919 ref_cb[105] = vec![8219, 16607, 24995, 33383, 41771, 50159, 58547, 65536];
920 data_sample_at_11111[106] = 159;
921 ref_cb[106] = vec![8254, 16678, 25102, 33526, 41950, 50374, 58798, 65536];
922 data_sample_at_11111[107] = 210;
923 ref_cb[107] = vec![8289, 16514, 24739, 32964, 41189, 49414, 57639, 65536];
924 data_sample_at_11111[108] = 178;
925 ref_cb[108] = vec![8324, 16584, 24844, 33104, 41364, 49624, 57884, 65536];
926 data_sample_at_11111[109] = 0;
927 ref_cb[109] = vec![8359, 16654, 24949, 33244, 41539, 49834, 58129, 65536];
928 data_sample_at_11111[110] = 0;
929 ref_cb[110] = vec![8394, 16724, 25054, 33384, 41714, 50044, 58374, 65536];
930 data_sample_at_11111[111] = 170;
931 ref_cb[111] = vec![8429, 16794, 25159, 33524, 41889, 50254, 58619, 65536];
932 data_sample_at_11111[112] = 173;
933 ref_cb[112] = vec![8224, 16624, 25024, 33424, 41824, 50224, 58624, 65536];
934 data_sample_at_11111[113] = 235;
935 ref_cb[113] = vec![8258, 16452, 24646, 32840, 41034, 49228, 57422, 65536];
936 data_sample_at_11111[114] = 0;
937 ref_cb[114] = vec![8292, 16520, 24748, 32976, 41204, 49432, 57660, 65536];
938 data_sample_at_11111[115] = 0;
939 ref_cb[115] = vec![8326, 16588, 24850, 33112, 41374, 49636, 57898, 65536];
940 data_sample_at_11111[116] = 0;
941 ref_cb[116] = vec![8360, 16656, 24952, 33248, 41544, 49840, 58136, 65536];
942 data_sample_at_11111[117] = 24;
943 ref_cb[117] = vec![8394, 16724, 25054, 33384, 41714, 50044, 58374, 65536];
944 data_sample_at_11111[118] = 228;
945 ref_cb[118] = vec![8428, 16792, 25156, 33520, 41884, 50248, 58612, 65536];
946 data_sample_at_11111[119] = 0;
947 ref_cb[119] = vec![8215, 16613, 25011, 33409, 41807, 50205, 58603, 65536];
948 data_sample_at_11111[120] = 0;
949 ref_cb[120] = vec![8248, 16680, 25112, 33544, 41976, 50408, 58840, 65536];
950 data_sample_at_11111[121] = 0;
951 ref_cb[121] = vec![8281, 16498, 24715, 32932, 41149, 49366, 57583, 65536];
952 data_sample_at_11111[122] = 101;
953 ref_cb[122] = vec![8314, 16564, 24814, 33064, 41314, 49564, 57814, 65536];
954 data_sample_at_11111[123] = 174;
955 ref_cb[123] = vec![8347, 16630, 24913, 33196, 41479, 49762, 58045, 65536];
956 data_sample_at_11111[124] = 126;
957 ref_cb[124] = vec![8380, 16696, 25012, 33328, 41644, 49960, 58276, 65536];
958 data_sample_at_11111[125] = 0;
959 ref_cb[125] = vec![8413, 16762, 25111, 33460, 41809, 50158, 58507, 65536];
960 data_sample_at_11111[126] = 0;
961 ref_cb[126] = vec![8192, 16574, 24956, 33338, 41720, 50102, 58484, 65536];
962 data_sample_at_11111[127] = 0;
963 ref_cb[127] = vec![8224, 16639, 25054, 33469, 41884, 50299, 58714, 65536];
964
965 for i in 0..128 {
967 let data = get_triggering_base_data(65536, i);
968
969 assert_eq!(data[11111], data_sample_at_11111[i]);
972
973 let chunks = ChunkerTestWrapper::default().next_block(&data, true);
978
979 let chunk_boundaries: Vec<usize> = get_chunk_boundaries(&chunks);
981
982 assert_eq!(chunk_boundaries, ref_cb[i]);
986 }
987
988 }
991}