assembler.rs 21 KB

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