Split Cursor into ReadCursor and WriteCursor
This commit is contained in:
parent
53aa5a0127
commit
a37c3a5e77
4 changed files with 334 additions and 40 deletions
|
|
@ -17,7 +17,7 @@ use crate::index::Index;
|
|||
|
||||
use std::mem::size_of;
|
||||
|
||||
type Result<T> = std::result::Result<T, Error>;
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
|
||||
pub type Column = u64;
|
||||
pub type FilePosition = u64;
|
||||
|
|
@ -31,7 +31,7 @@ pub struct Store<T> {
|
|||
// {write: 0, read: n + 1} ~> {write:0, read: n} // destroy read
|
||||
// {write: 0, read: 0} ~> {write: 1, read: 0} // create write
|
||||
// {write: 1, read: 0} ~> {write: 0, read: 0} // destroy write
|
||||
table_folder: String,
|
||||
pub table_folder: String,
|
||||
// primary_index: Vec<Index<T, FilePosition>>>,
|
||||
// indexes: Vec<Option<Index<T, HashSet<FilePosition>>>>,
|
||||
// primary_index: Index<PositionOfValue, PositionOfRow>,
|
||||
|
|
@ -39,8 +39,8 @@ pub struct Store<T> {
|
|||
// TODO: It's not good to have StoreHeader copied to all the cursors, since they may modify it.
|
||||
// How to sync?
|
||||
// All
|
||||
header: StoreHeader,
|
||||
data_type: PhantomData<T>,
|
||||
pub header: StoreHeader,
|
||||
pub data_type: PhantomData<T>,
|
||||
|
||||
// meta
|
||||
// location of rows file
|
||||
|
|
@ -61,14 +61,6 @@ pub struct Cursor<T> {
|
|||
eof_file_position: FilePosition,
|
||||
}
|
||||
|
||||
pub struct WriteCursor<'a, T> {
|
||||
header: &'a mut StoreHeader,
|
||||
file: File,
|
||||
data_type: PhantomData<T>,
|
||||
|
||||
eof_file_position: FilePosition,
|
||||
}
|
||||
|
||||
pub enum AccessMode {
|
||||
Read,
|
||||
Write
|
||||
|
|
@ -80,22 +72,22 @@ pub type PositionOfRow = FilePosition;
|
|||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct StoreHeader {
|
||||
number_of_columns: usize,
|
||||
deleted_count: usize,
|
||||
total_count: usize,
|
||||
primary_column: Column,
|
||||
pub number_of_columns: usize,
|
||||
pub deleted_count: usize,
|
||||
pub total_count: usize,
|
||||
pub primary_column: Column,
|
||||
}
|
||||
impl StoreHeader {
|
||||
const NUMBER_OF_COLUMNS_SIZE: usize = size_of::<usize>();
|
||||
const DELETED_COUNT_SIZE: usize = size_of::<usize>();
|
||||
const TOTAL_COUNT_SIZE: usize = size_of::<usize>();
|
||||
const PRIMARY_COLUMN_SIZE: usize = size_of::<Column>();
|
||||
const SIZE: usize = Self::NUMBER_OF_COLUMNS_SIZE + Self::DELETED_COUNT_SIZE + Self::TOTAL_COUNT_SIZE + Self::PRIMARY_COLUMN_SIZE;
|
||||
pub const NUMBER_OF_COLUMNS_SIZE: usize = size_of::<usize>();
|
||||
pub const DELETED_COUNT_SIZE: usize = size_of::<usize>();
|
||||
pub const TOTAL_COUNT_SIZE: usize = size_of::<usize>();
|
||||
pub const PRIMARY_COLUMN_SIZE: usize = size_of::<Column>();
|
||||
pub const SIZE: usize = Self::NUMBER_OF_COLUMNS_SIZE + Self::DELETED_COUNT_SIZE + Self::TOTAL_COUNT_SIZE + Self::PRIMARY_COLUMN_SIZE;
|
||||
|
||||
const NUMBER_OF_COLUMNS_OFFSET: usize = 0;
|
||||
const DELETED_COUNT_OFFSET: usize = Self::NUMBER_OF_COLUMNS_OFFSET + Self::NUMBER_OF_COLUMNS_SIZE;
|
||||
const TOTAL_COUNT_OFFSET: usize = Self::DELETED_COUNT_OFFSET + Self::DELETED_COUNT_SIZE;
|
||||
const PRIMARY_COLUMN_OFFSET: usize = Self::TOTAL_COUNT_OFFSET + Self::TOTAL_COUNT_SIZE;
|
||||
pub const NUMBER_OF_COLUMNS_OFFSET: usize = 0;
|
||||
pub const DELETED_COUNT_OFFSET: usize = Self::NUMBER_OF_COLUMNS_OFFSET + Self::NUMBER_OF_COLUMNS_SIZE;
|
||||
pub const TOTAL_COUNT_OFFSET: usize = Self::DELETED_COUNT_OFFSET + Self::DELETED_COUNT_SIZE;
|
||||
pub const PRIMARY_COLUMN_OFFSET: usize = Self::TOTAL_COUNT_OFFSET + Self::TOTAL_COUNT_SIZE;
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
@ -105,21 +97,21 @@ pub struct EntryHeader {
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct EntryHeaderWithDataSize {
|
||||
is_deleted: bool,
|
||||
data_sizes: Vec<usize>, // vec![5, 6, 20] means that column 0 stores 5 bytes, column 1 stores 6
|
||||
pub is_deleted: bool,
|
||||
pub data_sizes: Vec<usize>, // vec![5, 6, 20] means that column 0 stores 5 bytes, column 1 stores 6
|
||||
// bytes etc
|
||||
}
|
||||
impl EntryHeaderWithDataSize {
|
||||
const IS_DELETED_OFFSET: usize = 0;
|
||||
const IS_DELETED_SIZE: usize = size_of::<bool>();
|
||||
const DATA_SIZES_OFFSET: usize = Self::IS_DELETED_OFFSET + Self::IS_DELETED_SIZE;
|
||||
pub const IS_DELETED_OFFSET: usize = 0;
|
||||
pub const IS_DELETED_SIZE: usize = size_of::<bool>();
|
||||
pub const DATA_SIZES_OFFSET: usize = Self::IS_DELETED_OFFSET + Self::IS_DELETED_SIZE;
|
||||
|
||||
fn size(number_of_columns: usize) -> usize {
|
||||
pub fn size(number_of_columns: usize) -> usize {
|
||||
let size_of_data_sizes: usize = number_of_columns*size_of::<usize>();
|
||||
Self::IS_DELETED_SIZE + size_of_data_sizes
|
||||
}
|
||||
|
||||
fn size_of_data(&self) -> usize{
|
||||
pub fn size_of_data(&self) -> usize{
|
||||
self.data_sizes.iter().sum()
|
||||
}
|
||||
}
|
||||
|
|
@ -164,7 +156,7 @@ impl <T>SomethingSupportingLeq for Store<T>
|
|||
}
|
||||
}
|
||||
|
||||
const ROWS_FILE_NAME: &'static str = "rows";
|
||||
pub const ROWS_FILE_NAME: &'static str = "rows";
|
||||
|
||||
impl <T>Store<T> {
|
||||
// For debugging.
|
||||
|
|
@ -289,13 +281,13 @@ impl StoreHeader {
|
|||
}
|
||||
|
||||
// returns new count
|
||||
fn increment_total_count(&mut self) -> usize {
|
||||
pub fn increment_total_count(&mut self) -> usize {
|
||||
self.total_count += 1;
|
||||
self.total_count
|
||||
}
|
||||
|
||||
// returns new count
|
||||
fn increment_deleted_count(&mut self) -> usize {
|
||||
pub fn increment_deleted_count(&mut self) -> usize {
|
||||
self.deleted_count += 1;
|
||||
self.deleted_count
|
||||
}
|
||||
|
|
@ -310,7 +302,7 @@ impl EntryHeader {
|
|||
}
|
||||
|
||||
impl EntryHeaderWithDataSize {
|
||||
fn decode(bytes: &mut [u8], number_of_columns: usize) -> Result<Self> {
|
||||
pub fn decode(bytes: &mut [u8], number_of_columns: usize) -> Result<Self> {
|
||||
let (is_deleted, _) =
|
||||
decode::<bool>(&bytes)
|
||||
.map_err(|e| Error::DecodeError(DecodeErrorKind::EntryIsDeleted, e))?;
|
||||
|
|
@ -332,7 +324,7 @@ impl <T>Entry<T> {
|
|||
}
|
||||
|
||||
// FORMAT: [EntryHeaderWithDataSize, ..sequence of data]
|
||||
fn encode(&self) -> Result<Vec<u8>>
|
||||
pub fn encode(&self) -> Result<Vec<u8>>
|
||||
where T: Encode
|
||||
{
|
||||
let mut result: Vec<u8> = self.header.encode()?;
|
||||
|
|
@ -345,7 +337,7 @@ impl <T>Entry<T> {
|
|||
}
|
||||
|
||||
impl <T>EntryDetailed<T> {
|
||||
fn decode(header: EntryHeaderWithDataSize, number_of_columns: usize, bytes: &[u8]) -> Result<Self>
|
||||
pub fn decode(header: EntryHeaderWithDataSize, number_of_columns: usize, bytes: &[u8]) -> Result<Self>
|
||||
where T: Decode
|
||||
{
|
||||
let data = decode_sequence::<T>(number_of_columns, bytes)
|
||||
|
|
@ -405,7 +397,6 @@ impl <T>Cursor<T> {
|
|||
Ok(result)
|
||||
}
|
||||
|
||||
// TODO: make private
|
||||
pub async fn seek_to(&mut self, file_position: FilePosition) -> Result<()> {
|
||||
self.file.seek(SeekFrom::Start(file_position)).await?;
|
||||
Ok(())
|
||||
|
|
@ -425,7 +416,6 @@ impl <T>Cursor<T> {
|
|||
self.seek_to(StoreHeader::SIZE as u64).await
|
||||
}
|
||||
|
||||
// TODO: Make private
|
||||
pub async fn current_file_position(&mut self) -> Result<FilePosition> {
|
||||
let next_file_position: FilePosition = self.file.stream_position().await?;
|
||||
Ok(next_file_position)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue