I/O trait

This commit is contained in:
Pekka Enberg 2023-09-10 21:54:42 +03:00
parent 58eab38066
commit fe41f46bc0
7 changed files with 52 additions and 76 deletions

View file

@ -8,8 +8,16 @@ pub struct Database {
#[wasm_bindgen]
impl Database {
pub fn open(path: &str) -> Database {
let io = lig_core::IO::new().unwrap();
let inner = lig_core::Database::open(io, path).unwrap();
let io = IO {};
let inner = lig_core::Database::open(&io, path).unwrap();
Database { _inner: inner }
}
}
struct IO {}
impl lig_core::IO for IO {
fn open(&self, _path: &str) -> anyhow::Result<lig_core::PageSource> {
todo!();
}
}

View file

@ -1,6 +1,6 @@
use clap::{Parser, ValueEnum};
use cli_table::{Cell, Table};
use lig_core::{Database, Value, IO};
use lig_core::{Database, Value};
use rustyline::{error::ReadlineError, DefaultEditor};
use std::path::PathBuf;
@ -29,8 +29,8 @@ struct Opts {
fn main() -> anyhow::Result<()> {
let opts = Opts::parse();
let io = IO::new()?;
let db = Database::open(io, opts.database.to_str().unwrap())?;
let io = lig_core::default_io()?;
let db = Database::open(&io, opts.database.to_str().unwrap())?;
let conn = db.connect();
let mut rl = DefaultEditor::new()?;
let home = dirs::home_dir().unwrap();

View file

@ -1,12 +1,21 @@
use crate::{PageSource, IO};
use anyhow::{Ok, Result};
use std::cell::RefCell;
use std::io::{Read, Seek};
use std::sync::Arc;
pub(crate) struct Loop {}
pub(crate) struct DarwinIO {}
impl Loop {
impl IO for DarwinIO {
fn open(&self, path: &str) -> Result<PageSource> {
let file = self.open_file(path)?;
Ok(PageSource { io: Arc::new(file) })
}
}
impl DarwinIO {
pub(crate) fn new() -> Result<Self> {
Ok(Loop {})
Ok(DarwinIO {})
}
pub(crate) fn open_file(&self, path: &str) -> Result<File> {

View file

@ -1,16 +1,25 @@
use crate::io::{PageSource, IO};
use anyhow::Result;
use std::cell::RefCell;
use std::os::unix::io::AsRawFd;
use std::rc::Rc;
use std::sync::Arc;
pub(crate) struct Loop {
pub(crate) struct LinuxIO {
ring: Rc<RefCell<io_uring::IoUring>>,
}
impl Loop {
impl IO for LinuxIO {
fn open(&self, path: &str) -> Result<PageSource> {
let file = self.open_file(path)?;
Ok(PageSource { io: Arc::new(file) })
}
}
impl LinuxIO {
pub(crate) fn new() -> Result<Self> {
let ring = io_uring::IoUring::new(8)?;
Ok(Loop {
Ok(LinuxIO {
ring: Rc::new(RefCell::new(ring)),
})
}

View file

@ -1,75 +1,24 @@
use anyhow::{Ok, Result};
use anyhow::Result;
use std::sync::Arc;
#[cfg(all(feature = "fs", target_os = "linux"))]
#[cfg(target_os = "linux")]
mod linux;
#[cfg(feature = "fs")]
#[cfg(target_os = "macos")]
mod darwin;
/// I/O access method
enum IOMethod {
#[cfg(not(feature = "fs"))]
Memory,
#[cfg(feature = "fs")]
Sync { io: darwin::Loop },
#[cfg(target_os = "linux")]
IoUring { io: linux::Loop },
pub trait IO {
fn open(&self, path: &str) -> Result<PageSource>;
}
/// I/O access interface.
pub struct IO {
io_method: IOMethod,
#[cfg(target_os = "linux")]
pub fn default_io() -> Result<impl IO> {
Ok(linux::LinuxIO::new()?)
}
impl IO {
#[cfg(all(feature = "fs", target_os = "linux"))]
pub fn new() -> Result<Self> {
Ok(IO {
io_method: IOMethod::IoUring {
io: linux::Loop::new()?,
},
})
}
#[cfg(all(feature = "fs", target_os = "macos"))]
pub fn new() -> Result<Self> {
Ok(IO {
io_method: IOMethod::Sync {
io: darwin::Loop::new()?,
},
})
}
#[cfg(not(feature = "fs"))]
pub fn new() -> Result<Self> {
Ok(IO {
io_method: IOMethod::Memory,
})
}
}
impl IO {
pub fn open(&self, path: &str) -> Result<PageSource> {
match &self.io_method {
#[cfg(feature = "fs")]
IOMethod::Sync { io } => {
let io = Arc::new(io.open_file(path)?);
Ok(PageSource { io })
}
#[cfg(all(feature = "fs", target_os = "linux"))]
IOMethod::IoUring { io } => {
let io = Arc::new(io.open_file(path)?);
Ok(PageSource { io })
}
#[cfg(not(feature = "fs"))]
IOMethod::Memory => {
todo!();
}
}
}
#[cfg(target_os = "macos")]
pub fn default_io() -> Result<impl IO> {
Ok(darwin::DarwinIO::new()?)
}
pub struct PageSource {

View file

@ -20,6 +20,7 @@ use schema::Schema;
use sqlite3_parser::{ast::Cmd, lexer::sql::Parser};
use std::sync::Arc;
pub use io::default_io;
pub use io::{PageSource, IO};
pub use types::Value;
@ -29,8 +30,8 @@ pub struct Database {
}
impl Database {
pub fn open(io: IO, path: &str) -> Result<Database> {
let pager = Arc::new(Pager::open(&io, path)?);
pub fn open(io: &impl IO, path: &str) -> Result<Database> {
let pager = Arc::new(Pager::open(io, path)?);
let bootstrap_schema = Arc::new(Schema::new());
let conn = Connection {
pager: pager.clone(),

View file

@ -13,7 +13,7 @@ pub struct Pager {
}
impl Pager {
pub fn open(io: &IO, path: &str) -> anyhow::Result<Self> {
pub fn open(io: &impl IO, path: &str) -> anyhow::Result<Self> {
let database = io.open(path)?;
let db_header = sqlite3_ondisk::read_database_header(&database)?;
let page_size = db_header.page_size as usize;