1 use core::fmt;
2 
3 use crate::config::ASSEMBLER_MAX_SEGMENT_COUNT;
4 
5 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
6 pub struct TooManyHolesError;
7 
8 /// A contiguous chunk of absent data, followed by a contiguous chunk of present data.
9 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
10 #[cfg_attr(feature = "defmt", derive(defmt::Format))]
11 struct Contig {
12     hole_size: usize,
13     data_size: usize,
14 }
15 
16 impl fmt::Display for Contig {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result17     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
18         if self.has_hole() {
19             write!(f, "({})", self.hole_size)?;
20         }
21         if self.has_hole() && self.has_data() {
22             write!(f, " ")?;
23         }
24         if self.has_data() {
25             write!(f, "{}", self.data_size)?;
26         }
27         Ok(())
28     }
29 }
30 
31 impl Contig {
empty() -> Contig32     const fn empty() -> Contig {
33         Contig {
34             hole_size: 0,
35             data_size: 0,
36         }
37     }
38 
hole_and_data(hole_size: usize, data_size: usize) -> Contig39     fn hole_and_data(hole_size: usize, data_size: usize) -> Contig {
40         Contig {
41             hole_size,
42             data_size,
43         }
44     }
45 
has_hole(&self) -> bool46     fn has_hole(&self) -> bool {
47         self.hole_size != 0
48     }
49 
has_data(&self) -> bool50     fn has_data(&self) -> bool {
51         self.data_size != 0
52     }
53 
total_size(&self) -> usize54     fn total_size(&self) -> usize {
55         self.hole_size + self.data_size
56     }
57 
shrink_hole_by(&mut self, size: usize)58     fn shrink_hole_by(&mut self, size: usize) {
59         self.hole_size -= size;
60     }
61 
shrink_hole_to(&mut self, size: usize)62     fn shrink_hole_to(&mut self, size: usize) {
63         debug_assert!(self.hole_size >= size);
64 
65         let total_size = self.total_size();
66         self.hole_size = size;
67         self.data_size = total_size - size;
68     }
69 }
70 
71 /// A buffer (re)assembler.
72 ///
73 /// Currently, up to a hardcoded limit of 4 or 32 holes can be tracked in the buffer.
74 #[derive(Debug, PartialEq, Eq, Clone)]
75 #[cfg_attr(feature = "defmt", derive(defmt::Format))]
76 pub struct Assembler {
77     contigs: [Contig; ASSEMBLER_MAX_SEGMENT_COUNT],
78 }
79 
80 impl fmt::Display for Assembler {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result81     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
82         write!(f, "[ ")?;
83         for contig in self.contigs.iter() {
84             if !contig.has_data() {
85                 break;
86             }
87             write!(f, "{contig} ")?;
88         }
89         write!(f, "]")?;
90         Ok(())
91     }
92 }
93 
94 // Invariant on Assembler::contigs:
95 // - There's an index `i` where all contigs before have data, and all contigs after don't (are unused).
96 // - All contigs with data must have hole_size != 0, except the first.
97 
98 impl Assembler {
99     /// Create a new buffer assembler.
new() -> Assembler100     pub const fn new() -> Assembler {
101         const EMPTY: Contig = Contig::empty();
102         Assembler {
103             contigs: [EMPTY; ASSEMBLER_MAX_SEGMENT_COUNT],
104         }
105     }
106 
clear(&mut self)107     pub fn clear(&mut self) {
108         self.contigs.fill(Contig::empty());
109     }
110 
front(&self) -> Contig111     fn front(&self) -> Contig {
112         self.contigs[0]
113     }
114 
115     /// Return length of the front contiguous range without removing it from the assembler
peek_front(&self) -> usize116     pub fn peek_front(&self) -> usize {
117         let front = self.front();
118         if front.has_hole() {
119             0
120         } else {
121             front.data_size
122         }
123     }
124 
back(&self) -> Contig125     fn back(&self) -> Contig {
126         self.contigs[self.contigs.len() - 1]
127     }
128 
129     /// Return whether the assembler contains no data.
is_empty(&self) -> bool130     pub fn is_empty(&self) -> bool {
131         !self.front().has_data()
132     }
133 
134     /// Remove a contig at the given index.
remove_contig_at(&mut self, at: usize)135     fn remove_contig_at(&mut self, at: usize) {
136         debug_assert!(self.contigs[at].has_data());
137 
138         for i in at..self.contigs.len() - 1 {
139             if !self.contigs[i].has_data() {
140                 return;
141             }
142             self.contigs[i] = self.contigs[i + 1];
143         }
144 
145         // Removing the last one.
146         self.contigs[self.contigs.len() - 1] = Contig::empty();
147     }
148 
149     /// Add a contig at the given index, and return a pointer to it.
add_contig_at(&mut self, at: usize) -> Result<&mut Contig, TooManyHolesError>150     fn add_contig_at(&mut self, at: usize) -> Result<&mut Contig, TooManyHolesError> {
151         if self.back().has_data() {
152             return Err(TooManyHolesError);
153         }
154 
155         for i in (at + 1..self.contigs.len()).rev() {
156             self.contigs[i] = self.contigs[i - 1];
157         }
158 
159         self.contigs[at] = Contig::empty();
160         Ok(&mut self.contigs[at])
161     }
162 
163     /// Add a new contiguous range to the assembler,
164     /// or return `Err(TooManyHolesError)` if too many discontiguities are already recorded.
add(&mut self, mut offset: usize, size: usize) -> Result<(), TooManyHolesError>165     pub fn add(&mut self, mut offset: usize, size: usize) -> Result<(), TooManyHolesError> {
166         if size == 0 {
167             return Ok(());
168         }
169 
170         let mut i = 0;
171 
172         // Find index of the contig containing the start of the range.
173         loop {
174             if i == self.contigs.len() {
175                 // The new range is after all the previous ranges, but there/s no space to add it.
176                 return Err(TooManyHolesError);
177             }
178             let contig = &mut self.contigs[i];
179             if !contig.has_data() {
180                 // The new range is after all the previous ranges. Add it.
181                 *contig = Contig::hole_and_data(offset, size);
182                 return Ok(());
183             }
184             if offset <= contig.total_size() {
185                 break;
186             }
187             offset -= contig.total_size();
188             i += 1;
189         }
190 
191         let contig = &mut self.contigs[i];
192         if offset < contig.hole_size {
193             // Range starts within the hole.
194 
195             if offset + size < contig.hole_size {
196                 // Range also ends within the hole.
197                 let new_contig = self.add_contig_at(i)?;
198                 new_contig.hole_size = offset;
199                 new_contig.data_size = size;
200 
201                 // Previous contigs[index] got moved to contigs[index+1]
202                 self.contigs[i + 1].shrink_hole_by(offset + size);
203                 return Ok(());
204             }
205 
206             // The range being added covers both a part of the hole and a part of the data
207             // in this contig, shrink the hole in this contig.
208             contig.shrink_hole_to(offset);
209         }
210 
211         // coalesce contigs to the right.
212         let mut j = i + 1;
213         while j < self.contigs.len()
214             && self.contigs[j].has_data()
215             && offset + size >= self.contigs[i].total_size() + self.contigs[j].hole_size
216         {
217             self.contigs[i].data_size += self.contigs[j].total_size();
218             j += 1;
219         }
220         let shift = j - i - 1;
221         if shift != 0 {
222             for x in i + 1..self.contigs.len() {
223                 if !self.contigs[x].has_data() {
224                     break;
225                 }
226 
227                 self.contigs[x] = self
228                     .contigs
229                     .get(x + shift)
230                     .copied()
231                     .unwrap_or_else(Contig::empty);
232             }
233         }
234 
235         if offset + size > self.contigs[i].total_size() {
236             // The added range still extends beyond the current contig. Increase data size.
237             let left = offset + size - self.contigs[i].total_size();
238             self.contigs[i].data_size += left;
239 
240             // Decrease hole size of the next, if any.
241             if i + 1 < self.contigs.len() && self.contigs[i + 1].has_data() {
242                 self.contigs[i + 1].hole_size -= left;
243             }
244         }
245 
246         Ok(())
247     }
248 
249     /// Remove a contiguous range from the front of the assembler.
250     /// If no such range, return 0.
remove_front(&mut self) -> usize251     pub fn remove_front(&mut self) -> usize {
252         let front = self.front();
253         if front.has_hole() || !front.has_data() {
254             0
255         } else {
256             self.remove_contig_at(0);
257             debug_assert!(front.data_size > 0);
258             front.data_size
259         }
260     }
261 
262     /// Add a segment, then remove_front.
263     ///
264     /// This is equivalent to calling `add` then `remove_front` individually,
265     /// except it's guaranteed to not fail when offset = 0.
266     /// This is required for TCP: we must never drop the next expected segment, or
267     /// the protocol might get stuck.
add_then_remove_front( &mut self, offset: usize, size: usize, ) -> Result<usize, TooManyHolesError>268     pub fn add_then_remove_front(
269         &mut self,
270         offset: usize,
271         size: usize,
272     ) -> Result<usize, TooManyHolesError> {
273         // This is the only case where a segment at offset=0 would cause the
274         // total amount of contigs to rise (and therefore can potentially cause
275         // a TooManyHolesError). Handle it in a way that is guaranteed to succeed.
276         if offset == 0 && size < self.contigs[0].hole_size {
277             self.contigs[0].hole_size -= size;
278             return Ok(size);
279         }
280 
281         self.add(offset, size)?;
282         Ok(self.remove_front())
283     }
284 
285     /// Iterate over all of the contiguous data ranges.
286     ///
287     /// This is used in calculating what data ranges have been received. The offset indicates the
288     /// number of bytes of contiguous data received before the beginnings of this Assembler.
289     ///
290     ///    Data        Hole        Data
291     /// |--- 100 ---|--- 200 ---|--- 100 ---|
292     ///
293     /// An offset of 1500 would return the ranges: ``(1500, 1600), (1800, 1900)``
iter_data(&self, first_offset: usize) -> AssemblerIter294     pub fn iter_data(&self, first_offset: usize) -> AssemblerIter {
295         AssemblerIter::new(self, first_offset)
296     }
297 }
298 
299 pub struct AssemblerIter<'a> {
300     assembler: &'a Assembler,
301     offset: usize,
302     index: usize,
303     left: usize,
304     right: usize,
305 }
306 
307 impl<'a> AssemblerIter<'a> {
new(assembler: &'a Assembler, offset: usize) -> AssemblerIter<'a>308     fn new(assembler: &'a Assembler, offset: usize) -> AssemblerIter<'a> {
309         AssemblerIter {
310             assembler,
311             offset,
312             index: 0,
313             left: 0,
314             right: 0,
315         }
316     }
317 }
318 
319 impl<'a> Iterator for AssemblerIter<'a> {
320     type Item = (usize, usize);
321 
next(&mut self) -> Option<(usize, usize)>322     fn next(&mut self) -> Option<(usize, usize)> {
323         let mut data_range = None;
324         while data_range.is_none() && self.index < self.assembler.contigs.len() {
325             let contig = self.assembler.contigs[self.index];
326             self.left += contig.hole_size;
327             self.right = self.left + contig.data_size;
328             data_range = if self.left < self.right {
329                 let data_range = (self.left + self.offset, self.right + self.offset);
330                 self.left = self.right;
331                 Some(data_range)
332             } else {
333                 None
334             };
335             self.index += 1;
336         }
337         data_range
338     }
339 }
340 
341 #[cfg(test)]
342 mod test {
343     use super::*;
344     use std::vec::Vec;
345 
346     impl From<Vec<(usize, usize)>> for Assembler {
from(vec: Vec<(usize, usize)>) -> Assembler347         fn from(vec: Vec<(usize, usize)>) -> Assembler {
348             const EMPTY: Contig = Contig::empty();
349 
350             let mut contigs = [EMPTY; ASSEMBLER_MAX_SEGMENT_COUNT];
351             for (i, &(hole_size, data_size)) in vec.iter().enumerate() {
352                 contigs[i] = Contig {
353                     hole_size,
354                     data_size,
355                 };
356             }
357             Assembler { contigs }
358         }
359     }
360 
361     macro_rules! contigs {
362         [$( $x:expr ),*] => ({
363             Assembler::from(vec![$( $x ),*])
364         })
365     }
366 
367     #[test]
test_new()368     fn test_new() {
369         let assr = Assembler::new();
370         assert_eq!(assr, contigs![]);
371     }
372 
373     #[test]
test_empty_add_full()374     fn test_empty_add_full() {
375         let mut assr = Assembler::new();
376         assert_eq!(assr.add(0, 16), Ok(()));
377         assert_eq!(assr, contigs![(0, 16)]);
378     }
379 
380     #[test]
test_empty_add_front()381     fn test_empty_add_front() {
382         let mut assr = Assembler::new();
383         assert_eq!(assr.add(0, 4), Ok(()));
384         assert_eq!(assr, contigs![(0, 4)]);
385     }
386 
387     #[test]
test_empty_add_back()388     fn test_empty_add_back() {
389         let mut assr = Assembler::new();
390         assert_eq!(assr.add(12, 4), Ok(()));
391         assert_eq!(assr, contigs![(12, 4)]);
392     }
393 
394     #[test]
test_empty_add_mid()395     fn test_empty_add_mid() {
396         let mut assr = Assembler::new();
397         assert_eq!(assr.add(4, 8), Ok(()));
398         assert_eq!(assr, contigs![(4, 8)]);
399     }
400 
401     #[test]
test_partial_add_front()402     fn test_partial_add_front() {
403         let mut assr = contigs![(4, 8)];
404         assert_eq!(assr.add(0, 4), Ok(()));
405         assert_eq!(assr, contigs![(0, 12)]);
406     }
407 
408     #[test]
test_partial_add_back()409     fn test_partial_add_back() {
410         let mut assr = contigs![(4, 8)];
411         assert_eq!(assr.add(12, 4), Ok(()));
412         assert_eq!(assr, contigs![(4, 12)]);
413     }
414 
415     #[test]
test_partial_add_front_overlap()416     fn test_partial_add_front_overlap() {
417         let mut assr = contigs![(4, 8)];
418         assert_eq!(assr.add(0, 8), Ok(()));
419         assert_eq!(assr, contigs![(0, 12)]);
420     }
421 
422     #[test]
test_partial_add_front_overlap_split()423     fn test_partial_add_front_overlap_split() {
424         let mut assr = contigs![(4, 8)];
425         assert_eq!(assr.add(2, 6), Ok(()));
426         assert_eq!(assr, contigs![(2, 10)]);
427     }
428 
429     #[test]
test_partial_add_back_overlap()430     fn test_partial_add_back_overlap() {
431         let mut assr = contigs![(4, 8)];
432         assert_eq!(assr.add(8, 8), Ok(()));
433         assert_eq!(assr, contigs![(4, 12)]);
434     }
435 
436     #[test]
test_partial_add_back_overlap_split()437     fn test_partial_add_back_overlap_split() {
438         let mut assr = contigs![(4, 8)];
439         assert_eq!(assr.add(10, 4), Ok(()));
440         assert_eq!(assr, contigs![(4, 10)]);
441     }
442 
443     #[test]
test_partial_add_both_overlap()444     fn test_partial_add_both_overlap() {
445         let mut assr = contigs![(4, 8)];
446         assert_eq!(assr.add(0, 16), Ok(()));
447         assert_eq!(assr, contigs![(0, 16)]);
448     }
449 
450     #[test]
test_partial_add_both_overlap_split()451     fn test_partial_add_both_overlap_split() {
452         let mut assr = contigs![(4, 8)];
453         assert_eq!(assr.add(2, 12), Ok(()));
454         assert_eq!(assr, contigs![(2, 12)]);
455     }
456 
457     #[test]
test_rejected_add_keeps_state()458     fn test_rejected_add_keeps_state() {
459         let mut assr = Assembler::new();
460         for c in 1..=ASSEMBLER_MAX_SEGMENT_COUNT {
461             assert_eq!(assr.add(c * 10, 3), Ok(()));
462         }
463         // Maximum of allowed holes is reached
464         let assr_before = assr.clone();
465         assert_eq!(assr.add(1, 3), Err(TooManyHolesError));
466         assert_eq!(assr_before, assr);
467     }
468 
469     #[test]
test_empty_remove_front()470     fn test_empty_remove_front() {
471         let mut assr = contigs![];
472         assert_eq!(assr.remove_front(), 0);
473     }
474 
475     #[test]
test_trailing_hole_remove_front()476     fn test_trailing_hole_remove_front() {
477         let mut assr = contigs![(0, 4)];
478         assert_eq!(assr.remove_front(), 4);
479         assert_eq!(assr, contigs![]);
480     }
481 
482     #[test]
test_trailing_data_remove_front()483     fn test_trailing_data_remove_front() {
484         let mut assr = contigs![(0, 4), (4, 4)];
485         assert_eq!(assr.remove_front(), 4);
486         assert_eq!(assr, contigs![(4, 4)]);
487     }
488 
489     #[test]
test_boundary_case_remove_front()490     fn test_boundary_case_remove_front() {
491         let mut vec = vec![(1, 1); ASSEMBLER_MAX_SEGMENT_COUNT];
492         vec[0] = (0, 2);
493         let mut assr = Assembler::from(vec);
494         assert_eq!(assr.remove_front(), 2);
495         let mut vec = vec![(1, 1); ASSEMBLER_MAX_SEGMENT_COUNT];
496         vec[ASSEMBLER_MAX_SEGMENT_COUNT - 1] = (0, 0);
497         let exp_assr = Assembler::from(vec);
498         assert_eq!(assr, exp_assr);
499     }
500 
501     #[test]
test_shrink_next_hole()502     fn test_shrink_next_hole() {
503         let mut assr = Assembler::new();
504         assert_eq!(assr.add(100, 10), Ok(()));
505         assert_eq!(assr.add(50, 10), Ok(()));
506         assert_eq!(assr.add(40, 30), Ok(()));
507         assert_eq!(assr, contigs![(40, 30), (30, 10)]);
508     }
509 
510     #[test]
test_join_two()511     fn test_join_two() {
512         let mut assr = Assembler::new();
513         assert_eq!(assr.add(10, 10), Ok(()));
514         assert_eq!(assr.add(50, 10), Ok(()));
515         assert_eq!(assr.add(15, 40), Ok(()));
516         assert_eq!(assr, contigs![(10, 50)]);
517     }
518 
519     #[test]
test_join_two_reversed()520     fn test_join_two_reversed() {
521         let mut assr = Assembler::new();
522         assert_eq!(assr.add(50, 10), Ok(()));
523         assert_eq!(assr.add(10, 10), Ok(()));
524         assert_eq!(assr.add(15, 40), Ok(()));
525         assert_eq!(assr, contigs![(10, 50)]);
526     }
527 
528     #[test]
test_join_two_overlong()529     fn test_join_two_overlong() {
530         let mut assr = Assembler::new();
531         assert_eq!(assr.add(50, 10), Ok(()));
532         assert_eq!(assr.add(10, 10), Ok(()));
533         assert_eq!(assr.add(15, 60), Ok(()));
534         assert_eq!(assr, contigs![(10, 65)]);
535     }
536 
537     #[test]
test_iter_empty()538     fn test_iter_empty() {
539         let assr = Assembler::new();
540         let segments: Vec<_> = assr.iter_data(10).collect();
541         assert_eq!(segments, vec![]);
542     }
543 
544     #[test]
test_iter_full()545     fn test_iter_full() {
546         let mut assr = Assembler::new();
547         assert_eq!(assr.add(0, 16), Ok(()));
548         let segments: Vec<_> = assr.iter_data(10).collect();
549         assert_eq!(segments, vec![(10, 26)]);
550     }
551 
552     #[test]
test_iter_offset()553     fn test_iter_offset() {
554         let mut assr = Assembler::new();
555         assert_eq!(assr.add(0, 16), Ok(()));
556         let segments: Vec<_> = assr.iter_data(100).collect();
557         assert_eq!(segments, vec![(100, 116)]);
558     }
559 
560     #[test]
test_iter_one_front()561     fn test_iter_one_front() {
562         let mut assr = Assembler::new();
563         assert_eq!(assr.add(0, 4), Ok(()));
564         let segments: Vec<_> = assr.iter_data(10).collect();
565         assert_eq!(segments, vec![(10, 14)]);
566     }
567 
568     #[test]
test_iter_one_back()569     fn test_iter_one_back() {
570         let mut assr = Assembler::new();
571         assert_eq!(assr.add(12, 4), Ok(()));
572         let segments: Vec<_> = assr.iter_data(10).collect();
573         assert_eq!(segments, vec![(22, 26)]);
574     }
575 
576     #[test]
test_iter_one_mid()577     fn test_iter_one_mid() {
578         let mut assr = Assembler::new();
579         assert_eq!(assr.add(4, 8), Ok(()));
580         let segments: Vec<_> = assr.iter_data(10).collect();
581         assert_eq!(segments, vec![(14, 22)]);
582     }
583 
584     #[test]
test_iter_one_trailing_gap()585     fn test_iter_one_trailing_gap() {
586         let assr = contigs![(4, 8)];
587         let segments: Vec<_> = assr.iter_data(100).collect();
588         assert_eq!(segments, vec![(104, 112)]);
589     }
590 
591     #[test]
test_iter_two_split()592     fn test_iter_two_split() {
593         let assr = contigs![(2, 6), (4, 1)];
594         let segments: Vec<_> = assr.iter_data(100).collect();
595         assert_eq!(segments, vec![(102, 108), (112, 113)]);
596     }
597 
598     #[test]
test_iter_three_split()599     fn test_iter_three_split() {
600         let assr = contigs![(2, 6), (2, 1), (2, 2)];
601         let segments: Vec<_> = assr.iter_data(100).collect();
602         assert_eq!(segments, vec![(102, 108), (110, 111), (113, 115)]);
603     }
604 
605     #[test]
test_issue_694()606     fn test_issue_694() {
607         let mut assr = Assembler::new();
608         assert_eq!(assr.add(0, 1), Ok(()));
609         assert_eq!(assr.add(2, 1), Ok(()));
610         assert_eq!(assr.add(1, 1), Ok(()));
611     }
612 
613     #[test]
test_add_then_remove_front()614     fn test_add_then_remove_front() {
615         let mut assr = Assembler::new();
616         assert_eq!(assr.add(50, 10), Ok(()));
617         assert_eq!(assr.add_then_remove_front(10, 10), Ok(0));
618         assert_eq!(assr, contigs![(10, 10), (30, 10)]);
619     }
620 
621     #[test]
test_add_then_remove_front_at_front()622     fn test_add_then_remove_front_at_front() {
623         let mut assr = Assembler::new();
624         assert_eq!(assr.add(50, 10), Ok(()));
625         assert_eq!(assr.add_then_remove_front(0, 10), Ok(10));
626         assert_eq!(assr, contigs![(40, 10)]);
627     }
628 
629     #[test]
test_add_then_remove_front_at_front_touch()630     fn test_add_then_remove_front_at_front_touch() {
631         let mut assr = Assembler::new();
632         assert_eq!(assr.add(50, 10), Ok(()));
633         assert_eq!(assr.add_then_remove_front(0, 50), Ok(60));
634         assert_eq!(assr, contigs![]);
635     }
636 
637     #[test]
test_add_then_remove_front_at_front_full()638     fn test_add_then_remove_front_at_front_full() {
639         let mut assr = Assembler::new();
640         for c in 1..=ASSEMBLER_MAX_SEGMENT_COUNT {
641             assert_eq!(assr.add(c * 10, 3), Ok(()));
642         }
643         // Maximum of allowed holes is reached
644         let assr_before = assr.clone();
645         assert_eq!(assr.add_then_remove_front(1, 3), Err(TooManyHolesError));
646         assert_eq!(assr_before, assr);
647     }
648 
649     #[test]
test_add_then_remove_front_at_front_full_offset_0()650     fn test_add_then_remove_front_at_front_full_offset_0() {
651         let mut assr = Assembler::new();
652         for c in 1..=ASSEMBLER_MAX_SEGMENT_COUNT {
653             assert_eq!(assr.add(c * 10, 3), Ok(()));
654         }
655         assert_eq!(assr.add_then_remove_front(0, 3), Ok(3));
656     }
657 
658     // Test against an obviously-correct but inefficient bitmap impl.
659     #[test]
test_random()660     fn test_random() {
661         use rand::Rng;
662 
663         const MAX_INDEX: usize = 256;
664 
665         for max_size in [2, 5, 10, 100] {
666             for _ in 0..300 {
667                 //println!("===");
668                 let mut assr = Assembler::new();
669                 let mut map = [false; MAX_INDEX];
670 
671                 for _ in 0..60 {
672                     let offset = rand::thread_rng().gen_range(0..MAX_INDEX - max_size - 1);
673                     let size = rand::thread_rng().gen_range(1..=max_size);
674 
675                     //println!("add {}..{} {}", offset, offset + size, size);
676                     // Real impl
677                     let res = assr.add(offset, size);
678 
679                     // Bitmap impl
680                     let mut map2 = map;
681                     map2[offset..][..size].fill(true);
682 
683                     let mut contigs = vec![];
684                     let mut hole: usize = 0;
685                     let mut data: usize = 0;
686                     for b in map2 {
687                         if b {
688                             data += 1;
689                         } else {
690                             if data != 0 {
691                                 contigs.push((hole, data));
692                                 hole = 0;
693                                 data = 0;
694                             }
695                             hole += 1;
696                         }
697                     }
698 
699                     // Compare.
700                     let wanted_res = if contigs.len() > ASSEMBLER_MAX_SEGMENT_COUNT {
701                         Err(TooManyHolesError)
702                     } else {
703                         Ok(())
704                     };
705                     assert_eq!(res, wanted_res);
706                     if res.is_ok() {
707                         map = map2;
708                         assert_eq!(assr, Assembler::from(contigs));
709                     }
710                 }
711             }
712         }
713     }
714 }
715