diff --git a/bindings/javascript/src/lib.rs b/bindings/javascript/src/lib.rs index 2c9f874ef..7a8ed46c1 100644 --- a/bindings/javascript/src/lib.rs +++ b/bindings/javascript/src/lib.rs @@ -726,7 +726,7 @@ impl turso_core::DatabaseStorage for DatabaseFile { fn size(&self) -> turso_core::Result { self.file.size() } - fn truncate(&self, len: usize, c: turso_core::Completion) -> turso_core::Result<()> { + fn truncate(&self, len: usize, c: Arc) -> turso_core::Result<()> { let _ = self.file.truncate(len, c)?; Ok(()) } diff --git a/bindings/wasm/lib.rs b/bindings/wasm/lib.rs index 40bafe9b5..2e9e49984 100644 --- a/bindings/wasm/lib.rs +++ b/bindings/wasm/lib.rs @@ -264,12 +264,12 @@ impl turso_core::File for File { fn truncate( &self, len: usize, - c: turso_core::Completion, + c: Arc, ) -> Result> { - self.vfs.truncate(self.fd, len as usize); + self.vfs.truncate(self.fd, len); c.complete(0); #[allow(clippy::arc_with_non_send_sync)] - Ok(Arc::new(c)) + Ok(c) } } @@ -391,7 +391,7 @@ impl turso_core::DatabaseStorage for DatabaseFile { self.file.size() } - fn truncate(&self, len: usize, c: turso_core::Completion) -> Result<()> { + fn truncate(&self, len: usize, c: Arc) -> Result<()> { self.file.truncate(len, c)?; Ok(()) } diff --git a/core/io/generic.rs b/core/io/generic.rs index 005de9553..cb70ea068 100644 --- a/core/io/generic.rs +++ b/core/io/generic.rs @@ -121,12 +121,12 @@ impl File for GenericFile { Ok(c) } - fn truncate(&self, len: usize, c: Completion) -> Result> { + fn truncate(&self, len: usize, c: Arc) -> Result> { let mut file = self.file.borrow_mut(); file.set_len(len as u64) .map_err(|err| LimboError::IOError(err))?; c.complete(0); - Ok(Arc::new(c)) + Ok(c) } fn size(&self) -> Result { diff --git a/core/io/io_uring.rs b/core/io/io_uring.rs index be8083032..4b02aa516 100644 --- a/core/io/io_uring.rs +++ b/core/io/io_uring.rs @@ -354,14 +354,13 @@ impl File for UringFile { Ok(self.file.metadata()?.len()) } - fn truncate(&self, len: usize, c: Completion) -> Result> { + fn truncate(&self, len: usize, c: Arc) -> Result> { let mut io = self.io.borrow_mut(); let truncate = with_fd!(self, |fd| { io_uring::opcode::Ftruncate::new(fd, len as u64) .build() .user_data(io.ring.get_key()) }); - let c = Arc::new(c); io.ring.submit_entry(&truncate, c.clone()); Ok(c) } diff --git a/core/io/memory.rs b/core/io/memory.rs index ee9903801..df9161453 100644 --- a/core/io/memory.rs +++ b/core/io/memory.rs @@ -174,7 +174,7 @@ impl File for MemoryFile { Ok(c) } - fn truncate(&self, len: usize, c: Completion) -> Result> { + fn truncate(&self, len: usize, c: Arc) -> Result> { if len < self.size.get() { // Truncate pages unsafe { @@ -184,7 +184,7 @@ impl File for MemoryFile { } self.size.set(len); c.complete(0); - Ok(Arc::new(c)) + Ok(c) } fn size(&self) -> Result { diff --git a/core/io/unix.rs b/core/io/unix.rs index a98943836..0d388044b 100644 --- a/core/io/unix.rs +++ b/core/io/unix.rs @@ -452,10 +452,9 @@ impl File for UnixFile<'_> { } #[instrument(err, skip_all, level = Level::INFO)] - fn truncate(&self, len: usize, c: Completion) -> Result> { + fn truncate(&self, len: usize, c: Arc) -> Result> { let file = self.file.borrow(); let result = file.set_len(len as u64); - let c = Arc::new(c); match result { Ok(()) => { trace!("file truncated to len=({})", len); diff --git a/core/io/vfs.rs b/core/io/vfs.rs index 50873636e..25a52263a 100644 --- a/core/io/vfs.rs +++ b/core/io/vfs.rs @@ -166,7 +166,7 @@ impl File for VfsFileImpl { } } - fn truncate(&self, len: usize, c: Completion) -> Result> { + fn truncate(&self, len: usize, c: Arc) -> Result> { if self.vfs.is_null() { return Err(LimboError::ExtensionError("VFS is null".to_string())); } @@ -176,7 +176,7 @@ impl File for VfsFileImpl { Err(LimboError::ExtensionError("truncate failed".to_string())) } else { c.complete(0); - Ok(Arc::new(c)) + Ok(c) } } } diff --git a/core/io/windows.rs b/core/io/windows.rs index 418faf59f..2ae910b9b 100644 --- a/core/io/windows.rs +++ b/core/io/windows.rs @@ -123,11 +123,11 @@ impl File for WindowsFile { } #[instrument(err, skip_all, level = Level::TRACE)] - fn truncate(&self, len: usize, c: Completion) -> Result> { + fn truncate(&self, len: usize, c: Arc) -> Result> { let mut file = self.file.borrow_mut(); file.set_len(len as u64).map_err(LimboError::IOError)?; c.complete(0); - Ok(()) + Ok(c) } fn size(&self) -> Result { diff --git a/core/storage/database.rs b/core/storage/database.rs index 17f17439b..c7560f8fe 100644 --- a/core/storage/database.rs +++ b/core/storage/database.rs @@ -18,7 +18,7 @@ pub trait DatabaseStorage: Send + Sync { ) -> Result; fn sync(&self, c: Completion) -> Result; fn size(&self) -> Result; - fn truncate(&self, len: usize, c: Completion) -> Result<()>; + fn truncate(&self, len: usize, c: Arc) -> Result<()>; } #[cfg(feature = "fs")] @@ -72,7 +72,7 @@ impl DatabaseStorage for DatabaseFile { } #[instrument(skip_all, level = Level::INFO)] - fn truncate(&self, len: usize, c: Completion) -> Result<()> { + fn truncate(&self, len: usize, c: Arc) -> Result<()> { self.file.truncate(len, c)?; Ok(()) } @@ -131,7 +131,7 @@ impl DatabaseStorage for FileMemoryStorage { } #[instrument(skip_all, level = Level::INFO)] - fn truncate(&self, len: usize, c: Completion) -> Result<()> { + fn truncate(&self, len: usize, c: Arc) -> Result<()> { let _ = self.file.truncate(len, c)?; Ok(()) } diff --git a/core/storage/wal.rs b/core/storage/wal.rs index e1cea6635..9cb997f9f 100644 --- a/core/storage/wal.rs +++ b/core/storage/wal.rs @@ -17,7 +17,7 @@ use std::{ }; use crate::fast_lock::SpinLock; -use crate::io::{CompletionType, File, IO}; +use crate::io::{File, IO}; use crate::result::LimboResult; use crate::storage::sqlite3_ondisk::{ begin_read_wal_frame, begin_read_wal_frame_raw, finish_read_page, prepare_wal_frame, @@ -1345,10 +1345,7 @@ impl WalFileShared { #[cfg(test)] pub mod test { - use crate::{ - storage::sqlite3_ondisk::WAL_HEADER_SIZE, Completion, CompletionType, Database, MemoryIO, - IO, - }; + use crate::{storage::sqlite3_ondisk::WAL_HEADER_SIZE, Completion, Database, MemoryIO, IO}; use std::{cell::Cell, rc::Rc, sync::Arc}; use tempfile::TempDir; @@ -1380,12 +1377,10 @@ pub mod test { let _done = done.clone(); let _ = file.file.truncate( WAL_HEADER_SIZE, - Completion::new(CompletionType::Truncate( - crate::io::TruncateCompletion::new(Box::new(move |_| { - let done = _done.clone(); - done.set(true); - })), - )), + Arc::new(Completion::new_trunc(move |_| { + let done = _done.clone(); + done.set(true); + })), ); assert!(file.file.size().unwrap() == WAL_HEADER_SIZE as u64); assert!(done.get()); diff --git a/simulator/runner/file.rs b/simulator/runner/file.rs index f78ae3287..928b51d5a 100644 --- a/simulator/runner/file.rs +++ b/simulator/runner/file.rs @@ -229,33 +229,24 @@ impl File for SimulatorFile { fn truncate( &self, len: usize, - mut c: turso_core::Completion, + c: Arc, ) -> Result> { if self.fault.get() { return Err(turso_core::LimboError::InternalError( FAULT_ERROR_MSG.into(), )); } - if let Some(latency) = self.generate_latency_duration() { - let CompletionType::Truncate(truncate_completion) = &mut c.completion_type else { - unreachable!(); - }; - let before = self.rng.borrow_mut().gen_bool(0.5); - let dummy_complete = Box::new(|_| {}); - let prev_complete = - std::mem::replace(&mut truncate_completion.complete, dummy_complete); - let new_complete = move |res| { - if before { - std::thread::sleep(latency); - } - (prev_complete)(res); - if !before { - std::thread::sleep(latency); - } - }; - truncate_completion.complete = Box::new(new_complete); + let c = if let Some(latency) = self.generate_latency_duration() { + let cloned_c = c.clone(); + let op = Box::new(move |file: &SimulatorFile| file.inner.truncate(len, cloned_c)); + self.queued_io + .borrow_mut() + .push(DelayedIo { time: latency, op }); + c + } else { + self.inner.truncate(len, c)? }; - self.inner.truncate(len, c) + Ok(c) } }