@@ -285,23 +285,42 @@ impl<F> CurrentSegment<F> {
285285
286286 if let Some ( size_after) = size_after {
287287 if tx. not_empty ( ) {
288- if let Some ( offset) = tx. recompute_checksum {
289- self . recompute_checksum ( offset, tx. next_offset - 1 ) ?;
288+ let new_checksum = if let Some ( offset) = tx. recompute_checksum {
289+ self . recompute_checksum ( offset, tx. next_offset - 1 ) ?
290+ } else {
291+ tx. current_checksum ( )
292+ } ;
293+
294+ #[ cfg( debug_assertions) ]
295+ {
296+ // ensure that file checksum for that transaction is valid
297+ let from = {
298+ let header = self . header . lock ( ) ;
299+ if header. last_commited_frame_no ( ) == 0 {
300+ 0
301+ } else {
302+ ( header. last_commited_frame_no ( ) - header. start_frame_no . get ( ) ) as u32
303+ }
304+ } ;
305+
306+ self . assert_valid_checksum ( from, tx. next_offset - 1 ) ?;
290307 }
308+
291309 let last_frame_no = tx. next_frame_no - 1 ;
292310 let mut header = { * self . header . lock ( ) } ;
293311 header. last_commited_frame_no = last_frame_no. into ( ) ;
294312 header. size_after = size_after. into ( ) ;
295313 header. recompute_checksum ( ) ;
296314
297315 self . file . write_all_at ( header. as_bytes ( ) , 0 ) ?;
316+ // todo: sync if sync mode is EXTRA
298317 // self.file.sync_data().unwrap();
299318 tx. merge_savepoints ( & self . index ) ;
300319 // set the header last, so that a transaction does not witness a write before
301320 // it's actually committed.
302321 * self . header . lock ( ) = header;
303322 self . current_checksum
304- . store ( tx . current_checksum ( ) , Ordering :: Relaxed ) ;
323+ . store ( new_checksum , Ordering :: Relaxed ) ;
305324
306325 tx. is_commited = true ;
307326
@@ -343,7 +362,7 @@ impl<F> CurrentSegment<F> {
343362 F : FileExt ,
344363 B : IoBufMut + Send + ' static ,
345364 {
346- let byte_offset = dbg ! ( frame_offset( dbg! ( offset) ) ) ;
365+ let byte_offset = frame_offset ( offset) ;
347366 self . file . read_exact_at_async ( buf, byte_offset) . await
348367 }
349368
@@ -501,14 +520,14 @@ impl<F> CurrentSegment<F> {
501520 ( stream, replicated_until, db_size)
502521 }
503522
504- fn recompute_checksum ( & self , start_offset : u32 , until_offset : u32 ) -> Result < ( ) >
523+ fn recompute_checksum ( & self , start_offset : u32 , until_offset : u32 ) -> Result < u32 >
505524 where F : FileExt
506525 {
507526 let mut current_checksum = if start_offset == 0 {
508527 self . header . lock ( ) . salt . get ( )
509528 } else {
510529 // we get the checksum from the frame just before the the start offset
511- let frame_offset = checked_frame_offset ( start_offset - 1 ) ;
530+ let frame_offset = checked_frame_offset ( ( start_offset - 1 ) ) ;
512531 let mut out = U32 :: new ( 0 ) ;
513532 self . file . read_exact_at ( out. as_bytes_mut ( ) , frame_offset) ?;
514533 out. get ( )
@@ -522,6 +541,31 @@ impl<F> CurrentSegment<F> {
522541 self . file . write_all_at ( & current_checksum. to_le_bytes ( ) , frame_offset) ?;
523542 }
524543
544+ Ok ( current_checksum)
545+ }
546+
547+ /// test fuction to ensure checksum integrity
548+ #[ cfg( debug_assertions) ]
549+ #[ track_caller]
550+ fn assert_valid_checksum ( & self , from : u32 , until : u32 ) -> Result < ( ) >
551+ where F : FileExt
552+ {
553+ let mut frame: Box < CheckedFrame > = CheckedFrame :: new_box_zeroed ( ) ;
554+ let mut current_checksum = if from != 0 {
555+ let offset = checked_frame_offset ( from - 1 ) ;
556+ self . file . read_exact_at ( frame. as_bytes_mut ( ) , offset) ?;
557+ frame. checksum . get ( )
558+ } else {
559+ self . header . lock ( ) . salt . get ( )
560+ } ;
561+
562+ for i in from..=until {
563+ let offset = checked_frame_offset ( i) ;
564+ self . file . read_exact_at ( frame. as_bytes_mut ( ) , offset) ?;
565+ current_checksum = frame. frame . checksum ( current_checksum) ;
566+ assert_eq ! ( current_checksum, frame. checksum. get( ) , "invalid checksum at offset {i}" ) ;
567+ }
568+
525569 Ok ( ( ) )
526570 }
527571}
@@ -915,7 +959,7 @@ mod test {
915959 let mut inner = self . inner . lock ( ) ;
916960 if !inner. contains_key ( path) {
917961 let data = if path. exists ( ) {
918- std:: fs:: read ( path) . map_err ( |e| dbg ! ( e ) ) ?
962+ std:: fs:: read ( path) ?
919963 } else {
920964 vec ! [ ]
921965 } ;
0 commit comments