diff --git a/core/lib.rs b/core/lib.rs index aa139b319..87daf3dc6 100644 --- a/core/lib.rs +++ b/core/lib.rs @@ -809,15 +809,8 @@ impl Connection { self.pager.borrow().wal_frame_count() } - pub fn wal_get_frame( - &self, - frame_no: u32, - p_frame: *mut u8, - frame_len: u32, - ) -> Result> { - self.pager - .borrow() - .wal_get_frame(frame_no, p_frame, frame_len) + pub fn wal_get_frame(&self, frame_no: u32, frame: &mut [u8]) -> Result> { + self.pager.borrow().wal_get_frame(frame_no, frame) } /// Flush dirty pages to disk. diff --git a/core/storage/pager.rs b/core/storage/pager.rs index 8d93ae95d..9a760f2ff 100644 --- a/core/storage/pager.rs +++ b/core/storage/pager.rs @@ -959,19 +959,9 @@ impl Pager { } #[instrument(skip_all, level = Level::DEBUG)] - pub fn wal_get_frame( - &self, - frame_no: u32, - p_frame: *mut u8, - frame_len: u32, - ) -> Result> { + pub fn wal_get_frame(&self, frame_no: u32, frame: &mut [u8]) -> Result> { let wal = self.wal.borrow(); - wal.read_frame_raw( - frame_no.into(), - self.buffer_pool.clone(), - p_frame, - frame_len, - ) + wal.read_frame_raw(frame_no.into(), frame) } #[instrument(skip_all, level = Level::DEBUG, name = "pager_checkpoint",)] diff --git a/core/storage/sqlite3_ondisk.rs b/core/storage/sqlite3_ondisk.rs index bf5c1d47e..400d8af65 100644 --- a/core/storage/sqlite3_ondisk.rs +++ b/core/storage/sqlite3_ondisk.rs @@ -1509,6 +1509,24 @@ pub fn read_entire_wal_dumb(file: &Arc) -> Result, + offset: usize, + page_size: u32, + complete: Box>, i32)>, +) -> Result> { + tracing::trace!("begin_read_wal_frame_raw(offset={})", offset); + let drop_fn = Rc::new(|_buf| {}); + let buf = Arc::new(RefCell::new(Buffer::allocate( + page_size as usize + WAL_FRAME_HEADER_SIZE, + drop_fn, + ))); + #[allow(clippy::arc_with_non_send_sync)] + let c = Completion::new_read(buf, complete); + let c = io.pread(offset, c.into())?; + Ok(c) +} + pub fn begin_read_wal_frame( io: &Arc, offset: usize, diff --git a/core/storage/wal.rs b/core/storage/wal.rs index bb5eba210..86106e521 100644 --- a/core/storage/wal.rs +++ b/core/storage/wal.rs @@ -20,8 +20,8 @@ use crate::fast_lock::SpinLock; use crate::io::{File, IO}; use crate::result::LimboResult; use crate::storage::sqlite3_ondisk::{ - begin_read_wal_frame, begin_write_wal_frame, finish_read_page, WAL_FRAME_HEADER_SIZE, - WAL_HEADER_SIZE, + begin_read_wal_frame, begin_read_wal_frame_raw, begin_write_wal_frame, finish_read_page, + WAL_FRAME_HEADER_SIZE, WAL_HEADER_SIZE, }; use crate::types::IOResult; use crate::{turso_assert, Buffer, LimboError, Result}; @@ -214,14 +214,8 @@ pub trait Wal { /// Read a frame from the WAL. fn read_frame(&self, frame_id: u64, page: PageRef, buffer_pool: Arc) -> Result<()>; - /// Read a frame from the WAL. - fn read_frame_raw( - &self, - frame_id: u64, - buffer_pool: Arc, - frame: *mut u8, - frame_len: u32, - ) -> Result>; + /// Read a raw frame (header included) from the WAL. + fn read_frame_raw(&self, frame_id: u64, frame: &mut [u8]) -> Result>; /// Write a frame to the WAL. /// db_size is the database size in pages after the transaction finishes. @@ -289,13 +283,7 @@ impl Wal for DummyWAL { Ok(()) } - fn read_frame_raw( - &self, - _frame_id: u64, - _buffer_pool: Arc, - _frame: *mut u8, - _frame_len: u32, - ) -> Result> { + fn read_frame_raw(&self, _frame_id: u64, _frame: &mut [u8]) -> Result> { todo!(); } @@ -633,15 +621,10 @@ impl Wal for WalFile { } #[instrument(skip_all, level = Level::DEBUG)] - fn read_frame_raw( - &self, - frame_id: u64, - buffer_pool: Arc, - frame: *mut u8, - frame_len: u32, - ) -> Result> { + fn read_frame_raw(&self, frame_id: u64, frame: &mut [u8]) -> Result> { tracing::debug!("read_frame({})", frame_id); let offset = self.frame_offset(frame_id); + let (frame_ptr, frame_len) = (frame.as_mut_ptr(), frame.len()); let complete = Box::new(move |buf: Arc>, bytes_read: i32| { let buf = buf.borrow(); let buf_len = buf.len(); @@ -651,15 +634,11 @@ impl Wal for WalFile { ); let buf_ptr = buf.as_ptr(); unsafe { - std::ptr::copy_nonoverlapping(buf_ptr, frame, frame_len as usize); + std::ptr::copy_nonoverlapping(buf_ptr, frame_ptr, frame_len); } }); - let c = begin_read_wal_frame( - &self.get_shared().file, - offset + WAL_FRAME_HEADER_SIZE, - buffer_pool, - complete, - )?; + let c = + begin_read_wal_frame_raw(&self.get_shared().file, offset, self.page_size(), complete)?; Ok(c) } diff --git a/sqlite3/src/lib.rs b/sqlite3/src/lib.rs index c063bcccc..f502e0286 100644 --- a/sqlite3/src/lib.rs +++ b/sqlite3/src/lib.rs @@ -1185,7 +1185,8 @@ pub unsafe extern "C" fn libsql_wal_get_frame( } let db: &mut sqlite3 = &mut *db; let db = db.inner.lock().unwrap(); - match db.conn.wal_get_frame(frame_no, p_frame, frame_len) { + let frame = std::slice::from_raw_parts_mut(p_frame, frame_len as usize); + match db.conn.wal_get_frame(frame_no, frame) { Ok(c) => match db.io.wait_for_completion(c) { Ok(_) => SQLITE_OK, Err(_) => SQLITE_ERROR,