diff --git a/core/io/mod.rs b/core/io/mod.rs index 98d903adc..36d9b985a 100644 --- a/core/io/mod.rs +++ b/core/io/mod.rs @@ -1,7 +1,9 @@ use crate::Result; use cfg_block::cfg_block; +use std::fmt; use std::{ cell::{Ref, RefCell, RefMut}, + fmt::Debug, mem::ManuallyDrop, pin::Pin, rc::Rc, @@ -21,11 +23,11 @@ pub trait IO { fn run_once(&self) -> Result<()>; } -pub type Complete = dyn Fn(&Buffer); +pub type Complete = dyn Fn(Rc>); pub type WriteComplete = dyn Fn(usize); pub struct Completion { - pub buf: RefCell, + pub buf: Rc>, pub complete: Box, } @@ -34,8 +36,7 @@ pub struct WriteCompletion { } impl Completion { - pub fn new(buf: Buffer, complete: Box) -> Self { - let buf = RefCell::new(buf); + pub fn new(buf: Rc>, complete: Box) -> Self { Self { buf, complete } } @@ -48,8 +49,7 @@ impl Completion { } pub fn complete(&self) { - let buf = self.buf.borrow_mut(); - (self.complete)(&buf); + (self.complete)(self.buf.clone()); } } @@ -72,6 +72,12 @@ pub struct Buffer { drop: BufferDropFn, } +impl Debug for Buffer { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{:?}", self.data) + } +} + impl Drop for Buffer { fn drop(&mut self) { let data = unsafe { ManuallyDrop::take(&mut self.data) }; diff --git a/core/sqlite3_ondisk.rs b/core/sqlite3_ondisk.rs index 35f170475..e7ba274c4 100644 --- a/core/sqlite3_ondisk.rs +++ b/core/sqlite3_ondisk.rs @@ -31,6 +31,7 @@ use crate::types::{OwnedRecord, OwnedValue}; use crate::{PageSource, Result}; use log::trace; use std::cell::RefCell; +use std::ptr::NonNull; use std::rc::Rc; /// The size of the database header in bytes. @@ -70,10 +71,10 @@ pub struct DatabaseHeader { pub fn begin_read_database_header(page_source: &PageSource) -> Result>> { let drop_fn = Rc::new(|_buf| {}); - let buf = Buffer::allocate(512, drop_fn); + let buf = Rc::new(RefCell::new(Buffer::allocate(512, drop_fn))); let result = Rc::new(RefCell::new(DatabaseHeader::default())); let header = result.clone(); - let complete = Box::new(move |buf: &Buffer| { + let complete = Box::new(move |buf: Rc>| { let header = header.clone(); finish_read_database_header(buf, header).unwrap(); }); @@ -82,7 +83,11 @@ pub fn begin_read_database_header(page_source: &PageSource) -> Result>) -> Result<()> { +fn finish_read_database_header( + buf: Rc>, + header: Rc>, +) -> Result<()> { + let buf = buf.borrow(); let buf = buf.as_slice(); let mut header = std::cell::RefCell::borrow_mut(&header); header.magic.copy_from_slice(&buf[0..16]); @@ -123,9 +128,9 @@ pub fn begin_write_database_header(header: &DatabaseHeader, pager: &Pager) -> Re let buffer_to_copy_in_cb = buffer_to_copy.clone(); let header_cb = header.clone(); - let complete = Box::new(move |buffer: &Buffer| { + let complete = Box::new(move |buffer: Rc>| { let header = header_cb.clone(); - let buffer: Buffer = buffer.clone(); + let buffer: Buffer = buffer.borrow().clone(); let buffer = Rc::new(RefCell::new(buffer)); { let mut buf_mut = std::cell::RefCell::borrow_mut(&buffer); @@ -163,7 +168,7 @@ pub fn begin_write_database_header(header: &DatabaseHeader, pager: &Pager) -> Re }); let drop_fn = Rc::new(|_buf| {}); - let buf = Buffer::allocate(512, drop_fn); + let buf = Rc::new(RefCell::new(Buffer::allocate(512, drop_fn))); let c = Rc::new(Completion::new(buf.clone(), complete)); page_source.get(1, c.clone())?; // run get header block @@ -221,6 +226,7 @@ impl TryFrom for PageType { pub struct BTreePage { pub header: BTreePageHeader, pub cells: Vec, + pub buffer: Rc>, } impl BTreePage { @@ -246,8 +252,8 @@ pub fn begin_read_btree_page( let buffer_pool = buffer_pool.clone(); buffer_pool.put(buf); }); - let buf = Buffer::new(buf, drop_fn); - let complete = Box::new(move |buf: &Buffer| { + let buf = Rc::new(RefCell::new(Buffer::new(buf, drop_fn))); + let complete = Box::new(move |buf: Rc>| { let page = page.clone(); if finish_read_btree_page(page_idx, buf, page.clone()).is_err() { page.borrow_mut().set_error(); @@ -258,13 +264,18 @@ pub fn begin_read_btree_page( Ok(()) } -fn finish_read_btree_page(page_idx: usize, buf: &Buffer, page: Rc>) -> Result<()> { +fn finish_read_btree_page( + page_idx: usize, + buffer_ref: Rc>, + page: Rc>, +) -> Result<()> { trace!("finish_read_btree_page(page_idx = {})", page_idx); let mut pos = if page_idx == 1 { DATABASE_HEADER_SIZE } else { 0 }; + let buf = buffer_ref.borrow(); let buf = buf.as_slice(); let mut header = BTreePageHeader { page_type: buf[pos].try_into()?, @@ -291,7 +302,11 @@ fn finish_read_btree_page(page_idx: usize, buf: &Buffer, page: Rc> let cell = read_btree_cell(buf, &header.page_type, cell_pointer as usize)?; cells.push(cell); } - let inner = BTreePage { header, cells }; + let inner = BTreePage { + header, + cells, + buffer: buffer_ref.clone(), + }; { let page = page.borrow_mut(); page.contents.write().unwrap().replace(inner); diff --git a/core/vdbe/mod.rs b/core/vdbe/mod.rs index d638a302c..929b8c66a 100644 --- a/core/vdbe/mod.rs +++ b/core/vdbe/mod.rs @@ -410,8 +410,6 @@ impl Program { loop { let insn = &self.insns[state.pc as usize]; trace_insn(self, state.pc as InsnReference, insn); - dbg!(state.pc); - dbg!(insn); let mut cursors = state.cursors.borrow_mut(); match insn { Insn::Init { target_pc } => {