Skip to content

Commit 4ee44bd

Browse files
committed
switch to keeping the vec in a box
1 parent a7b5320 commit 4ee44bd

File tree

9 files changed

+71
-76
lines changed

9 files changed

+71
-76
lines changed

core/rs/core/src/alter.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
// Not yet fully migrated from `crsqlite.c`
22

3-
use core::ffi::{c_char, c_int, CStr};
4-
3+
use alloc::boxed::Box;
54
use alloc::format;
65
use alloc::string::String;
76
use alloc::vec::Vec;
7+
use core::ffi::{c_char, c_int, CStr};
88
use core::mem;
99
#[cfg(not(feature = "std"))]
1010
use num_traits::FromPrimitive;
@@ -99,11 +99,8 @@ unsafe fn compact_post_alter(
9999
}
100100
return Err(ResultCode::ERROR);
101101
}
102-
let table_infos = mem::ManuallyDrop::new(Vec::from_raw_parts(
103-
(*ext_data).tableInfos as *mut TableInfo,
104-
(*ext_data).tableInfosLen as usize,
105-
(*ext_data).tableInfosCap as usize,
106-
));
102+
let table_infos =
103+
mem::ManuallyDrop::new(Box::from_raw((*ext_data).tableInfos as *mut Vec<TableInfo>));
107104
let table_info = table_infos.iter().find(|x| x.tbl_name == tbl_name_str);
108105
if table_info.is_none() {
109106
return Err(ResultCode::ERROR);

core/rs/core/src/c.rs

Lines changed: 10 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,6 @@ pub struct crsql_ExtData {
5959
pub siteId: *mut ::core::ffi::c_uchar,
6060
pub pDbVersionStmt: *mut sqlite::stmt,
6161
pub tableInfos: *mut ::core::ffi::c_void,
62-
pub tableInfosLen: ::core::ffi::c_int,
63-
pub tableInfosCap: ::core::ffi::c_int,
6462
pub rowsImpacted: ::core::ffi::c_int,
6563
pub seq: ::core::ffi::c_int,
6664
pub pSetSyncBitStmt: *mut sqlite::stmt,
@@ -109,6 +107,7 @@ extern "C" {
109107
db: *mut sqlite::sqlite3,
110108
siteIdBuffer: *mut c_char,
111109
) -> *mut crsql_ExtData;
110+
pub fn crsql_freeExtData(pExtData: *mut crsql_ExtData);
112111
}
113112

114113
#[test]
@@ -263,7 +262,7 @@ fn bindgen_test_layout_crsql_ExtData() {
263262
let ptr = UNINIT.as_ptr();
264263
assert_eq!(
265264
::core::mem::size_of::<crsql_ExtData>(),
266-
136usize,
265+
128usize,
267266
concat!("Size of: ", stringify!(crsql_ExtData))
268267
);
269268
assert_eq!(
@@ -373,29 +372,9 @@ fn bindgen_test_layout_crsql_ExtData() {
373372
stringify!(tableInfos)
374373
)
375374
);
376-
assert_eq!(
377-
unsafe { ::core::ptr::addr_of!((*ptr).tableInfosLen) as usize - ptr as usize },
378-
72usize,
379-
concat!(
380-
"Offset of field: ",
381-
stringify!(crsql_ExtData),
382-
"::",
383-
stringify!(tableInfosLen)
384-
)
385-
);
386-
assert_eq!(
387-
unsafe { ::core::ptr::addr_of!((*ptr).tableInfosCap) as usize - ptr as usize },
388-
76usize,
389-
concat!(
390-
"Offset of field: ",
391-
stringify!(crsql_ExtData),
392-
"::",
393-
stringify!(tableInfosCap)
394-
)
395-
);
396375
assert_eq!(
397376
unsafe { ::core::ptr::addr_of!((*ptr).rowsImpacted) as usize - ptr as usize },
398-
80usize,
377+
72usize,
399378
concat!(
400379
"Offset of field: ",
401380
stringify!(crsql_ExtData),
@@ -405,7 +384,7 @@ fn bindgen_test_layout_crsql_ExtData() {
405384
);
406385
assert_eq!(
407386
unsafe { ::core::ptr::addr_of!((*ptr).seq) as usize - ptr as usize },
408-
84usize,
387+
76usize,
409388
concat!(
410389
"Offset of field: ",
411390
stringify!(crsql_ExtData),
@@ -415,7 +394,7 @@ fn bindgen_test_layout_crsql_ExtData() {
415394
);
416395
assert_eq!(
417396
unsafe { ::core::ptr::addr_of!((*ptr).pSetSyncBitStmt) as usize - ptr as usize },
418-
88usize,
397+
80usize,
419398
concat!(
420399
"Offset of field: ",
421400
stringify!(crsql_ExtData),
@@ -425,7 +404,7 @@ fn bindgen_test_layout_crsql_ExtData() {
425404
);
426405
assert_eq!(
427406
unsafe { ::core::ptr::addr_of!((*ptr).pClearSyncBitStmt) as usize - ptr as usize },
428-
96usize,
407+
88usize,
429408
concat!(
430409
"Offset of field: ",
431410
stringify!(crsql_ExtData),
@@ -435,7 +414,7 @@ fn bindgen_test_layout_crsql_ExtData() {
435414
);
436415
assert_eq!(
437416
unsafe { ::core::ptr::addr_of!((*ptr).pSetSiteIdOrdinalStmt) as usize - ptr as usize },
438-
104usize,
417+
96usize,
439418
concat!(
440419
"Offset of field: ",
441420
stringify!(crsql_ExtData),
@@ -445,7 +424,7 @@ fn bindgen_test_layout_crsql_ExtData() {
445424
);
446425
assert_eq!(
447426
unsafe { ::core::ptr::addr_of!((*ptr).pSelectSiteIdOrdinalStmt) as usize - ptr as usize },
448-
112usize,
427+
104usize,
449428
concat!(
450429
"Offset of field: ",
451430
stringify!(crsql_ExtData),
@@ -455,7 +434,7 @@ fn bindgen_test_layout_crsql_ExtData() {
455434
);
456435
assert_eq!(
457436
unsafe { ::core::ptr::addr_of!((*ptr).pSelectClockTablesStmt) as usize - ptr as usize },
458-
120usize,
437+
112usize,
459438
concat!(
460439
"Offset of field: ",
461440
stringify!(crsql_ExtData),
@@ -465,7 +444,7 @@ fn bindgen_test_layout_crsql_ExtData() {
465444
);
466445
assert_eq!(
467446
unsafe { ::core::ptr::addr_of!((*ptr).pStmtCache) as usize - ptr as usize },
468-
128usize,
447+
120usize,
469448
concat!(
470449
"Offset of field: ",
471450
stringify!(crsql_ExtData),

core/rs/core/src/changes_vtab.rs

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use crate::stmt_cache::{
55
get_cache_key, get_cached_stmt, reset_cached_stmt, set_cached_stmt, CachedStmtType,
66
};
77
use crate::tableinfo::{crsql_ensure_table_infos_are_up_to_date, TableInfo};
8+
use alloc::boxed::Box;
89
use alloc::format;
910
use alloc::string::String;
1011
use alloc::vec::Vec;
@@ -290,16 +291,14 @@ unsafe fn changes_filter(
290291
}
291292

292293
// nothing to fetch, no crrs exist.
293-
if (*(*tab).pExtData).tableInfosLen == 0 {
294+
let tbl_infos = mem::ManuallyDrop::new(Box::from_raw(
295+
(*(*tab).pExtData).tableInfos as *mut Vec<TableInfo>,
296+
));
297+
if tbl_infos.len() == 0 {
294298
return Ok(ResultCode::OK);
295299
}
296300

297-
let table_infos = mem::ManuallyDrop::new(Vec::from_raw_parts(
298-
(*(*tab).pExtData).tableInfos as *mut TableInfo,
299-
(*(*tab).pExtData).tableInfosLen as usize,
300-
(*(*tab).pExtData).tableInfosCap as usize,
301-
));
302-
let sql = changes_union_query(&table_infos, idx_str)?;
301+
let sql = changes_union_query(&tbl_infos, idx_str)?;
303302

304303
let stmt = db.prepare_v2(&sql)?;
305304
for (i, arg) in args.iter().enumerate() {
@@ -375,10 +374,8 @@ unsafe fn changes_next(
375374
.column_int64(ClockUnionColumn::RowId as i32);
376375
(*cursor).dbVersion = db_version;
377376

378-
let tbl_infos = mem::ManuallyDrop::new(Vec::from_raw_parts(
379-
(*(*(*cursor).pTab).pExtData).tableInfos as *mut TableInfo,
380-
(*(*(*cursor).pTab).pExtData).tableInfosLen as usize,
381-
(*(*(*cursor).pTab).pExtData).tableInfosCap as usize,
377+
let tbl_infos = mem::ManuallyDrop::new(Box::from_raw(
378+
(*(*(*cursor).pTab).pExtData).tableInfos as *mut Vec<TableInfo>,
382379
));
383380
// TODO: will this work given `insert_tbl` is null termed?
384381
let tbl_info_index = tbl_infos.iter().position(|x| x.tbl_name == tbl);

core/rs/core/src/changes_vtab_write.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use alloc::boxed::Box;
12
use alloc::ffi::CString;
23
use alloc::format;
34
use alloc::string::String;
@@ -591,10 +592,8 @@ unsafe fn merge_insert(
591592
}
592593

593594
let insert_site_id = insert_site_id.blob();
594-
let tbl_infos = mem::ManuallyDrop::new(Vec::from_raw_parts(
595-
(*(*tab).pExtData).tableInfos as *mut TableInfo,
596-
(*(*tab).pExtData).tableInfosLen as usize,
597-
(*(*tab).pExtData).tableInfosCap as usize,
595+
let tbl_infos = mem::ManuallyDrop::new(Box::from_raw(
596+
(*(*tab).pExtData).tableInfos as *mut Vec<TableInfo>,
598597
));
599598
// TODO: will this work given `insert_tbl` is null termed?
600599
let tbl_info_index = tbl_infos.iter().position(|x| x.tbl_name == insert_tbl);

core/rs/core/src/tableinfo.rs

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,16 @@ use crate::c::crsql_ExtData;
33
use crate::c::crsql_fetchPragmaSchemaVersion;
44
use crate::c::TABLE_INFO_SCHEMA_VERSION;
55
use crate::util::Countable;
6+
use alloc::boxed::Box;
67
use alloc::format;
78
use alloc::string::String;
89
use alloc::vec;
910
use alloc::vec::Vec;
1011
use core::ffi::c_char;
1112
use core::ffi::c_int;
13+
use core::ffi::c_void;
1214
use core::mem;
15+
use core::mem::forget;
1316
use num_traits::ToPrimitive;
1417
use sqlite_nostd as sqlite;
1518
use sqlite_nostd::Connection;
@@ -36,12 +39,14 @@ pub struct ColumnInfo {
3639

3740
#[no_mangle]
3841
pub extern "C" fn crsql_init_table_info_vec(ext_data: *mut crsql_ExtData) {
39-
let vec = vec![];
40-
let (ptr, len, cap) = vec.into_raw_parts();
42+
let vec: Vec<TableInfo> = vec![];
43+
unsafe { (*ext_data).tableInfos = Box::into_raw(Box::new(vec)) as *mut c_void }
44+
}
45+
46+
#[no_mangle]
47+
pub extern "C" fn crsql_drop_table_info_vec(ext_data: *mut crsql_ExtData) {
4148
unsafe {
42-
(*ext_data).tableInfos = ptr;
43-
(*ext_data).tableInfosLen = len as i32;
44-
(*ext_data).tableInfosCap = cap as i32;
49+
drop(Box::from_raw((*ext_data).tableInfos as *mut Vec<TableInfo>));
4550
}
4651
}
4752

@@ -58,27 +63,23 @@ pub extern "C" fn crsql_ensure_table_infos_are_up_to_date(
5863
return ResultCode::ERROR as c_int;
5964
}
6065

61-
let mut table_infos = unsafe {
62-
mem::ManuallyDrop::new(Vec::from_raw_parts(
63-
(*ext_data).tableInfos as *mut TableInfo,
64-
(*ext_data).tableInfosLen as usize,
65-
(*ext_data).tableInfosCap as usize,
66-
))
67-
};
66+
let mut table_infos = unsafe { Box::from_raw((*ext_data).tableInfos as *mut Vec<TableInfo>) };
6867

6968
if schema_changed > 0 || table_infos.len() == 0 {
70-
table_infos.clear();
7169
match pull_all_table_infos(db, ext_data, err) {
7270
Ok(new_table_infos) => {
73-
table_infos.extend(new_table_infos.into_iter());
71+
*table_infos = new_table_infos;
72+
forget(table_infos);
7473
return ResultCode::OK as c_int;
7574
}
7675
Err(e) => {
76+
forget(table_infos);
7777
return e as c_int;
7878
}
7979
}
8080
}
8181

82+
forget(table_infos);
8283
return ResultCode::OK as c_int;
8384
}
8485

@@ -107,7 +108,11 @@ fn pull_all_table_infos(
107108

108109
let mut ret = vec![];
109110
for name in clock_table_names {
110-
ret.push(pull_table_info(db, &name, err)?)
111+
ret.push(pull_table_info(
112+
db,
113+
&name[0..(name.len() - "__crsql_clock".len())],
114+
err,
115+
)?)
111116
}
112117

113118
Ok(ret)

core/rs/integration-check/tests/tableinfo.rs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
use std::ffi::{c_char, CString};
1+
use std::{
2+
ffi::{c_char, CString},
3+
mem,
4+
};
25

3-
use crsql_bundle::crsql_core;
6+
use crsql_bundle::crsql_core::{self, tableinfo::TableInfo};
47
use sqlite::Connection;
58
use sqlite_nostd as sqlite;
69

@@ -41,13 +44,32 @@ fn test_ensure_table_infos_are_up_to_date() {
4144
)
4245
.expect("made foo clock");
4346

47+
let stmt = c
48+
.prepare_v2("SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name LIKE '%__crsql_clock'")
49+
.expect("preped");
50+
let r = stmt.step().expect("stepped");
51+
assert_eq!(r, sqlite::ResultCode::ROW);
52+
4453
let ext_data = unsafe { crsql_core::c::crsql_newExtData(raw_db, make_site()) };
4554
crsql_core::tableinfo::crsql_ensure_table_infos_are_up_to_date(
4655
raw_db,
4756
ext_data,
4857
make_err_ptr(),
4958
);
5059

60+
let table_infos = unsafe {
61+
mem::ManuallyDrop::new(Box::from_raw((*ext_data).tableInfos as *mut Vec<TableInfo>))
62+
};
63+
64+
assert_eq!(table_infos.len(), 1);
65+
assert_eq!(table_infos[0].tbl_name, "foo");
66+
67+
unsafe {
68+
crsql_core::c::crsql_freeExtData(ext_data);
69+
};
70+
71+
// free ext_data since it has prepared statements
72+
5173
// ideally we can check if it does a repull or not...
5274
// we could do this by mutating table infos to something unexpected and checking it is still that.
5375
decrement_counter();

core/src/ext-data.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
void crsql_init_stmt_cache(crsql_ExtData *pExtData);
88
void crsql_clear_stmt_cache(crsql_ExtData *pExtData);
99
void crsql_init_table_info_vec(crsql_ExtData *pExtData);
10+
void crsql_drop_table_info_vec(crsql_ExtData *pExtData);
1011

1112
crsql_ExtData *crsql_newExtData(sqlite3 *db, unsigned char *siteIdBuffer) {
1213
crsql_ExtData *pExtData = sqlite3_malloc(sizeof *pExtData);
@@ -50,8 +51,6 @@ crsql_ExtData *crsql_newExtData(sqlite3 *db, unsigned char *siteIdBuffer) {
5051
pExtData->siteId = siteIdBuffer;
5152
pExtData->pDbVersionStmt = 0;
5253
pExtData->tableInfos = 0;
53-
pExtData->tableInfosCap = 0;
54-
pExtData->tableInfosLen = 0;
5554
pExtData->rowsImpacted = 0;
5655
pExtData->pStmtCache = 0;
5756
crsql_init_stmt_cache(pExtData);
@@ -77,6 +76,7 @@ void crsql_freeExtData(crsql_ExtData *pExtData) {
7776
sqlite3_finalize(pExtData->pSelectSiteIdOrdinalStmt);
7877
sqlite3_finalize(pExtData->pSelectClockTablesStmt);
7978
crsql_clear_stmt_cache(pExtData);
79+
crsql_drop_table_info_vec(pExtData);
8080
sqlite3_free(pExtData);
8181
}
8282

core/src/ext-data.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@ struct crsql_ExtData {
2929
unsigned char *siteId;
3030
sqlite3_stmt *pDbVersionStmt;
3131
void *tableInfos;
32-
int tableInfosLen;
33-
int tableInfosCap;
3432

3533
// tracks the number of rows impacted by all inserts into crsql_changes in the
3634
// current transaction. This number is reset on transaction commit.

core/src/ext-data.test.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,6 @@ static void textNewExtData() {
3535
assert(pExtData->pDbVersionStmt == 0);
3636
// table info allocated to an empty vec
3737
assert(pExtData->tableInfos != 0);
38-
assert(pExtData->tableInfosLen == 0);
39-
assert(pExtData->tableInfosCap == 0);
4038

4139
// data version should have been fetched
4240
assert(pExtData->pragmaDataVersion != -1);

0 commit comments

Comments
 (0)