Skip to content

Commit

Permalink
refactor: introduce RandomAccessFile trait
Browse files Browse the repository at this point in the history
introduce RandomAccessFile trait in order to create mmap implementation of it for readonly operations

Find more: Fullstop000#84
  • Loading branch information
khlopkov committed Nov 3, 2024
1 parent b8e4c6f commit e9a3a06
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 8 deletions.
18 changes: 11 additions & 7 deletions src/sstable/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use crate::options::{CompressionType, Options, ReadOptions};
use crate::sstable::block::{Block, BlockBuilder, BlockIterator};
use crate::sstable::filter_block::{FilterBlockBuilder, FilterBlockReader};
use crate::sstable::{BlockHandle, Footer, BLOCK_TRAILER_SIZE, FOOTER_ENCODED_LENGTH};
use crate::storage::File;
use crate::storage::{File, RandomAccessFile};
use crate::util::coding::{decode_fixed_32, put_fixed_32, put_fixed_64};
use crate::util::comparator::Comparator;
use crate::util::crc32::{extend, hash, mask, unmask};
Expand All @@ -34,7 +34,7 @@ use std::sync::Arc;
/// A `Table` is a sorted map from strings to strings, which must be immutable and persistent.
/// A `Table` may be safely accessed from multiple threads
/// without external synchronization.
pub struct Table<F: File> {
pub struct Table<F: RandomAccessFile> {
file: F,
file_number: u64,
filter_reader: Option<FilterBlockReader>,
Expand All @@ -43,7 +43,7 @@ pub struct Table<F: File> {
block_cache: Option<Arc<dyn Cache<Vec<u8>, Arc<Block>>>>,
}

impl<F: File> Table<F> {
impl<F: RandomAccessFile> Table<F> {
/// Attempt to open the table that is stored in bytes `[0..size)`
/// of `file`, and read the metadata entries necessary to allow
/// retrieving data from the table.
Expand Down Expand Up @@ -215,13 +215,13 @@ impl<F: File> Table<F> {
}
}

pub struct TableIterFactory<C: Comparator, F: File> {
pub struct TableIterFactory<C: Comparator, F: RandomAccessFile> {
options: ReadOptions,
table: Arc<Table<F>>,
cmp: C,
}

impl<C: Comparator, F: File> DerivedIterFactory for TableIterFactory<C, F> {
impl<C: Comparator, F: RandomAccessFile> DerivedIterFactory for TableIterFactory<C, F> {
type Iter = BlockIterator<C>;
fn derive(&self, value: &[u8]) -> Result<Self::Iter> {
BlockHandle::decode_from(value).and_then(|(handle, _)| {
Expand All @@ -239,7 +239,7 @@ pub type TableIterator<C, F> = ConcatenateIterator<BlockIterator<C>, TableIterFa
/// Entry format:
/// key: internal key
/// value: value of user key
pub fn new_table_iterator<C: Comparator, F: File>(
pub fn new_table_iterator<C: Comparator, F: RandomAccessFile>(
cmp: C,
table: Arc<Table<F>>,
options: ReadOptions,
Expand Down Expand Up @@ -567,7 +567,11 @@ fn write_raw_block<F: File>(

// Read the block identified from `file` according to the given `handle`.
// If the read data does not match the checksum, return a error marked as `Status::Corruption`
fn read_block<F: File>(file: &F, handle: &BlockHandle, verify_checksum: bool) -> Result<Vec<u8>> {
fn read_block<F: RandomAccessFile>(
file: &F,
handle: &BlockHandle,
verify_checksum: bool,
) -> Result<Vec<u8>> {
let n = handle.size as usize;
// TODO: use pre-allocated buf
let mut buffer = vec![0; n + BLOCK_TRAILER_SIZE];
Expand Down
1 change: 1 addition & 0 deletions src/storage/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ impl File for SysFile {
#[cfg(test)]
mod tests {
use super::*;
use crate::storage::RandomAccessFile;
use std::fs::remove_file;
use std::io::Write;

Expand Down
8 changes: 7 additions & 1 deletion src/storage/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ pub trait Storage: Send + Sync {
}

/// A file abstraction for IO operations
pub trait File: Send + Sync {
pub trait File: RandomAccessFile + Send + Sync {
fn write(&mut self, buf: &[u8]) -> Result<usize>;
fn flush(&mut self) -> Result<()>;
fn close(&mut self) -> Result<()>;
Expand Down Expand Up @@ -88,7 +88,13 @@ pub trait File: Send + Sync {
/// See [`Read::read()`](https://doc.rust-lang.org/std/io/trait.Read.html#tymethod.read)
/// for details.
fn read_at(&self, buf: &mut [u8], offset: u64) -> Result<usize>;
}

pub trait RandomAccessFile: Send + Sync {
fn read_exact_at(&self, buf: &mut [u8], offset: u64) -> Result<()>;
}

impl<T: File> RandomAccessFile for T {
/// Reads the exact number of bytes required to fill `buf` from an `offset`.
///
/// Errors if the "EOF" is encountered before filling the buffer.
Expand Down

0 comments on commit e9a3a06

Please sign in to comment.