11use alloc:: boxed:: Box ;
2- use alloc:: collections:: BTreeMap ;
32use alloc:: ffi:: CString ;
43use alloc:: format;
5- use alloc:: string:: String ;
64use alloc:: vec:: Vec ;
75use core:: ffi:: { c_char, c_int} ;
86use core:: mem;
@@ -382,36 +380,45 @@ pub unsafe extern "C" fn crsql_merge_insert(
382380
383381fn get_local_cl (
384382 db : * mut sqlite:: sqlite3 ,
385- tbl_info : & TableInfo ,
383+ tbl_info : & mut TableInfo ,
386384 key : sqlite:: int64 ,
387385) -> Result < sqlite:: int64 , ResultCode > {
388- let local_cl_stmt_ref = tbl_info. get_local_cl_stmt ( db) ?;
389- let local_cl_stmt = local_cl_stmt_ref. as_ref ( ) . ok_or ( ResultCode :: ERROR ) ?;
390-
391- let rc = local_cl_stmt
392- . bind_int64 ( 1 , key)
393- . and_then ( |_| local_cl_stmt. bind_int64 ( 2 , key) ) ;
394- if let Err ( rc) = rc {
395- reset_cached_stmt ( local_cl_stmt. stmt ) ?;
396- return Err ( rc) ;
386+ if let Some ( cl) = tbl_info. get_cl ( key) {
387+ return Ok ( * cl) ;
397388 }
398389
399- let step_result = local_cl_stmt . step ( ) ;
400- match step_result {
401- Ok ( ResultCode :: ROW ) => {
402- let ret = local_cl_stmt . column_int64 ( 0 ) ;
403- reset_cached_stmt ( local_cl_stmt. stmt ) ? ;
404- Ok ( ret )
405- }
406- Ok ( ResultCode :: DONE ) => {
390+ let cl = {
391+ let local_cl_stmt_ref = tbl_info . get_local_cl_stmt ( db ) ? ;
392+ let local_cl_stmt = local_cl_stmt_ref . as_ref ( ) . ok_or ( ResultCode :: ERROR ) ? ;
393+
394+ let rc = local_cl_stmt
395+ . bind_int64 ( 1 , key )
396+ . and_then ( |_| local_cl_stmt . bind_int64 ( 2 , key ) ) ;
397+ if let Err ( rc ) = rc {
407398 reset_cached_stmt ( local_cl_stmt. stmt ) ?;
408- Ok ( 0 )
399+ return Err ( rc ) ;
409400 }
410- Ok ( rc) | Err ( rc) => {
411- reset_cached_stmt ( local_cl_stmt. stmt ) ?;
412- Err ( rc)
401+
402+ let step_result = local_cl_stmt. step ( ) ;
403+ match step_result {
404+ Ok ( ResultCode :: ROW ) => {
405+ let ret = local_cl_stmt. column_int64 ( 0 ) ;
406+ reset_cached_stmt ( local_cl_stmt. stmt ) ?;
407+ ret
408+ }
409+ Ok ( ResultCode :: DONE ) => {
410+ reset_cached_stmt ( local_cl_stmt. stmt ) ?;
411+ 0
412+ }
413+ Ok ( rc) | Err ( rc) => {
414+ reset_cached_stmt ( local_cl_stmt. stmt ) ?;
415+ return Err ( rc) ;
416+ }
413417 }
414- }
418+ } ;
419+
420+ tbl_info. set_cl ( key, cl) ;
421+ Ok ( cl)
415422}
416423
417424unsafe fn merge_insert (
@@ -465,14 +472,10 @@ unsafe fn merge_insert(
465472
466473 let insert_site_id = insert_site_id. blob ( ) ;
467474
468- let tbl_infos = mem:: ManuallyDrop :: new ( Box :: from_raw (
475+ let mut tbl_infos = mem:: ManuallyDrop :: new ( Box :: from_raw (
469476 ( * ( * tab) . pExtData ) . tableInfos as * mut Vec < TableInfo > ,
470477 ) ) ;
471478
472- let mut cl_cache = mem:: ManuallyDrop :: new ( Box :: from_raw (
473- ( * ( * tab) . pExtData ) . clCache as * mut BTreeMap < String , BTreeMap < i64 , i64 > > ,
474- ) ) ;
475-
476479 // TODO: will this work given `insert_tbl` is null termed?
477480 let tbl_info_index = tbl_infos. iter ( ) . position ( |x| x. tbl_name == insert_tbl) ;
478481
@@ -487,14 +490,14 @@ unsafe fn merge_insert(
487490 // TODO: technically safe since we checked `is_none` but this should be more idiomatic
488491 let tbl_info_index = tbl_info_index. unwrap ( ) ;
489492
490- let tbl_info = & tbl_infos[ tbl_info_index] ;
493+ let tbl_info = & mut tbl_infos[ tbl_info_index] ;
491494 let unpacked_pks = unpack_columns ( insert_pks. blob ( ) ) ?;
492495
493496 // Get or create key as the first thing we do.
494497 // We'll need the key for all later operations.
495498 let key = tbl_info. get_or_create_key ( db, & unpacked_pks) ?;
496499
497- let local_cl = get_pk_cl ( db, & mut cl_cache , & tbl_info, key) ?;
500+ let local_cl = get_local_cl ( db, tbl_info, key) ?;
498501
499502 // We can ignore all updates from older causal lengths.
500503 // They won't win at anything.
@@ -720,37 +723,9 @@ unsafe fn merge_insert(
720723
721724 // a bigger cl always wins
722725 if insert_cl > local_cl {
723- match cl_cache. get_mut ( & tbl_info. tbl_name ) {
724- Some ( x) => {
725- x. insert ( key, insert_cl) ;
726- }
727- None => {
728- let mut new_map = BTreeMap :: new ( ) ;
729- new_map. insert ( key, insert_cl) ;
730- cl_cache. insert ( tbl_info. tbl_name . clone ( ) , new_map) ;
731- }
732- }
726+ tbl_info. set_cl ( key, insert_cl) ;
733727 }
734728 }
735729
736730 res
737731}
738-
739- unsafe fn get_pk_cl (
740- db : * mut sqlite3 ,
741- cl_cache : & mut BTreeMap < String , BTreeMap < i64 , i64 > > ,
742- tbl_info : & TableInfo ,
743- key : sqlite:: int64 ,
744- ) -> Result < sqlite:: int64 , ResultCode > {
745- match cl_cache. get ( & tbl_info. tbl_name ) . and_then ( |x| x. get ( & key) ) {
746- Some ( cl) => Ok ( * cl) ,
747- None => {
748- let cl = get_local_cl ( db, tbl_info, key) ?;
749- cl_cache
750- . entry ( tbl_info. tbl_name . clone ( ) )
751- . or_default ( )
752- . insert ( key, cl) ;
753- Ok ( cl)
754- }
755- }
756- }
0 commit comments