@@ -390,6 +390,77 @@ fn for_each() {
390390 assert_eq ! ( * db. stats. borrow( ) , BSStats { r: 1431 , w: 1431 , br: 88649 , bw: 88649 } ) ;
391391}
392392
393+ #[ test]
394+ fn for_each_cacheless ( ) {
395+ let mem = MemoryBlockstore :: default ( ) ;
396+ let db = TrackingBlockstore :: new ( & mem) ;
397+ let mut a = Amt :: new ( & db) ;
398+
399+ let mut indexes = Vec :: new ( ) ;
400+ for i in 0 ..10000 {
401+ if ( i + 1 ) % 3 == 0 {
402+ indexes. push ( i) ;
403+ }
404+ }
405+
406+ // Set all indices in the Amt
407+ for i in indexes. iter ( ) {
408+ a. set ( * i, tbytes ( b"value" ) ) . unwrap ( ) ;
409+ }
410+
411+ // Ensure all values were added into the amt
412+ for i in indexes. iter ( ) {
413+ assert_eq ! ( a. get( * i) . unwrap( ) , Some ( & tbytes( b"value" ) ) ) ;
414+ }
415+
416+ assert_eq ! ( a. count( ) , indexes. len( ) as u64 ) ;
417+
418+ // Iterate over amt with dirty cache. This should not touch the database at all.
419+ let mut x = 0 ;
420+ a. for_each_cacheless ( |_, _: & BytesDe | {
421+ x += 1 ;
422+ Ok ( ( ) )
423+ } )
424+ . unwrap ( ) ;
425+ #[ rustfmt:: skip]
426+ assert_eq ! ( * db. stats. borrow( ) , BSStats { r: 0 , w: 0 , br: 0 , bw: 0 } ) ;
427+ assert_eq ! ( x, indexes. len( ) ) ;
428+
429+ // Flush and regenerate amt
430+ let c = a. flush ( ) . unwrap ( ) ;
431+ let new_amt = Amt :: load ( & c, & db) . unwrap ( ) ;
432+ assert_eq ! ( new_amt. count( ) , indexes. len( ) as u64 ) ;
433+
434+ let mut x = 0 ;
435+ new_amt
436+ . for_each_cacheless ( |i, _: & BytesDe | {
437+ if i != indexes[ x] {
438+ panic ! (
439+ "for each cacheless found wrong index: expected {} got {}" ,
440+ indexes[ x] , i
441+ ) ;
442+ }
443+ x += 1 ;
444+ Ok ( ( ) )
445+ } )
446+ . unwrap ( ) ;
447+ assert_eq ! ( x, indexes. len( ) ) ;
448+
449+ // After 1st pass, the amount of block reads should be the same as in the caching iteration.
450+ #[ rustfmt:: skip]
451+ assert_eq ! ( * db. stats. borrow( ) , BSStats { r: 1431 , w: 1431 , br: 88649 , bw: 88649 } ) ;
452+
453+ new_amt. for_each_cacheless ( |_, _: & BytesDe | Ok ( ( ) ) ) . unwrap ( ) ;
454+ assert_eq ! (
455+ c. to_string( ) . as_str( ) ,
456+ "bafy2bzaceanqxtbsuyhqgxubiq6vshtbhktmzp2if4g6kxzttxmzkdxmtipcm"
457+ ) ;
458+
459+ // 2nd pass, no caching so block reads roughly doubled.
460+ #[ rustfmt:: skip]
461+ assert_eq ! ( * db. stats. borrow( ) , BSStats { r: 2861 , w: 1431 , br: 177158 , bw: 88649 } ) ;
462+ }
463+
393464#[ test]
394465fn for_each_ranged ( ) {
395466 let mem = MemoryBlockstore :: default ( ) ;
0 commit comments