diff --git a/bindings/javascript/src/lib.rs b/bindings/javascript/src/lib.rs index ca0aad517..7abdfd521 100644 --- a/bindings/javascript/src/lib.rs +++ b/bindings/javascript/src/lib.rs @@ -695,10 +695,7 @@ impl turso_core::DatabaseStorage for DatabaseFile { page_idx: usize, c: turso_core::Completion, ) -> turso_core::Result> { - let r = match c.completion_type { - turso_core::CompletionType::Read(ref r) => r, - _ => unreachable!(), - }; + let r = c.as_read(); let size = r.buf().len(); assert!(page_idx > 0); if !(512..=65536).contains(&size) || size & (size - 1) != 0 { diff --git a/bindings/wasm/lib.rs b/bindings/wasm/lib.rs index a14bda524..e9b435a57 100644 --- a/bindings/wasm/lib.rs +++ b/bindings/wasm/lib.rs @@ -218,10 +218,7 @@ impl turso_core::File for File { pos: usize, c: Arc, ) -> Result> { - let r = match c.completion_type { - turso_core::CompletionType::Read(ref r) => r, - _ => unreachable!(), - }; + let r = c.as_read(); let nr = { let mut buf = r.buf_mut(); let buf: &mut [u8] = buf.as_mut_slice(); @@ -238,10 +235,7 @@ impl turso_core::File for File { buffer: Arc>, c: Arc, ) -> Result> { - let w = match c.completion_type { - turso_core::CompletionType::Write(ref w) => w, - _ => unreachable!(), - }; + let w = c.as_write(); let buf = buffer.borrow(); let buf: &[u8] = buf.as_slice(); self.vfs.pwrite(self.fd, buf, pos); @@ -349,10 +343,7 @@ impl turso_core::DatabaseStorage for DatabaseFile { page_idx: usize, c: turso_core::Completion, ) -> Result> { - let r = match c.completion_type { - turso_core::CompletionType::Read(ref r) => r, - _ => unreachable!(), - }; + let r = c.as_read(); let size = r.buf().len(); assert!(page_idx > 0); if !(512..=65536).contains(&size) || size & (size - 1) != 0 { diff --git a/core/io/mod.rs b/core/io/mod.rs index ee757d972..a2717db0b 100644 --- a/core/io/mod.rs +++ b/core/io/mod.rs @@ -58,7 +58,13 @@ pub type Complete = dyn Fn(Arc>, i32); pub type WriteComplete = dyn Fn(i32); pub type SyncComplete = dyn Fn(i32); +#[must_use] +#[derive(Clone)] pub struct Completion { + inner: Arc, +} + +struct CompletionInner { pub completion_type: CompletionType, is_completed: Cell, } @@ -77,8 +83,10 @@ pub struct ReadCompletion { impl Completion { pub fn new(completion_type: CompletionType) -> Self { Self { - completion_type, - is_completed: Cell::new(false), + inner: Arc::new(CompletionInner { + completion_type, + is_completed: Cell::new(false), + }), } } @@ -110,26 +118,35 @@ impl Completion { } pub fn is_completed(&self) -> bool { - self.is_completed.get() + self.inner.is_completed.get() } pub fn complete(&self, result: i32) { - match &self.completion_type { + match &self.inner.completion_type { CompletionType::Read(r) => r.complete(result), CompletionType::Write(w) => w.complete(result), CompletionType::Sync(s) => s.complete(result), // fix }; - self.is_completed.set(true); + self.inner.is_completed.set(true); } /// only call this method if you are sure that the completion is /// a ReadCompletion, panics otherwise pub fn as_read(&self) -> &ReadCompletion { - match self.completion_type { + match self.inner.completion_type { CompletionType::Read(ref r) => r, _ => unreachable!(), } } + + /// only call this method if you are sure that the completion is + /// a WriteCompletion, panics otherwise + pub fn as_write(&self) -> &WriteCompletion { + match self.inner.completion_type { + CompletionType::Write(ref w) => w, + _ => unreachable!(), + } + } } pub struct WriteCompletion { diff --git a/core/io/vfs.rs b/core/io/vfs.rs index 4df856eed..bad8a5940 100644 --- a/core/io/vfs.rs +++ b/core/io/vfs.rs @@ -1,7 +1,6 @@ use super::{Buffer, Completion, File, MemoryIO, OpenFlags, IO}; use crate::ext::VfsMod; use crate::io::clock::{Clock, Instant}; -use crate::io::CompletionType; use crate::{LimboError, Result}; use std::cell::RefCell; use std::ffi::{c_void, CString}; @@ -99,10 +98,7 @@ impl File for VfsFileImpl { } fn pread(&self, pos: usize, c: Arc) -> Result> { - let r = match c.completion_type { - CompletionType::Read(ref r) => r, - _ => unreachable!(), - }; + let r = c.as_read(); let result = { let mut buf = r.buf_mut(); let count = buf.len(); diff --git a/core/storage/database.rs b/core/storage/database.rs index ffb11f724..5d00a09a6 100644 --- a/core/storage/database.rs +++ b/core/storage/database.rs @@ -1,5 +1,4 @@ use crate::error::LimboError; -use crate::io::CompletionType; use crate::{io::Completion, Buffer, Result}; use std::{cell::RefCell, sync::Arc}; use tracing::{instrument, Level}; @@ -89,10 +88,7 @@ unsafe impl Sync for FileMemoryStorage {} impl DatabaseStorage for FileMemoryStorage { #[instrument(skip_all, level = Level::DEBUG)] fn read_page(&self, page_idx: usize, c: Completion) -> Result> { - let r = match c.completion_type { - CompletionType::Read(ref r) => r, - _ => unreachable!(), - }; + let r = c.as_read(); let size = r.buf().len(); assert!(page_idx > 0); if !(512..=65536).contains(&size) || size & (size - 1) != 0 {