Skip to content

Commit efc67a4

Browse files
committed
update next_db_version to return what will actually be the next db version after commit
This also allows us to stop clearing the db version cache and should give us quicker TPS.
1 parent 339b712 commit efc67a4

File tree

5 files changed

+61
-25
lines changed

5 files changed

+61
-25
lines changed

core/rs/core/src/c.rs

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ pub struct crsql_ExtData {
7575
pub pPragmaDataVersionStmt: *mut sqlite::stmt,
7676
pub pragmaDataVersion: ::core::ffi::c_int,
7777
pub dbVersion: sqlite::int64,
78+
pub pendingDbVersion: sqlite::int64,
7879
pub pragmaSchemaVersion: ::core::ffi::c_int,
7980
pub pragmaSchemaVersionForTableInfos: ::core::ffi::c_int,
8081
pub siteId: *mut ::core::ffi::c_uchar,
@@ -448,7 +449,7 @@ fn bindgen_test_layout_crsql_ExtData() {
448449
let ptr = UNINIT.as_ptr();
449450
assert_eq!(
450451
::std::mem::size_of::<crsql_ExtData>(),
451-
120usize,
452+
128usize,
452453
concat!("Size of: ", stringify!(crsql_ExtData))
453454
);
454455
assert_eq!(
@@ -497,8 +498,18 @@ fn bindgen_test_layout_crsql_ExtData() {
497498
)
498499
);
499500
assert_eq!(
500-
unsafe { ::std::ptr::addr_of!((*ptr).pragmaSchemaVersion) as usize - ptr as usize },
501+
unsafe { ::std::ptr::addr_of!((*ptr).pendingDbVersion) as usize - ptr as usize },
501502
32usize,
503+
concat!(
504+
"Offset of field: ",
505+
stringify!(crsql_ExtData),
506+
"::",
507+
stringify!(pendingDbVersion)
508+
)
509+
);
510+
assert_eq!(
511+
unsafe { ::std::ptr::addr_of!((*ptr).pragmaSchemaVersion) as usize - ptr as usize },
512+
40usize,
502513
concat!(
503514
"Offset of field: ",
504515
stringify!(crsql_ExtData),
@@ -510,7 +521,7 @@ fn bindgen_test_layout_crsql_ExtData() {
510521
unsafe {
511522
::std::ptr::addr_of!((*ptr).pragmaSchemaVersionForTableInfos) as usize - ptr as usize
512523
},
513-
36usize,
524+
44usize,
514525
concat!(
515526
"Offset of field: ",
516527
stringify!(crsql_ExtData),
@@ -520,7 +531,7 @@ fn bindgen_test_layout_crsql_ExtData() {
520531
);
521532
assert_eq!(
522533
unsafe { ::std::ptr::addr_of!((*ptr).siteId) as usize - ptr as usize },
523-
40usize,
534+
48usize,
524535
concat!(
525536
"Offset of field: ",
526537
stringify!(crsql_ExtData),
@@ -530,7 +541,7 @@ fn bindgen_test_layout_crsql_ExtData() {
530541
);
531542
assert_eq!(
532543
unsafe { ::std::ptr::addr_of!((*ptr).pDbVersionStmt) as usize - ptr as usize },
533-
48usize,
544+
56usize,
534545
concat!(
535546
"Offset of field: ",
536547
stringify!(crsql_ExtData),
@@ -540,7 +551,7 @@ fn bindgen_test_layout_crsql_ExtData() {
540551
);
541552
assert_eq!(
542553
unsafe { ::std::ptr::addr_of!((*ptr).zpTableInfos) as usize - ptr as usize },
543-
56usize,
554+
64usize,
544555
concat!(
545556
"Offset of field: ",
546557
stringify!(crsql_ExtData),
@@ -550,7 +561,7 @@ fn bindgen_test_layout_crsql_ExtData() {
550561
);
551562
assert_eq!(
552563
unsafe { ::std::ptr::addr_of!((*ptr).tableInfosLen) as usize - ptr as usize },
553-
64usize,
564+
72usize,
554565
concat!(
555566
"Offset of field: ",
556567
stringify!(crsql_ExtData),
@@ -560,7 +571,7 @@ fn bindgen_test_layout_crsql_ExtData() {
560571
);
561572
assert_eq!(
562573
unsafe { ::std::ptr::addr_of!((*ptr).rowsImpacted) as usize - ptr as usize },
563-
68usize,
574+
76usize,
564575
concat!(
565576
"Offset of field: ",
566577
stringify!(crsql_ExtData),
@@ -570,7 +581,7 @@ fn bindgen_test_layout_crsql_ExtData() {
570581
);
571582
assert_eq!(
572583
unsafe { ::std::ptr::addr_of!((*ptr).seq) as usize - ptr as usize },
573-
72usize,
584+
80usize,
574585
concat!(
575586
"Offset of field: ",
576587
stringify!(crsql_ExtData),
@@ -580,7 +591,7 @@ fn bindgen_test_layout_crsql_ExtData() {
580591
);
581592
assert_eq!(
582593
unsafe { ::std::ptr::addr_of!((*ptr).pSetSyncBitStmt) as usize - ptr as usize },
583-
80usize,
594+
88usize,
584595
concat!(
585596
"Offset of field: ",
586597
stringify!(crsql_ExtData),
@@ -590,7 +601,7 @@ fn bindgen_test_layout_crsql_ExtData() {
590601
);
591602
assert_eq!(
592603
unsafe { ::std::ptr::addr_of!((*ptr).pClearSyncBitStmt) as usize - ptr as usize },
593-
88usize,
604+
96usize,
594605
concat!(
595606
"Offset of field: ",
596607
stringify!(crsql_ExtData),
@@ -600,7 +611,7 @@ fn bindgen_test_layout_crsql_ExtData() {
600611
);
601612
assert_eq!(
602613
unsafe { ::std::ptr::addr_of!((*ptr).pSetSiteIdOrdinalStmt) as usize - ptr as usize },
603-
96usize,
614+
104usize,
604615
concat!(
605616
"Offset of field: ",
606617
stringify!(crsql_ExtData),
@@ -610,7 +621,7 @@ fn bindgen_test_layout_crsql_ExtData() {
610621
);
611622
assert_eq!(
612623
unsafe { ::std::ptr::addr_of!((*ptr).pSelectSiteIdOrdinalStmt) as usize - ptr as usize },
613-
104usize,
624+
112usize,
614625
concat!(
615626
"Offset of field: ",
616627
stringify!(crsql_ExtData),
@@ -620,7 +631,7 @@ fn bindgen_test_layout_crsql_ExtData() {
620631
);
621632
assert_eq!(
622633
unsafe { ::std::ptr::addr_of!((*ptr).pStmtCache) as usize - ptr as usize },
623-
112usize,
634+
120usize,
624635
concat!(
625636
"Offset of field: ",
626637
stringify!(crsql_ExtData),

core/rs/core/src/changes_vtab_write.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ fn set_winner_clock(
237237
{pk_bind_list},
238238
?,
239239
?,
240-
MAX(crsql_next_db_version(), ?),
240+
crsql_next_db_version(?),
241241
?,
242242
?
243243
) RETURNING _rowid_",
@@ -373,7 +373,7 @@ fn zero_clocks_on_resurrect(
373373
let stmt_key = get_cache_key(CachedStmtType::ZeroClocksOnResurrect, table_name, None)?;
374374
let zero_stmt = get_cached_stmt_rt_wt(db, ext_data, stmt_key, || {
375375
Ok(format!(
376-
"UPDATE \"{table_name}__crsql_clock\" SET __crsql_col_version = 0, __crsql_db_version = MAX(crsql_next_db_version(), ?) WHERE {pk_where_list} AND __crsql_col_name IS NOT '{sentinel}'",
376+
"UPDATE \"{table_name}__crsql_clock\" SET __crsql_col_version = 0, __crsql_db_version = crsql_next_db_version(?) WHERE {pk_where_list} AND __crsql_col_name IS NOT '{sentinel}'",
377377
table_name = crate::util::escape_ident(table_name),
378378
pk_where_list = pk_where_list_from_tbl_info(tbl_info, None)?,
379379
sentinel = crate::c::INSERT_SENTINEL

core/src/crsqlite.c

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,33 @@ static void nextDbVersionFunc(sqlite3_context *context, int argc,
7272
char *errmsg = 0;
7373
crsql_ExtData *pExtData = (crsql_ExtData *)sqlite3_user_data(context);
7474
sqlite3 *db = sqlite3_context_db_handle(context);
75+
// "getDbVersion" is really just filling the cached db version value if
76+
// invalid
7577
int rc = crsql_getDbVersion(db, pExtData, &errmsg);
7678
if (rc != SQLITE_OK) {
7779
sqlite3_result_error(context, errmsg, -1);
7880
sqlite3_free(errmsg);
7981
return;
8082
}
8183

82-
sqlite3_result_int64(context, pExtData->dbVersion + 1);
84+
sqlite3_int64 providedVersion = 0;
85+
if (argc == 1) {
86+
providedVersion = sqlite3_value_int64(argv[0]);
87+
}
88+
89+
// now return max of:
90+
// dbVersion + 1, pendingDbVersion, arg (if there is one)
91+
// and set pendingDbVersion to that max
92+
sqlite3_int64 ret = pExtData->dbVersion + 1;
93+
if (ret < pExtData->pendingDbVersion) {
94+
ret = pExtData->pendingDbVersion;
95+
}
96+
if (ret < providedVersion) {
97+
ret = providedVersion;
98+
}
99+
pExtData->pendingDbVersion = ret;
100+
101+
sqlite3_result_int64(context, ret);
83102
}
84103

85104
static void incrementAndGetSeqFunc(sqlite3_context *context, int argc,
@@ -320,15 +339,16 @@ static void crsqlRowsImpacted(sqlite3_context *context, int argc,
320339
static int commitHook(void *pUserData) {
321340
crsql_ExtData *pExtData = (crsql_ExtData *)pUserData;
322341

323-
pExtData->dbVersion = -1;
342+
pExtData->pendingDbVersion = -1;
324343
pExtData->seq = 0;
325344
return SQLITE_OK;
326345
}
327346

328347
static void rollbackHook(void *pUserData) {
329348
crsql_ExtData *pExtData = (crsql_ExtData *)pUserData;
330349

331-
pExtData->dbVersion = -1;
350+
pExtData->pendingDbVersion = -1;
351+
pExtData->seq = 0;
332352
}
333353

334354
int sqlite3_crsqlrustbundle_init(sqlite3 *db, char **pzErrMsg,
@@ -400,7 +420,7 @@ __declspec(dllexport)
400420
dbVersionFunc, 0, 0, freeConnectionExtData);
401421
}
402422
if (rc == SQLITE_OK) {
403-
rc = sqlite3_create_function(db, "crsql_next_db_version", 0,
423+
rc = sqlite3_create_function(db, "crsql_next_db_version", -1,
404424
// dbversion can change on each invocation.
405425
SQLITE_UTF8 | SQLITE_INNOCUOUS, pExtData,
406426
nextDbVersionFunc, 0, 0);

core/src/ext-data.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ crsql_ExtData *crsql_newExtData(sqlite3 *db, unsigned char *siteIdBuffer) {
3636
SQLITE_PREPARE_PERSISTENT, &(pExtData->pSelectSiteIdOrdinalStmt), 0);
3737

3838
pExtData->dbVersion = -1;
39+
pExtData->pendingDbVersion = -1;
3940
pExtData->seq = 0;
4041
pExtData->pragmaSchemaVersion = -1;
4142
pExtData->pragmaDataVersion = -1;
@@ -254,11 +255,12 @@ int crsql_fetchDbVersionFromStorage(sqlite3 *db, crsql_ExtData *pExtData,
254255
int crsql_getDbVersion(sqlite3 *db, crsql_ExtData *pExtData, char **errmsg) {
255256
int rc = SQLITE_OK;
256257

257-
// version is cached. We clear the cached version
258-
// at the end of each transaction so it is safe to return this
259-
// without checking the schema version.
260-
// It is an error to use crsqlite in such a way that you modify
261-
// a schema and fetch changes in the same transaction.
258+
// Version is cached. We update the cached version at the end of every
259+
// transaction to match what is written to disk. The cache is only invalid if
260+
// another connection also made writes. We detect this via `pragmaDataVersion`
261+
// and force a re-fetch of the db version when `pragmaDataVersion` changes. It
262+
// is an error to use crsqlite in such a way that you modify a schema and
263+
// fetch changes in the same transaction.
262264
rc = crsql_fetchPragmaDataVersion(db, pExtData);
263265
if (rc == -1) {
264266
*errmsg = sqlite3_mprintf("failed to fetch PRAGMA data_version");

core/src/ext-data.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ struct crsql_ExtData {
1818
// to crsql_next_db_version()
1919
// and re-set on transaction commit or rollback.
2020
sqlite3_int64 dbVersion;
21+
// the version that the db will be set to at the end of the transaction
22+
// if that transaction were to commit at the time this value is checked.
23+
sqlite3_int64 pendingDbVersion;
2124
int pragmaSchemaVersion;
2225

2326
// we need another schema version number that tracks when we checked it

0 commit comments

Comments
 (0)