mirror of
https://github.com/aljazceru/turso.git
synced 2026-02-23 17:05:36 +01:00
core/io: save raw buffers on page
necessary for future lazy addressing of values and writes to page data
This commit is contained in:
@@ -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<RefCell<Buffer>>);
|
||||
pub type WriteComplete = dyn Fn(usize);
|
||||
|
||||
pub struct Completion {
|
||||
pub buf: RefCell<Buffer>,
|
||||
pub buf: Rc<RefCell<Buffer>>,
|
||||
pub complete: Box<Complete>,
|
||||
}
|
||||
|
||||
@@ -34,8 +36,7 @@ pub struct WriteCompletion {
|
||||
}
|
||||
|
||||
impl Completion {
|
||||
pub fn new(buf: Buffer, complete: Box<Complete>) -> Self {
|
||||
let buf = RefCell::new(buf);
|
||||
pub fn new(buf: Rc<RefCell<Buffer>>, complete: Box<Complete>) -> 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) };
|
||||
|
||||
@@ -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<Rc<RefCell<DatabaseHeader>>> {
|
||||
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<RefCell<Buffer>>| {
|
||||
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<Rc<RefCell
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
fn finish_read_database_header(buf: &Buffer, header: Rc<RefCell<DatabaseHeader>>) -> Result<()> {
|
||||
fn finish_read_database_header(
|
||||
buf: Rc<RefCell<Buffer>>,
|
||||
header: Rc<RefCell<DatabaseHeader>>,
|
||||
) -> 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<RefCell<Buffer>>| {
|
||||
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<u8> for PageType {
|
||||
pub struct BTreePage {
|
||||
pub header: BTreePageHeader,
|
||||
pub cells: Vec<BTreeCell>,
|
||||
pub buffer: Rc<RefCell<Buffer>>,
|
||||
}
|
||||
|
||||
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<RefCell<Buffer>>| {
|
||||
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<RefCell<Page>>) -> Result<()> {
|
||||
fn finish_read_btree_page(
|
||||
page_idx: usize,
|
||||
buffer_ref: Rc<RefCell<Buffer>>,
|
||||
page: Rc<RefCell<Page>>,
|
||||
) -> 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<RefCell<Page>>
|
||||
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);
|
||||
|
||||
@@ -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 } => {
|
||||
|
||||
Reference in New Issue
Block a user