@@ -283,7 +283,8 @@ impl<T, const N: usize> HistoryBuffer<T, N> {
283
283
}
284
284
}
285
285
286
- /// Returns an iterator for iterating over the buffer from oldest to newest.
286
+ /// Returns double ended iterator for iterating over the buffer from
287
+ /// the oldest to the newest and back.
287
288
///
288
289
/// # Examples
289
290
///
@@ -298,19 +299,19 @@ impl<T, const N: usize> HistoryBuffer<T, N> {
298
299
/// }
299
300
/// ```
300
301
pub fn oldest_ordered ( & self ) -> OldestOrdered < ' _ , T , N > {
301
- if self . filled {
302
- OldestOrdered {
302
+ match ( self . oldest_index ( ) , self . recent_index ( ) ) {
303
+ ( Some ( oldest_index ) , Some ( recent_index ) ) => OldestOrdered {
303
304
buf : self ,
304
- cur : self . write_at ,
305
- wrapped : false ,
306
- }
307
- } else {
308
- // special case: act like we wrapped already to handle empty buffer.
309
- OldestOrdered {
305
+ next : oldest_index,
306
+ back : recent_index,
307
+ done : false ,
308
+ } ,
309
+ _ => OldestOrdered {
310
310
buf : self ,
311
- cur : 0 ,
312
- wrapped : true ,
313
- }
311
+ next : 0 ,
312
+ back : 0 ,
313
+ done : true ,
314
+ } ,
314
315
}
315
316
}
316
317
}
@@ -403,30 +404,50 @@ where
403
404
}
404
405
}
405
406
406
- /// An iterator on the underlying buffer ordered from oldest data to newest
407
+ /// Double ended iterator on the underlying buffer ordered from the oldest data
408
+ /// to the newest
407
409
#[ derive( Clone ) ]
408
410
pub struct OldestOrdered < ' a , T , const N : usize > {
409
411
buf : & ' a HistoryBuffer < T , N > ,
410
- cur : usize ,
411
- wrapped : bool ,
412
+ next : usize ,
413
+ back : usize ,
414
+ done : bool ,
412
415
}
413
416
414
417
impl < ' a , T , const N : usize > Iterator for OldestOrdered < ' a , T , N > {
415
418
type Item = & ' a T ;
416
419
417
420
fn next ( & mut self ) -> Option < & ' a T > {
418
- if self . cur == self . buf . len ( ) && self . buf . filled {
419
- // roll-over
420
- self . cur = 0 ;
421
- self . wrapped = true ;
421
+ if self . done {
422
+ return None ;
422
423
}
423
424
424
- if self . cur == self . buf . write_at && self . wrapped {
425
+ if self . next == self . back {
426
+ self . done = true ;
427
+ }
428
+
429
+ let item = & self . buf [ self . next ] ;
430
+
431
+ self . next = if self . next == N - 1 { 0 } else { self . next + 1 } ;
432
+
433
+ Some ( item)
434
+ }
435
+ }
436
+
437
+ impl < ' a , T , const N : usize > DoubleEndedIterator for OldestOrdered < ' a , T , N > {
438
+ fn next_back ( & mut self ) -> Option < Self :: Item > {
439
+ if self . done {
425
440
return None ;
426
441
}
427
442
428
- let item = & self . buf [ self . cur ] ;
429
- self . cur += 1 ;
443
+ if self . next == self . back {
444
+ self . done = true ;
445
+ }
446
+
447
+ let item = & self . buf [ self . back ] ;
448
+
449
+ self . back = if self . back == 0 { N - 1 } else { self . back - 1 } ;
450
+
430
451
Some ( item)
431
452
}
432
453
}
@@ -609,18 +630,28 @@ mod tests {
609
630
let mut iter = buffer. oldest_ordered ( ) ;
610
631
assert_eq ! ( iter. next( ) , None ) ;
611
632
assert_eq ! ( iter. next( ) , None ) ;
633
+ assert_eq ! ( iter. next_back( ) , None ) ;
634
+ assert_eq ! ( iter. next_back( ) , None ) ;
612
635
613
636
// test on a un-filled buffer
614
637
let mut buffer: HistoryBuffer < u8 , 6 > = HistoryBuffer :: new ( ) ;
615
638
buffer. extend ( [ 1 , 2 , 3 ] ) ;
616
639
assert_eq ! ( buffer. len( ) , 3 ) ;
617
640
assert_eq_iter ( buffer. oldest_ordered ( ) , & [ 1 , 2 , 3 ] ) ;
641
+ assert_eq_iter ( buffer. oldest_ordered ( ) . rev ( ) , & [ 3 , 2 , 1 ] ) ;
642
+ let mut iter = buffer. oldest_ordered ( ) ;
643
+ assert_eq ! ( iter. next( ) , Some ( & 1 ) ) ;
644
+ assert_eq ! ( iter. next_back( ) , Some ( & 3 ) ) ;
645
+ assert_eq ! ( iter. next_back( ) , Some ( & 2 ) ) ;
646
+ assert_eq ! ( iter. next_back( ) , None ) ;
647
+ assert_eq ! ( iter. next( ) , None ) ;
618
648
619
649
// test on a filled buffer
620
650
let mut buffer: HistoryBuffer < u8 , 6 > = HistoryBuffer :: new ( ) ;
621
651
buffer. extend ( [ 0 , 0 , 0 , 1 , 2 , 3 , 4 , 5 , 6 ] ) ;
622
652
assert_eq ! ( buffer. len( ) , 6 ) ;
623
653
assert_eq_iter ( buffer. oldest_ordered ( ) , & [ 1 , 2 , 3 , 4 , 5 , 6 ] ) ;
654
+ assert_eq_iter ( buffer. oldest_ordered ( ) . rev ( ) , & [ 6 , 5 , 4 , 3 , 2 , 1 ] ) ;
624
655
625
656
// comprehensive test all cases
626
657
for n in 0 ..50 {
@@ -631,6 +662,10 @@ mod tests {
631
662
buffer. oldest_ordered ( ) . copied ( ) ,
632
663
n. saturating_sub ( N as u8 ) ..n,
633
664
) ;
665
+ assert_eq_iter (
666
+ buffer. oldest_ordered ( ) . rev ( ) . copied ( ) ,
667
+ ( n. saturating_sub ( N as u8 ) ..n) . rev ( ) ,
668
+ ) ;
634
669
}
635
670
}
636
671
0 commit comments