@@ -59,13 +59,8 @@ impl BlockRange {
59
59
}
60
60
61
61
/// Get all [BlockRange] strictly contained in the given interval
62
- pub fn all_block_ranges_in ( interval : Range < BlockNumber > ) -> Vec < BlockRange > {
63
- let all_numbers: Vec < BlockNumber > =
64
- interval. skip_while ( |i| i % Self :: LENGTH != 0 ) . collect ( ) ;
65
- all_numbers
66
- . chunks_exact ( Self :: LENGTH as usize )
67
- . map ( |chunk| Self :: from_block_number ( chunk[ 0 ] ) )
68
- . collect ( )
62
+ pub fn all_block_ranges_in ( interval : Range < BlockNumber > ) -> BlockRangesSequence {
63
+ BlockRangesSequence :: new ( interval)
69
64
}
70
65
71
66
/// Create a BlockRange from a block number
@@ -149,6 +144,76 @@ impl From<BlockRange> for MKTreeNode {
149
144
150
145
impl MKMapKey for BlockRange { }
151
146
147
+ /// A continuous iterable sequence of [block ranges][BlockRange].
148
+ ///
149
+ /// Yielded block ranges are sized by [BlockRange::LENGTH], and always have
150
+ /// bounds that are multiples of [BlockRange::LENGTH].
151
+ #[ derive( Debug , Clone , Eq , PartialEq ) ]
152
+ pub struct BlockRangesSequence {
153
+ start : BlockNumber ,
154
+ end : BlockNumber ,
155
+ }
156
+
157
+ impl BlockRangesSequence {
158
+ /// Build the [BlockRangesSequence] strictly contained in the given interval.
159
+ ///
160
+ /// The interval bounds will be corrected to be multiples of [BlockRange::LENGTH].
161
+ pub fn new ( interval : Range < BlockNumber > ) -> Self {
162
+ let start = if ( interval. start % BlockRange :: LENGTH ) == 0 {
163
+ interval. start
164
+ } else {
165
+ BlockRange :: start ( interval. start ) + BlockRange :: LENGTH
166
+ } ;
167
+ let end = BlockRange :: start ( interval. end ) ;
168
+
169
+ Self { start, end }
170
+ }
171
+
172
+ /// Returns the start of the block ranges sequence.
173
+ pub fn start ( & self ) -> BlockNumber {
174
+ self . start
175
+ }
176
+
177
+ /// Returns the end of the block ranges sequence.
178
+ pub fn end ( & self ) -> BlockNumber {
179
+ self . end
180
+ }
181
+
182
+ /// Returns `true` if the block ranges sequence contains no elements.
183
+ pub fn is_empty ( & self ) -> bool {
184
+ self . len ( ) == 0
185
+ }
186
+
187
+ /// Consume `self` into a new Vec
188
+ pub fn into_vec ( self ) -> Vec < BlockRange > {
189
+ self . into_iter ( ) . collect ( )
190
+ }
191
+ }
192
+
193
+ impl Iterator for BlockRangesSequence {
194
+ type Item = BlockRange ;
195
+
196
+ fn next ( & mut self ) -> Option < Self :: Item > {
197
+ if self . start >= self . end {
198
+ return None ;
199
+ }
200
+
201
+ let block_range = BlockRange :: from_block_number ( self . start ) ;
202
+ self . start = block_range. end ;
203
+ Some ( block_range)
204
+ }
205
+
206
+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
207
+ ( self . start as usize , Some ( self . end as usize ) )
208
+ }
209
+ }
210
+
211
+ impl ExactSizeIterator for BlockRangesSequence {
212
+ fn len ( & self ) -> usize {
213
+ ( ( self . end - self . start ) / BlockRange :: LENGTH ) as usize
214
+ }
215
+ }
216
+
152
217
#[ cfg( test) ]
153
218
mod tests {
154
219
use std:: ops:: Not ;
@@ -214,28 +279,28 @@ mod tests {
214
279
215
280
#[ test]
216
281
fn test_block_range_all_block_ranges_in ( ) {
217
- assert_eq ! ( BlockRange :: all_block_ranges_in( 0 ..0 ) , vec![ ] ) ;
218
- assert_eq ! ( BlockRange :: all_block_ranges_in( 0 ..1 ) , vec![ ] ) ;
219
- assert_eq ! ( BlockRange :: all_block_ranges_in( 0 ..14 ) , vec![ ] ) ;
220
- assert_eq ! ( BlockRange :: all_block_ranges_in( 1 ..15 ) , vec![ ] ) ;
282
+ assert_eq ! ( BlockRange :: all_block_ranges_in( 0 ..0 ) . into_vec ( ) , vec![ ] ) ;
283
+ assert_eq ! ( BlockRange :: all_block_ranges_in( 0 ..1 ) . into_vec ( ) , vec![ ] ) ;
284
+ assert_eq ! ( BlockRange :: all_block_ranges_in( 0 ..14 ) . into_vec ( ) , vec![ ] ) ;
285
+ assert_eq ! ( BlockRange :: all_block_ranges_in( 1 ..15 ) . into_vec ( ) , vec![ ] ) ;
221
286
assert_eq ! (
222
- BlockRange :: all_block_ranges_in( 0 ..15 ) ,
287
+ BlockRange :: all_block_ranges_in( 0 ..15 ) . into_vec ( ) ,
223
288
vec![ BlockRange :: new( 0 , 15 ) ]
224
289
) ;
225
290
assert_eq ! (
226
- BlockRange :: all_block_ranges_in( 0 ..16 ) ,
291
+ BlockRange :: all_block_ranges_in( 0 ..16 ) . into_vec ( ) ,
227
292
vec![ BlockRange :: new( 0 , 15 ) ]
228
293
) ;
229
294
assert_eq ! (
230
- BlockRange :: all_block_ranges_in( 14 ..30 ) ,
295
+ BlockRange :: all_block_ranges_in( 14 ..30 ) . into_vec ( ) ,
231
296
vec![ BlockRange :: new( 15 , 30 ) ]
232
297
) ;
233
298
assert_eq ! (
234
- BlockRange :: all_block_ranges_in( 14 ..31 ) ,
299
+ BlockRange :: all_block_ranges_in( 14 ..31 ) . into_vec ( ) ,
235
300
vec![ BlockRange :: new( 15 , 30 ) ]
236
301
) ;
237
302
assert_eq ! (
238
- BlockRange :: all_block_ranges_in( 14 ..61 ) ,
303
+ BlockRange :: all_block_ranges_in( 14 ..61 ) . into_vec ( ) ,
239
304
vec![
240
305
BlockRange :: new( 15 , 30 ) ,
241
306
BlockRange :: new( 30 , 45 ) ,
@@ -244,6 +309,35 @@ mod tests {
244
309
) ;
245
310
}
246
311
312
+ #[ test]
313
+ fn test_block_ranges_sequence_is_empty ( ) {
314
+ assert ! ( BlockRange :: all_block_ranges_in( 0 ..0 ) . is_empty( ) ) ;
315
+ assert ! ( BlockRange :: all_block_ranges_in( 0 ..1 ) . is_empty( ) ) ;
316
+ assert ! ( BlockRange :: all_block_ranges_in( 0 ..14 ) . is_empty( ) ) ;
317
+ assert ! ( BlockRange :: all_block_ranges_in( 1 ..15 ) . is_empty( ) ) ;
318
+ assert ! ( BlockRange :: all_block_ranges_in( 0 ..15 ) . is_empty( ) . not( ) ) ;
319
+ assert ! ( BlockRange :: all_block_ranges_in( 0 ..16 ) . is_empty( ) . not( ) ) ;
320
+ assert ! ( BlockRange :: all_block_ranges_in( 14 ..30 ) . is_empty( ) . not( ) ) ;
321
+ assert ! ( BlockRange :: all_block_ranges_in( 14 ..31 ) . is_empty( ) . not( ) ) ;
322
+ assert ! ( BlockRange :: all_block_ranges_in( 14 ..61 ) . is_empty( ) . not( ) ) ;
323
+ }
324
+
325
+ #[ test]
326
+ fn test_block_ranges_sequence_len ( ) {
327
+ assert_eq ! (
328
+ BlockRange :: all_block_ranges_in( 0 ..( BlockRange :: LENGTH - 1 ) ) . len( ) ,
329
+ 0
330
+ ) ;
331
+ assert_eq ! (
332
+ BlockRange :: all_block_ranges_in( 0 ..( BlockRange :: LENGTH ) ) . len( ) ,
333
+ 1
334
+ ) ;
335
+ assert_eq ! (
336
+ BlockRange :: all_block_ranges_in( 0 ..( BlockRange :: LENGTH * 15 ) ) . len( ) ,
337
+ 15
338
+ ) ;
339
+ }
340
+
247
341
#[ test]
248
342
fn test_block_range_from_number ( ) {
249
343
assert_eq ! ( BlockRange :: from_block_number( 0 ) , BlockRange :: new( 0 , 15 ) ) ;
0 commit comments