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