Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 61c0b17

Browse files
committed
Use stable memory
1 parent 26fac3d commit 61c0b17

2 files changed

Lines changed: 47 additions & 27 deletions

File tree

crates/ic-sqlite/src/lib.rs

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,26 @@
1-
use std::cell::RefCell;
2-
use std::ffi::CString;
3-
use std::os::raw::c_char;
4-
use std::ptr::NonNull;
5-
1+
use crate::vfs::PagesVfs;
2+
use icfs::StableMemory;
63
use rusqlite::{params_from_iter, OpenFlags, Row, Rows};
74
use serde::ser::Serializer;
85
use serde::Serialize;
96
use serde_json::Value as JsonValue;
107
use sqlite_vfs::{register, RegisterError};
11-
12-
pub use crate::vfs::PagesVfs;
8+
use std::cell::RefCell;
9+
use std::ffi::CString;
10+
use std::os::raw::c_char;
11+
use std::ptr::NonNull;
1312

1413
mod vfs;
1514

1615
// TODO: icfs::stable_memory::WASM_PAGE_SIZE_IN_BYTES;
1716

18-
extern "C" {
19-
pub fn page_count() -> u32;
20-
pub fn get_page(ix: u32, ptr: *mut u8);
21-
pub fn put_page(ix: u32, ptr: *const u8);
22-
pub fn del_page(ix: u32);
23-
pub fn conn_sleep(ms: u32);
24-
}
17+
// extern "C" {
18+
// pub fn page_count() -> u32;
19+
// pub fn get_page(ix: u32, ptr: *mut u8);
20+
// pub fn put_page(ix: u32, ptr: *const u8);
21+
// pub fn del_page(ix: u32);
22+
// pub fn conn_sleep(ms: u32);
23+
// }
2524

2625
// TODO: is there any way to provide this method for SQLite, but not export it as part of the WASM
2726
// module?
@@ -49,7 +48,7 @@ pub struct Connection {
4948

5049
#[no_mangle]
5150
pub unsafe extern "C" fn conn_new() -> *mut Connection {
52-
let is_new = page_count() == 0;
51+
let is_new = StableMemory::capacity() == 0;
5352

5453
let conn = rusqlite::Connection::open_with_flags_and_vfs(
5554
&vfs::DB_NAME,

crates/ic-sqlite/src/vfs.rs

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// use ic_cdk::api::stable;
2-
// use icfs::StableMemory;
2+
use icfs::StableMemory;
33
use std::convert::TryInto;
4-
use std::io::{self, ErrorKind};
4+
use std::io::{self, ErrorKind, Read, Seek, SeekFrom, Write};
55
use std::sync::{Arc, Mutex};
66
use std::time::Duration;
77

@@ -10,6 +10,11 @@ use sqlite_vfs::{LockKind, OpenKind, OpenOptions, Vfs};
1010
pub const DB_NAME: &str = "main.db";
1111
pub const VFS_NAME: &str = "ic-sqlite";
1212

13+
thread_local! {
14+
static STABLE_MEMORY: std::cell::RefCell<StableMemory>
15+
= std::cell::RefCell::new(StableMemory::default());
16+
}
17+
1318
#[derive(Default)]
1419
pub struct PagesVfs<const PAGE_SIZE: usize> {
1520
lock_state: Arc<Mutex<LockState>>,
@@ -69,6 +74,10 @@ impl<const PAGE_SIZE: usize> Vfs for PagesVfs<PAGE_SIZE> {
6974
fn random(&self, buffer: &mut [i8]) {
7075
// Calling `raw_rand` would be preferable, but this method can't be async.
7176
// let raw_rand: Vec<u8> = call(Principal::management_canister(), "raw_rand", ()).await;
77+
//
78+
// We can't write and register a custom getrandom function either because that can't be async:
79+
// * https://github.com/rust-random/rand/blob/b73640705d6714509f8ceccc49e8df996fa19f51/README.md#wasm-support
80+
// * https://docs.rs/getrandom/0.2.7/getrandom/macro.register_custom_getrandom.html
7281
todo!();
7382
// rand::Rng::fill(&mut rand::thread_rng(), buffer);
7483
}
@@ -187,27 +196,39 @@ impl<const PAGE_SIZE: usize> sqlite_vfs::DatabaseHandle for Connection<PAGE_SIZE
187196
}
188197
}
189198

199+
fn put_page<const PAGE_SIZE: usize>(ix: u32, data: &[u8; PAGE_SIZE]) {
200+
STABLE_MEMORY.with(|stable_memory| {
201+
let mut stable_memory = *stable_memory.borrow();
202+
let page_size: u64 = PAGE_SIZE.try_into().unwrap();
203+
let offset: u64 = ix as u64 * page_size;
204+
stable_memory.seek(SeekFrom::Start(offset)).unwrap();
205+
stable_memory.write(data).unwrap();
206+
})
207+
}
208+
190209
impl<const PAGE_SIZE: usize> Connection<PAGE_SIZE> {
191210
fn get_page(ix: u32) -> [u8; PAGE_SIZE] {
192-
let mut data = [0u8; PAGE_SIZE];
193-
unsafe { crate::get_page(ix, data.as_mut_ptr()) };
194-
data
211+
STABLE_MEMORY.with(|stable_memory| {
212+
let mut stable_memory = *stable_memory.borrow();
213+
let mut data = [0u8; PAGE_SIZE];
214+
let page_size: u64 = PAGE_SIZE.try_into().unwrap();
215+
let offset: u64 = ix as u64 * page_size;
216+
stable_memory.seek(SeekFrom::Start(offset)).unwrap();
217+
stable_memory.read(&mut data).unwrap();
218+
data
219+
})
195220
}
196221

197222
fn put_page(ix: u32, data: &[u8; PAGE_SIZE]) {
198-
unsafe {
199-
crate::put_page(ix, data.as_ptr());
200-
}
223+
put_page(ix, data)
201224
}
202225

203226
fn del_page(ix: u32) {
204-
unsafe {
205-
crate::del_page(ix);
206-
}
227+
put_page(ix, &[0; PAGE_SIZE])
207228
}
208229

209230
fn page_count() -> usize {
210-
unsafe { crate::page_count() as usize }
231+
StableMemory::size().try_into().unwrap()
211232
}
212233

213234
fn lock(&mut self, to: LockKind) -> bool {

0 commit comments

Comments
 (0)