From 97185bfefc4984da392e9126df8a5b641aae7720 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Sat, 30 Sep 2023 19:20:48 +0300 Subject: [PATCH] Pin buffer into memory Make sure the buffer is pinned into memory for I/O. --- core/buffer_pool.rs | 2 +- core/io/darwin.rs | 2 +- core/io/mod.rs | 33 ++++++++++++++++++++++++++++++++- core/sqlite3_ondisk.rs | 4 +++- 4 files changed, 37 insertions(+), 4 deletions(-) diff --git a/core/buffer_pool.rs b/core/buffer_pool.rs index 7ce6a94b4..2fb83c476 100644 --- a/core/buffer_pool.rs +++ b/core/buffer_pool.rs @@ -19,7 +19,7 @@ impl BufferPool { if let Some(buffer) = free_buffers.pop() { Buffer::new(self, buffer) } else { - let raw_buffer = vec![0; self.page_size]; + let raw_buffer = IoBuffer::allocate(self.page_size); Buffer::new(self, raw_buffer) } } diff --git a/core/io/darwin.rs b/core/io/darwin.rs index b6b7f9832..64ecc1369 100644 --- a/core/io/darwin.rs +++ b/core/io/darwin.rs @@ -30,7 +30,7 @@ impl File { pub fn pread(&self, pos: usize, buf: &mut Buffer) -> Result<()> { let mut file = self.file.borrow_mut(); file.seek(std::io::SeekFrom::Start(pos as u64))?; - file.read_exact(buf)?; + file.read_exact(buf.as_mut_slice())?; Ok(()) } } \ No newline at end of file diff --git a/core/io/mod.rs b/core/io/mod.rs index f3b9ed620..aaa0ea65b 100644 --- a/core/io/mod.rs +++ b/core/io/mod.rs @@ -1,6 +1,37 @@ use cfg_block::cfg_block; +use std::pin::Pin; -pub type Buffer = Vec; +pub struct Buffer { + data: Pin>, +} + +impl Buffer { + pub fn allocate(size: usize) -> Self { + Self { + data: Pin::new(vec![0; size]), + } + } + + pub fn len(&self) -> usize { + self.data.len() + } + + pub fn as_slice(&self) -> &[u8] { + &self.data + } + + pub fn as_mut_slice(&mut self) -> &mut [u8] { + &mut self.data + } + + pub fn as_ptr(&self) -> *const u8 { + self.data.as_ptr() + } + + pub fn as_mut_ptr(&mut self) -> *mut u8 { + self.data.as_mut_ptr() + } +} cfg_block! { #[cfg(target_os = "linux")] { diff --git a/core/sqlite3_ondisk.rs b/core/sqlite3_ondisk.rs index a238c7353..74170496b 100644 --- a/core/sqlite3_ondisk.rs +++ b/core/sqlite3_ondisk.rs @@ -60,8 +60,9 @@ pub struct DatabaseHeader { } pub fn read_database_header(storage: &Storage) -> Result { - let mut buf = vec![0; 512]; + let mut buf = crate::Buffer::allocate(512); storage.get(1, &mut buf)?; + let buf = buf.as_slice(); let mut header = DatabaseHeader::default(); header.magic.copy_from_slice(&buf[0..16]); header.page_size = u16::from_be_bytes([buf[16], buf[17]]); @@ -141,6 +142,7 @@ pub fn read_btree_page( } else { 0 }; + let page = page.as_slice(); let mut header = BTreePageHeader { page_type: page[pos].try_into()?, _first_freeblock_offset: u16::from_be_bytes([page[pos + 1], page[pos + 2]]),