/ node / sync / src / block_sync / helpers.rs
helpers.rs
  1  // Copyright (c) 2025 ADnet Contributors
  2  // This file is part of the AlphaOS library.
  3  
  4  // Licensed under the Apache License, Version 2.0 (the "License");
  5  // you may not use this file except in compliance with the License.
  6  // You may obtain a copy of the License at:
  7  
  8  // http://www.apache.org/licenses/LICENSE-2.0
  9  
 10  // Unless required by applicable law or agreed to in writing, software
 11  // distributed under the License is distributed on an "AS IS" BASIS,
 12  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  // See the License for the specific language governing permissions and
 14  // limitations under the License.
 15  
 16  /// Generates a string containing all continuous sequenences within the list of numbers.
 17  ///
 18  /// The function expects the input to already be sorted.
 19  pub fn rangify_heights(heights: &[u32]) -> String {
 20      let mut iter = heights.iter().copied().peekable();
 21      let mut ret = String::from("[");
 22      let mut first = true;
 23  
 24      while let Some(next_height) = iter.next() {
 25          let start = next_height;
 26          let mut curr_height = start;
 27  
 28          while let Some(next_height) = iter.peek().copied() {
 29              if next_height == curr_height + 1 {
 30                  curr_height += 1;
 31                  let _ = iter.next();
 32              } else {
 33                  break;
 34              }
 35          }
 36  
 37          if first {
 38              first = false;
 39          } else {
 40              ret.push_str(", ");
 41          }
 42  
 43          if curr_height == start {
 44              ret.push_str(&format!("{curr_height}"));
 45          } else {
 46              ret.push_str(&format!("{start}-{curr_height}"));
 47          }
 48      }
 49  
 50      ret.push(']');
 51      ret
 52  }
 53  
 54  #[cfg(test)]
 55  mod tests {
 56      use super::rangify_heights;
 57  
 58      #[test]
 59      fn test_rangify_heights_empty() {
 60          let heights = &[];
 61  
 62          let rangified = rangify_heights(heights);
 63          assert_eq!(rangified, "[]");
 64      }
 65  
 66      #[test]
 67      fn test_rangify_heights_single_value() {
 68          let heights = &[52425];
 69  
 70          let rangified = rangify_heights(heights);
 71          assert_eq!(rangified, "[52425]");
 72      }
 73  
 74      #[test]
 75      fn test_rangify_large_continuous() {
 76          let start = 16353;
 77          let end = start + 52414;
 78  
 79          let heights: Vec<u32> = (start..=end).collect();
 80  
 81          let rangified = rangify_heights(&heights);
 82          assert_eq!(rangified, format!("[{start}-{end}]"));
 83      }
 84  
 85      #[test]
 86      fn test_rangify_many_small() {
 87          let mut heights = vec![];
 88          let mut expected = vec![];
 89  
 90          for idx in 0..100 {
 91              let start = idx * 4;
 92              let mid = idx * 4 + 1;
 93              let end = idx * 4 + 2;
 94              expected.push(format!("{start}-{end}"));
 95              heights.push(start);
 96              heights.push(mid);
 97              heights.push(end);
 98          }
 99  
100          let rangified = rangify_heights(&heights);
101          let expected = format!("[{}]", expected.join(", "));
102  
103          assert_eq!(rangified, expected);
104      }
105  
106      #[test]
107      fn test_rangify_heights_multiple_ranges() {
108          let heights = &[0, 1, 3, 4, 5, 6, 7, 10, 11, 12, 20, 22, 23, 24, 25, 27, 28];
109  
110          let rangified = rangify_heights(heights);
111          assert_eq!(rangified, "[0-1, 3-7, 10-12, 20, 22-25, 27-28]");
112      }
113  }