diff --git a/pageserver/src/tenant/block_io.rs b/pageserver/src/tenant/block_io.rs index 7f8da5fc12..a15f77c7de 100644 --- a/pageserver/src/tenant/block_io.rs +++ b/pageserver/src/tenant/block_io.rs @@ -150,53 +150,59 @@ pub struct FileBlockReader { file_id: page_cache::FileId, } -impl FileBlockReader -where - F: FileExt, -{ +impl FileBlockReader { pub fn new(file: F) -> Self { let file_id = page_cache::next_file_id(); FileBlockReader { file_id, file } } - - /// Read a page from the underlying file into given buffer. - fn fill_buffer(&self, buf: &mut [u8], blkno: u32) -> Result<(), std::io::Error> { - assert!(buf.len() == PAGE_SZ); - self.file.read_exact_at(buf, blkno as u64 * PAGE_SZ as u64) - } - /// Read a block. - /// - /// Returns a "lease" object that can be used to - /// access to the contents of the page. (For the page cache, the - /// lease object represents a lock on the buffer.) - pub async fn read_blk(&self, blknum: u32) -> Result { - // Look up the right page - let cache = page_cache::get(); - loop { - match cache - .read_immutable_buf(self.file_id, blknum) - .await - .map_err(|e| { - std::io::Error::new( - std::io::ErrorKind::Other, - format!("Failed to read immutable buf: {e:#}"), - ) - })? { - ReadBufResult::Found(guard) => break Ok(guard.into()), - ReadBufResult::NotFound(mut write_guard) => { - // Read the page from disk into the buffer - self.fill_buffer(write_guard.deref_mut(), blknum)?; - write_guard.mark_valid(); - - // Swap for read lock - continue; - } - }; - } - } } +macro_rules! impls { + (FileBlockReader<$ty:ty>) => { + impl FileBlockReader<$ty> { + /// Read a page from the underlying file into given buffer. + fn fill_buffer(&self, buf: &mut [u8], blkno: u32) -> Result<(), std::io::Error> { + assert!(buf.len() == PAGE_SZ); + self.file.read_exact_at(buf, blkno as u64 * PAGE_SZ as u64) + } + /// Read a block. + /// + /// Returns a "lease" object that can be used to + /// access to the contents of the page. (For the page cache, the + /// lease object represents a lock on the buffer.) + pub async fn read_blk(&self, blknum: u32) -> Result { + // Look up the right page + let cache = page_cache::get(); + loop { + match cache + .read_immutable_buf(self.file_id, blknum) + .await + .map_err(|e| { + std::io::Error::new( + std::io::ErrorKind::Other, + format!("Failed to read immutable buf: {e:#}"), + ) + })? { + ReadBufResult::Found(guard) => break Ok(guard.into()), + ReadBufResult::NotFound(mut write_guard) => { + // Read the page from disk into the buffer + self.fill_buffer(write_guard.deref_mut(), blknum)?; + write_guard.mark_valid(); + + // Swap for read lock + continue; + } + }; + } + } + } + }; +} + +impls!(FileBlockReader); +impls!(FileBlockReader); + impl BlockReader for FileBlockReader { fn block_cursor(&self) -> BlockCursor<'_> { BlockCursor::new(BlockReaderRef::FileBlockReaderFile(self))