@@ -14,6 +14,7 @@ use fst::MapBuilder;
14
14
use parking_lot:: { Mutex , RwLock } ;
15
15
use roaring:: RoaringBitmap ;
16
16
use tokio_stream:: Stream ;
17
+ use zerocopy:: little_endian:: U32 ;
17
18
use zerocopy:: { AsBytes , FromZeroes } ;
18
19
19
20
use crate :: io:: buf:: { IoBufMut , ZeroCopyBoxIoBuf , ZeroCopyBuf } ;
@@ -25,7 +26,7 @@ use crate::transaction::{Transaction, TxGuard};
25
26
use crate :: LIBSQL_MAGIC ;
26
27
27
28
use super :: list:: SegmentList ;
28
- use super :: { Frame , FrameHeader , SegmentHeader } ;
29
+ use super :: { CheckedFrame , Frame , FrameHeader , SegmentHeader } ;
29
30
30
31
use crate :: error:: Result ;
31
32
@@ -284,8 +285,8 @@ impl<F> CurrentSegment<F> {
284
285
285
286
if let Some ( size_after) = size_after {
286
287
if tx. not_empty ( ) {
287
- if let Some ( _offset ) = tx. recompute_checksum {
288
- todo ! ( "recompute checksum" ) ;
288
+ if let Some ( offset ) = tx. recompute_checksum {
289
+ self . recompute_checksum ( offset , tx . next_offset - 1 ) ? ;
289
290
}
290
291
let last_frame_no = tx. next_frame_no - 1 ;
291
292
let mut header = { * self . header . lock ( ) } ;
@@ -499,6 +500,31 @@ impl<F> CurrentSegment<F> {
499
500
500
501
( stream, replicated_until, db_size)
501
502
}
503
+
504
+ fn recompute_checksum ( & self , start_offset : u32 , until_offset : u32 ) -> Result < ( ) >
505
+ where F : FileExt
506
+ {
507
+ let mut current_checksum = if start_offset == 0 {
508
+ self . header . lock ( ) . salt . get ( )
509
+ } else {
510
+ // we get the checksum from the frame just before the the start offset
511
+ let frame_offset = checked_frame_offset ( start_offset - 1 ) ;
512
+ let mut out = U32 :: new ( 0 ) ;
513
+ self . file . read_exact_at ( out. as_bytes_mut ( ) , frame_offset) ?;
514
+ out. get ( )
515
+ } ;
516
+
517
+ let mut checked_frame: Box < CheckedFrame > = CheckedFrame :: new_box_zeroed ( ) ;
518
+ for offset in start_offset..=until_offset {
519
+ let frame_offset = checked_frame_offset ( offset) ;
520
+ self . file . read_exact_at ( checked_frame. as_bytes_mut ( ) , frame_offset) ?;
521
+ current_checksum = checked_frame. frame . checksum ( current_checksum) ;
522
+ self . file . write_all_at ( & current_checksum. to_le_bytes ( ) , frame_offset) ?;
523
+
524
+ }
525
+
526
+ Ok ( ( ) )
527
+ }
502
528
}
503
529
504
530
fn frame_list_to_option ( frames : Vec < Box < Frame > > ) -> Vec < Option < Box < Frame > > > {
@@ -956,12 +982,9 @@ mod test {
956
982
}
957
983
}
958
984
959
- dbg ! ( ) ;
960
985
{
961
986
let env = TestEnv :: new_io_and_tmp ( SyncFailBufferIo :: default ( ) , tmp. clone ( ) ) ;
962
- dbg ! ( ) ;
963
987
let conn = env. open_conn ( "test" ) ;
964
- dbg ! ( ) ;
965
988
conn. query_row ( "select count(*) from test" , ( ) , |row| {
966
989
dbg ! ( row) ;
967
990
Ok ( ( ) )
0 commit comments