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