@@ -24,7 +24,7 @@ use crate::io::file::FileExt;
2424use crate :: io:: Inspect ;
2525use crate :: segment:: { checked_frame_offset, SegmentFlags } ;
2626use crate :: segment:: { frame_offset, page_offset, sealed:: SealedSegment } ;
27- use crate :: transaction:: { Transaction , TxGuardOwned , TxGuardShared } ;
27+ use crate :: transaction:: { ReadTransaction , Transaction , TxGuardOwned , TxGuardShared } ;
2828use crate :: { LIBSQL_MAGIC , LIBSQL_PAGE_SIZE , LIBSQL_WAL_VERSION } ;
2929
3030use super :: list:: SegmentList ;
@@ -507,24 +507,25 @@ impl<F> CurrentSegment<F> {
507507 & ' a self ,
508508 start_frame_no : u64 ,
509509 seen : & ' a mut RoaringBitmap ,
510- ) -> ( impl Stream < Item = Result < Box < Frame > > > + ' a , u64 , u32 )
510+ // not actually used, but ensures that a read lock is held while this method id called
511+ tx : & ' a ReadTransaction < F > ,
512+ ) -> ( impl Stream < Item = Result < Box < Frame > > > + ' a , u64 )
511513 where
512514 F : FileExt ,
513515 {
514- let ( seg_start_frame_no, last_committed, db_size) =
515- self . with_header ( |h| ( h. start_frame_no . get ( ) , h. last_committed ( ) , h. size_after ( ) ) ) ;
516+ let seg_start_frame_no = tx. current . with_header ( |h| h. start_frame_no . get ( ) ) ;
516517 let replicated_until = seg_start_frame_no
517518 // if current is empty, start_frame_no doesn't exist
518- . min ( last_committed )
519+ . min ( tx . max_frame_no )
519520 . max ( start_frame_no) ;
520521
521522 // TODO: optim, we could read less frames if we had a mapping from frame_no to page_no in
522523 // the index
523524 let stream = async_stream:: try_stream! {
524525 if !self . is_empty( ) {
525- let mut frame_offset = ( last_committed - seg_start_frame_no) as u32 ;
526+ let mut frame_offset = ( tx . max_frame_no - seg_start_frame_no) as u32 ;
526527 loop {
527- let buf = ZeroCopyBoxIoBuf :: new ( Frame :: new_box_zeroed( ) ) ;
528+ let buf = ZeroCopyBoxIoBuf :: new_uninit ( Frame :: new_box_zeroed( ) ) ;
528529 let ( buf, res) = self . read_frame_offset_async( frame_offset, buf) . await ;
529530 res?;
530531
@@ -551,7 +552,7 @@ impl<F> CurrentSegment<F> {
551552 }
552553 } ;
553554
554- ( stream, replicated_until, db_size )
555+ ( stream, replicated_until)
555556 }
556557
557558 fn recompute_checksum ( & self , start_offset : u32 , until_offset : u32 ) -> Result < u32 >
@@ -714,18 +715,20 @@ mod test {
714715 . unwrap ( ) ;
715716 }
716717
717- let mut seen = RoaringBitmap :: new ( ) ;
718- let current = shared. current . load ( ) ;
719- let ( stream, replicated_until, size_after) = current. frame_stream_from ( 1 , & mut seen) ;
720- tokio:: pin!( stream) ;
721- assert_eq ! ( replicated_until, 1 ) ;
722- assert_eq ! ( size_after, 6 ) ;
723-
724718 let mut tmp = tempfile ( ) . unwrap ( ) ;
725- while let Some ( frame) = stream. next ( ) . await {
726- let frame = frame. unwrap ( ) ;
727- let offset = ( frame. header ( ) . page_no ( ) - 1 ) * 4096 ;
728- tmp. write_all_at ( frame. data ( ) , offset as _ ) . unwrap ( ) ;
719+ {
720+ let tx = shared. begin_read ( u64:: MAX ) ;
721+ let mut seen = RoaringBitmap :: new ( ) ;
722+ let ( stream, replicated_until) = tx. current . frame_stream_from ( 1 , & mut seen, & tx) ;
723+ tokio:: pin!( stream) ;
724+ assert_eq ! ( replicated_until, 1 ) ;
725+ assert_eq ! ( tx. db_size, 6 ) ;
726+
727+ while let Some ( frame) = stream. next ( ) . await {
728+ let frame = frame. unwrap ( ) ;
729+ let offset = ( frame. header ( ) . page_no ( ) - 1 ) * 4096 ;
730+ tmp. write_all_at ( frame. data ( ) , offset as _ ) . unwrap ( ) ;
731+ }
729732 }
730733
731734 seal_current_segment ( & shared) ;
@@ -768,11 +771,11 @@ mod test {
768771
769772 let mut seen = RoaringBitmap :: new ( ) ;
770773 {
771- let current = shared. current . load ( ) ;
772- let ( stream, replicated_until, size_after ) = current. frame_stream_from ( 1 , & mut seen) ;
774+ let tx = shared. begin_read ( u64 :: MAX ) ;
775+ let ( stream, replicated_until) = tx . current . frame_stream_from ( 1 , & mut seen, & tx ) ;
773776 tokio:: pin!( stream) ;
774777 assert_eq ! ( replicated_until, 60 ) ;
775- assert_eq ! ( size_after , 9 ) ;
778+ assert_eq ! ( tx . db_size , 9 ) ;
776779 assert_eq ! ( stream. fold( 0 , |count, _| count + 1 ) . await , 6 ) ;
777780 }
778781 assert_debug_snapshot ! ( seen) ;
@@ -787,12 +790,12 @@ mod test {
787790 conn. execute ( "create table test (x)" , ( ) ) . unwrap ( ) ;
788791
789792 let mut seen = RoaringBitmap :: new ( ) ;
790- let current = shared. current . load ( ) ;
791- let ( stream, replicated_until, size_after ) = current. frame_stream_from ( 100 , & mut seen) ;
793+ let tx = shared. begin_read ( u64 :: MAX ) ;
794+ let ( stream, replicated_until) = tx . current . frame_stream_from ( 100 , & mut seen, & tx ) ;
792795 tokio:: pin!( stream) ;
793796 assert_eq ! ( replicated_until, 100 ) ;
794797 assert_eq ! ( stream. fold( 0 , |count, _| count + 1 ) . await , 0 ) ;
795- assert_eq ! ( size_after , 2 ) ;
798+ assert_eq ! ( tx . db_size , 2 ) ;
796799 }
797800
798801 #[ tokio:: test]
@@ -805,11 +808,11 @@ mod test {
805808 seal_current_segment ( & shared) ;
806809
807810 let mut seen = RoaringBitmap :: new ( ) ;
808- let current = shared. current . load ( ) ;
809- let ( stream, replicated_until, size_after ) = current. frame_stream_from ( 1 , & mut seen) ;
811+ let tx = shared. begin_read ( u64 :: MAX ) ;
812+ let ( stream, replicated_until) = tx . current . frame_stream_from ( 1 , & mut seen, & tx ) ;
810813 tokio:: pin!( stream) ;
811814 assert_eq ! ( replicated_until, 2 ) ;
812- assert_eq ! ( size_after , 2 ) ;
815+ assert_eq ! ( tx . db_size , 2 ) ;
813816 assert_eq ! ( stream. fold( 0 , |count, _| count + 1 ) . await , 0 ) ;
814817 }
815818
@@ -1014,8 +1017,8 @@ mod test {
10141017 }
10151018 }
10161019
1017- fn db_payload ( db : & [ u8 ] ) -> & [ u8 ] {
1020+ fn db_payload ( db : & [ u8 ] ) -> u32 {
10181021 let size = ( db. len ( ) / 4096 ) * 4096 ;
1019- & db[ ..size]
1022+ crc32fast :: hash ( & db[ ..size] )
10201023 }
10211024}
0 commit comments