@@ -233,10 +233,11 @@ impl<F> CurrentSegment<F> {
233233 tracing:: trace!( page_no, "recycling frame" ) ;
234234 self . file . write_all_at ( page, page_offset ( * offset) ) ?;
235235 // we overwrote a frame, record that for later rewrite
236- tx. recompute_checksum = Some ( tx
237- . recompute_checksum
238- . map ( |old| old. min ( * offset) )
239- . unwrap_or ( * offset) ) ;
236+ tx. recompute_checksum = Some (
237+ tx. recompute_checksum
238+ . map ( |old| old. min ( * offset) )
239+ . unwrap_or ( * offset) ,
240+ ) ;
240241 continue ;
241242 }
242243
@@ -272,7 +273,8 @@ impl<F> CurrentSegment<F> {
272273 self . header. lock( ) . start_frame_no. get( ) + offset as u64 ,
273274 frame_no
274275 ) ;
275- self . file . write_at_vectored ( slices, checked_frame_offset ( offset) ) ?;
276+ self . file
277+ . write_at_vectored ( slices, checked_frame_offset ( offset) ) ?;
276278 assert ! (
277279 current_savepoint. index. insert( page_no, offset) . is_none( ) ,
278280 "existing frames should be recycled"
@@ -290,7 +292,7 @@ impl<F> CurrentSegment<F> {
290292 } else {
291293 tx. current_checksum ( )
292294 } ;
293-
295+
294296 #[ cfg( debug_assertions) ]
295297 {
296298 // ensure that file checksum for that transaction is valid
@@ -319,8 +321,7 @@ impl<F> CurrentSegment<F> {
319321 // set the header last, so that a transaction does not witness a write before
320322 // it's actually committed.
321323 * self . header . lock ( ) = header;
322- self . current_checksum
323- . store ( new_checksum, Ordering :: Relaxed ) ;
324+ self . current_checksum . store ( new_checksum, Ordering :: Relaxed ) ;
324325
325326 tx. is_commited = true ;
326327
@@ -521,13 +522,14 @@ impl<F> CurrentSegment<F> {
521522 }
522523
523524 fn recompute_checksum ( & self , start_offset : u32 , until_offset : u32 ) -> Result < u32 >
524- where F : FileExt
525+ where
526+ F : FileExt ,
525527 {
526528 let mut current_checksum = if start_offset == 0 {
527529 self . header . lock ( ) . salt . get ( )
528530 } else {
529531 // we get the checksum from the frame just before the the start offset
530- let frame_offset = checked_frame_offset ( ( start_offset - 1 ) ) ;
532+ let frame_offset = checked_frame_offset ( start_offset - 1 ) ;
531533 let mut out = U32 :: new ( 0 ) ;
532534 self . file . read_exact_at ( out. as_bytes_mut ( ) , frame_offset) ?;
533535 out. get ( )
@@ -536,9 +538,11 @@ impl<F> CurrentSegment<F> {
536538 let mut checked_frame: Box < CheckedFrame > = CheckedFrame :: new_box_zeroed ( ) ;
537539 for offset in start_offset..=until_offset {
538540 let frame_offset = checked_frame_offset ( offset) ;
539- self . file . read_exact_at ( checked_frame. as_bytes_mut ( ) , frame_offset) ?;
541+ self . file
542+ . read_exact_at ( checked_frame. as_bytes_mut ( ) , frame_offset) ?;
540543 current_checksum = checked_frame. frame . checksum ( current_checksum) ;
541- self . file . write_all_at ( & current_checksum. to_le_bytes ( ) , frame_offset) ?;
544+ self . file
545+ . write_all_at ( & current_checksum. to_le_bytes ( ) , frame_offset) ?;
542546 }
543547
544548 Ok ( current_checksum)
@@ -548,7 +552,8 @@ impl<F> CurrentSegment<F> {
548552 #[ cfg( debug_assertions) ]
549553 #[ track_caller]
550554 fn assert_valid_checksum ( & self , from : u32 , until : u32 ) -> Result < ( ) >
551- where F : FileExt
555+ where
556+ F : FileExt ,
552557 {
553558 let mut frame: Box < CheckedFrame > = CheckedFrame :: new_box_zeroed ( ) ;
554559 let mut current_checksum = if from != 0 {
@@ -563,7 +568,11 @@ impl<F> CurrentSegment<F> {
563568 let offset = checked_frame_offset ( i) ;
564569 self . file . read_exact_at ( frame. as_bytes_mut ( ) , offset) ?;
565570 current_checksum = frame. frame . checksum ( current_checksum) ;
566- assert_eq ! ( current_checksum, frame. checksum. get( ) , "invalid checksum at offset {i}" ) ;
571+ assert_eq ! (
572+ current_checksum,
573+ frame. checksum. get( ) ,
574+ "invalid checksum at offset {i}"
575+ ) ;
567576 }
568577
569578 Ok ( ( ) )
@@ -902,8 +911,9 @@ mod test {
902911 // simulate a flush that only flushes half the pages and then fail
903912 let inner = self . inner ( ) ;
904913 let inner = inner. lock ( ) ;
905- let npages = inner. len ( ) / 4096 ;
906- std:: fs:: write ( & self . path , & inner[ ..4096 * ( npages / 2 ) ] ) ?;
914+ // just keep 5 pages from the log. The log will be incomplete and frames will be
915+ // broken.
916+ std:: fs:: write ( & self . path , & inner[ ..4096 * 5 ] ) ?;
907917 Err ( io:: Error :: new ( io:: ErrorKind :: BrokenPipe , "" ) )
908918 }
909919
@@ -1007,12 +1017,9 @@ mod test {
10071017 let shared = env. shared ( "test" ) ;
10081018
10091019 conn. execute ( "create table test (x)" , ( ) ) . unwrap ( ) ;
1010- conn. execute ( "insert into test values (1234)" , ( ) ) . unwrap ( ) ;
1011- conn. execute ( "insert into test values (1234)" , ( ) ) . unwrap ( ) ;
1012- conn. execute ( "insert into test values (1234)" , ( ) ) . unwrap ( ) ;
1013- conn. execute ( "insert into test values (1234)" , ( ) ) . unwrap ( ) ;
1014- conn. execute ( "insert into test values (1234)" , ( ) ) . unwrap ( ) ;
1015- conn. execute ( "insert into test values (1234)" , ( ) ) . unwrap ( ) ;
1020+ for _ in 0 ..6 {
1021+ conn. execute ( "insert into test values (1234)" , ( ) ) . unwrap ( ) ;
1022+ }
10161023
10171024 // trigger a flush, that will fail. When we reopen the db, the log should need recovery
10181025 // this simulates a crash before flush
@@ -1028,8 +1035,9 @@ mod test {
10281035 {
10291036 let env = TestEnv :: new_io_and_tmp ( SyncFailBufferIo :: default ( ) , tmp. clone ( ) ) ;
10301037 let conn = env. open_conn ( "test" ) ;
1038+ // the db was recovered: we lost some rows, but it still works
10311039 conn. query_row ( "select count(*) from test" , ( ) , |row| {
1032- dbg ! ( row) ;
1040+ assert_eq ! ( row. get :: <_ , u32 > ( 0 ) . unwrap ( ) , 2 ) ;
10331041 Ok ( ( ) )
10341042 } )
10351043 . unwrap ( ) ;
0 commit comments