@@ -40,12 +40,18 @@ where
40
40
/// Unlike the standard flush() operation which only writes blocks connected
41
41
/// to the final state tree, this writes every block created during execution.
42
42
pub fn flush_all ( & self ) -> Result < ( ) > {
43
- log:: info !(
43
+ log:: debug !(
44
44
"Flushing all ({}) cache blocks to blockstore" ,
45
45
self . write. borrow( ) . len( )
46
46
) ;
47
- self . base
48
- . put_many_keyed ( self . write . borrow ( ) . iter ( ) . map ( |( k, v) | ( * k, v. as_slice ( ) ) ) )
47
+
48
+ self . base . put_many_keyed ( self . write . borrow_mut ( ) . drain ( ) ) ?;
49
+
50
+ Ok ( ( ) )
51
+ }
52
+
53
+ pub fn buffer_len ( & self ) -> usize {
54
+ self . write . borrow ( ) . len ( )
49
55
}
50
56
}
51
57
@@ -342,4 +348,99 @@ mod tests {
342
348
assert_eq ! ( buf_store. get( & sealed_comm_cid) . unwrap( ) , None ) ;
343
349
assert_eq ! ( mem. get_cbor:: <u8 >( & unconnected) . unwrap( ) , None ) ;
344
350
}
351
+
352
+ #[ test]
353
+ fn test_flush_vs_flush_all ( ) {
354
+ fn setup (
355
+ mem : & MemoryBlockstore ,
356
+ buf_store : & BufferedBlockstore < & MemoryBlockstore > ,
357
+ ) -> ( Cid , Cid , Cid , Cid ) {
358
+ // A DAG of 2 blocks
359
+ let value1 = 42u8 ;
360
+ let value2 = 84u8 ;
361
+ let value1_cid = buf_store. put_cbor ( & value1, Code :: Blake2b256 ) . unwrap ( ) ;
362
+ let root_cid = buf_store
363
+ . put_cbor ( & ( value1_cid, value2) , Code :: Blake2b256 )
364
+ . unwrap ( ) ;
365
+
366
+ // Two additional disconnected blocks
367
+ let disconnected1 = 100u8 ;
368
+ let disconnected2 = 200u8 ;
369
+ let disconnected1_cid = buf_store
370
+ . put_cbor ( & disconnected1, Code :: Blake2b256 )
371
+ . unwrap ( ) ;
372
+ let disconnected2_cid = buf_store
373
+ . put_cbor ( & disconnected2, Code :: Blake2b256 )
374
+ . unwrap ( ) ;
375
+
376
+ // Verify initial state - everything in buffer, nothing in backing store
377
+ assert_eq ! ( buf_store. get_cbor:: <u8 >( & value1_cid) . unwrap( ) , Some ( value1) ) ;
378
+ assert_eq ! (
379
+ buf_store. get_cbor:: <( Cid , u8 ) >( & root_cid) . unwrap( ) ,
380
+ Some ( ( value1_cid, value2) )
381
+ ) ;
382
+ assert_eq ! (
383
+ buf_store. get_cbor:: <u8 >( & disconnected1_cid) . unwrap( ) ,
384
+ Some ( disconnected1)
385
+ ) ;
386
+ assert_eq ! (
387
+ buf_store. get_cbor:: <u8 >( & disconnected2_cid) . unwrap( ) ,
388
+ Some ( disconnected2)
389
+ ) ;
390
+ assert_eq ! ( mem. get_cbor:: <u8 >( & value1_cid) . unwrap( ) , None ) ;
391
+ assert_eq ! ( mem. get_cbor:: <( Cid , u8 ) >( & root_cid) . unwrap( ) , None ) ;
392
+ assert_eq ! ( mem. get_cbor:: <u8 >( & disconnected1_cid) . unwrap( ) , None ) ;
393
+ assert_eq ! ( mem. get_cbor:: <u8 >( & disconnected2_cid) . unwrap( ) , None ) ;
394
+
395
+ ( root_cid, value1_cid, disconnected1_cid, disconnected2_cid)
396
+ }
397
+
398
+ // Case 1: flush operation only writes connected blocks
399
+ {
400
+ let mem = MemoryBlockstore :: default ( ) ;
401
+ let buf_store = BufferedBlockstore :: new ( & mem) ;
402
+ let ( root_cid, value1_cid, disconnected1_cid, disconnected2_cid) =
403
+ setup ( & mem, & buf_store) ;
404
+
405
+ // flush() should write only he DAG
406
+ buf_store. flush ( & root_cid) . unwrap ( ) ;
407
+
408
+ // DAG should be in backing store
409
+ assert_eq ! ( mem. get_cbor:: <u8 >( & value1_cid) . unwrap( ) , Some ( 42u8 ) ) ;
410
+ assert_eq ! (
411
+ mem. get_cbor:: <( Cid , u8 ) >( & root_cid) . unwrap( ) ,
412
+ Some ( ( value1_cid, 84u8 ) )
413
+ ) ;
414
+
415
+ // Disconnected blocks should NOT be in backing store
416
+ assert_eq ! ( mem. get_cbor:: <u8 >( & disconnected1_cid) . unwrap( ) , None ) ;
417
+ assert_eq ! ( mem. get_cbor:: <u8 >( & disconnected2_cid) . unwrap( ) , None ) ;
418
+
419
+ // Verify that the buffer still contains the disconnected blocks
420
+ assert_eq ! ( buf_store. buffer_len( ) , 2 ) ;
421
+ }
422
+
423
+ // Case 2: flush_all operation writes all blocks
424
+ {
425
+ let mem = MemoryBlockstore :: default ( ) ;
426
+ let buf_store = BufferedBlockstore :: new ( & mem) ;
427
+ let ( root_cid, value1_cid, disconnected1_cid, disconnected2_cid) =
428
+ setup ( & mem, & buf_store) ;
429
+
430
+ // flush_all() should write all blocks
431
+ buf_store. flush_all ( ) . unwrap ( ) ;
432
+
433
+ // All blocks should be in backing store
434
+ assert_eq ! ( mem. get_cbor:: <u8 >( & value1_cid) . unwrap( ) , Some ( 42u8 ) ) ;
435
+ assert_eq ! (
436
+ mem. get_cbor:: <( Cid , u8 ) >( & root_cid) . unwrap( ) ,
437
+ Some ( ( value1_cid, 84u8 ) )
438
+ ) ;
439
+ assert_eq ! ( mem. get_cbor:: <u8 >( & disconnected1_cid) . unwrap( ) , Some ( 100u8 ) ) ;
440
+ assert_eq ! ( mem. get_cbor:: <u8 >( & disconnected2_cid) . unwrap( ) , Some ( 200u8 ) ) ;
441
+
442
+ // Verify that all blocks are removed from the buffer
443
+ assert_eq ! ( buf_store. buffer_len( ) , 0 ) ;
444
+ }
445
+ }
345
446
}
0 commit comments