This commit is contained in:
Yuriy Dupyn 2024-02-05 17:39:38 +01:00
parent 167028a530
commit 84a880f9e6
7 changed files with 133 additions and 77 deletions

View file

@ -13,7 +13,8 @@ use crate::segments::store_header::StoreHeader;
use crate::store::{Store, FilePosition, Column, Result, ROWS_FILE_NAME, GARBAGE_COLLECTION_INTERMEDIATE_ROWS_FILE_NAME};
use crate::index::Index;
use crate::cursor_capabilities::primitive::{CursorCanRead, CursorCanWrite};
use crate::cursor_capabilities::header_access::{CursorCanReadHeader, CursorCanWriteHeader};
use crate::cursor_capabilities::traversal::CursorCanTraverse;
use crate::cursor_capabilities::entry_modification::CursorCanModifyEntries;
use crate::cursor_capabilities::index_access::{CursorCanWriteToIndex, CursorCanReadIndex};
const GARBAGE_COLLECTION_TRIGGER: usize = 100;
@ -82,24 +83,24 @@ impl <T>CursorCanWrite<T> for AppendOnlyCursor<T> {}
// ===capability to access header===
impl <T>CursorCanReadHeader<T> for ReadCursor<'_, T> {
impl <T>CursorCanTraverse<T> for ReadCursor<'_, T> {
fn header(&self) -> &StoreHeader { &self.header }
}
impl <T>CursorCanReadHeader<T> for WriteCursor<'_, T> {
impl <T>CursorCanTraverse<T> for WriteCursor<'_, T> {
fn header(&self) -> &StoreHeader { &self.header }
}
impl <T>CursorCanReadHeader<T> for AppendOnlyCursor<T> {
impl <T>CursorCanTraverse<T> for AppendOnlyCursor<T> {
fn header(&self) -> &StoreHeader { &self.header }
}
impl <T>CursorCanWriteHeader<T> for WriteCursor<'_, T> {
impl <T>CursorCanModifyEntries<T> for WriteCursor<'_, T> {
fn header_mut(&mut self) -> &mut StoreHeader { self.header }
fn set_eof_file_position(&mut self, new_file_position: FilePosition) { self.eof_file_position = new_file_position }
}
impl <T>CursorCanWriteHeader<T> for AppendOnlyCursor<T> {
impl <T>CursorCanModifyEntries<T> for AppendOnlyCursor<T> {
fn header_mut(&mut self) -> &mut StoreHeader { &mut self.header }
fn set_eof_file_position(&mut self, new_file_position: FilePosition) { self.eof_file_position = new_file_position }
}

View file

@ -0,0 +1,67 @@
use async_trait::async_trait;
use bincode;
use bincode::Encode;
use crate::binary_coding::encode;
use crate::segments::entry::Entry;
use crate::segments::store_header::StoreHeader;
use crate::store::{FilePosition, Result};
use crate::cursor_capabilities::primitive::{CursorCanRead, CursorCanWrite};
use crate::cursor_capabilities::traversal::CursorCanTraverse;
#[async_trait]
pub trait CursorCanModifyEntries<T>: CursorCanTraverse<T> + CursorCanWrite<T> {
fn header_mut(&mut self) -> &mut StoreHeader;
fn set_eof_file_position(&mut self, new_file_position: FilePosition);
// ===Store Header Manipulation===
async fn increment_total_count(&mut self) -> Result<()>
where T: Send
{
self.seek_to_start().await?;
self.seek_to(StoreHeader::TOTAL_COUNT_OFFSET as u64).await?;
let new_count = self.header_mut().increment_total_count();
self.write_bytes(&encode::<usize>(&new_count)?).await?;
Ok(())
}
async fn increment_deleted_count(&mut self) -> Result<()>
where T: Send
{
self.seek_to_start().await?;
self.seek_to(StoreHeader::DELETED_COUNT_OFFSET as u64).await?;
let new_count = self.header_mut().increment_deleted_count();
self.write_bytes(&encode::<usize>(&new_count)?).await?;
Ok(())
}
async fn set_header(&mut self, header: &StoreHeader) -> Result<()>
where T: Send
{
self.seek_to_start().await?;
let encoded_header: Vec<u8> = header.encode()?;
self.write_bytes(&encoded_header).await?;
Ok(())
}
// ===Append Entry===
// Moves cursor to the end.
// Returns file position to the start of the new entry.
async fn append_entry_no_indexing(&mut self, entry: &Entry<T>) -> Result<FilePosition>
where T: Encode + Send + Sync
{
self.increment_total_count().await?;
let encoded_entry: Vec<u8> = entry.encode()?;
let file_position = self.seek_to_end().await?;
self.write_bytes(&encoded_entry).await?;
let eof_file_position: FilePosition = self.current_file_position().await?;
self.set_eof_file_position(eof_file_position);
Ok(file_position)
}
}

View file

@ -9,10 +9,11 @@ use crate::error::Error;
use crate::segments::entry::{Entry, EntryDetailed};
use crate::store::{FilePosition, Column, Result};
use crate::index::Index;
use crate::cursor_capabilities::header_access::{CursorCanReadHeader, CursorCanWriteHeader};
use crate::cursor_capabilities::traversal::CursorCanTraverse;
use crate::cursor_capabilities::entry_modification::CursorCanModifyEntries;
#[async_trait]
pub trait CursorCanReadIndex<T>: CursorCanReadHeader<T> {
pub trait CursorCanReadIndex<T>: CursorCanTraverse<T> {
fn indexes(&mut self) -> &[Option<Index<T, FilePosition>>];
async fn index_lookup(&mut self, column: Column, value: &T) -> Result<Vec<EntryDetailed<T>>>
@ -52,7 +53,7 @@ pub trait CursorCanReadIndex<T>: CursorCanReadHeader<T> {
}
#[async_trait]
pub trait CursorCanWriteToIndex<T>: CursorCanReadIndex<T> + CursorCanWriteHeader<T> {
pub trait CursorCanWriteToIndex<T>: CursorCanReadIndex<T> + CursorCanModifyEntries<T> {
fn indexes_mut(&mut self) -> &mut [Option<Index<T, FilePosition>>];
// Assumes that the column is indexable.

View file

@ -1,3 +1,4 @@
pub(crate) mod primitive;
pub(crate) mod header_access;
pub(crate) mod traversal;
pub(crate) mod entry_modification;
pub(crate) mod index_access;

View file

@ -2,18 +2,19 @@ use tokio::io::AsyncReadExt;
use async_trait::async_trait;
use bincode;
use bincode::{Decode, Encode};
use crate::binary_coding::{encode, decode};
use bincode::Decode;
use crate::binary_coding::decode;
use crate::error::{Error, DecodeErrorKind};
use crate::segments::entry::{Entry, EntryDetailed};
use crate::segments::entry::EntryDetailed;
use crate::segments::entry_header::EntryHeaderWithDataSize;
use crate::segments::store_header::StoreHeader;
use crate::store::{FilePosition, Column, Result};
use crate::cursor_capabilities::primitive::{CursorCanRead, CursorCanWrite};
use crate::cursor_capabilities::primitive::CursorCanRead;
#[async_trait]
pub trait CursorCanReadHeader<T>: CursorCanRead<T> {
pub trait CursorCanTraverse<T>: CursorCanRead<T> {
fn header(&self) -> &StoreHeader;
async fn seek_to_start_of_data(&mut self) -> Result<FilePosition> {
@ -172,59 +173,3 @@ pub trait CursorCanReadHeader<T>: CursorCanRead<T> {
Ok(bytes)
}
}
#[async_trait]
pub trait CursorCanWriteHeader<T>: CursorCanReadHeader<T> + CursorCanWrite<T> {
fn header_mut(&mut self) -> &mut StoreHeader;
fn set_eof_file_position(&mut self, new_file_position: FilePosition);
// ===Store Header Manipulation===
async fn increment_total_count(&mut self) -> Result<()>
where T: Send
{
self.seek_to_start().await?;
self.seek_to(StoreHeader::TOTAL_COUNT_OFFSET as u64).await?;
let new_count = self.header_mut().increment_total_count();
self.write_bytes(&encode::<usize>(&new_count)?).await?;
Ok(())
}
async fn increment_deleted_count(&mut self) -> Result<()>
where T: Send
{
self.seek_to_start().await?;
self.seek_to(StoreHeader::DELETED_COUNT_OFFSET as u64).await?;
let new_count = self.header_mut().increment_deleted_count();
self.write_bytes(&encode::<usize>(&new_count)?).await?;
Ok(())
}
async fn set_header(&mut self, header: &StoreHeader) -> Result<()>
where T: Send
{
self.seek_to_start().await?;
let encoded_header: Vec<u8> = header.encode()?;
self.write_bytes(&encoded_header).await?;
Ok(())
}
// ===Append Entry===
// Moves cursor to the end.
// Returns file position to the start of the new entry.
async fn append_entry_no_indexing(&mut self, entry: &Entry<T>) -> Result<FilePosition>
where T: Encode + Send + Sync
{
self.increment_total_count().await?;
let encoded_entry: Vec<u8> = entry.encode()?;
let file_position = self.seek_to_end().await?;
self.write_bytes(&encoded_entry).await?;
let eof_file_position: FilePosition = self.current_file_position().await?;
self.set_eof_file_position(eof_file_position);
Ok(file_position)
}
}

View file

@ -6,7 +6,7 @@ use bincode::{Decode, Encode};
use crate::error::Error;
use crate::cursor::{ReadCursor, WriteCursor};
use crate::cursor_capabilities::header_access::CursorCanReadHeader;
use crate::cursor_capabilities::traversal::CursorCanTraverse;
use crate::segments::store_header::StoreHeader;
use crate::index::Index;
@ -208,8 +208,8 @@ impl <T>Store<T> {
mod tests {
use super::*;
use crate::segments::entry::Entry;
use crate::cursor_capabilities::header_access::CursorCanReadHeader;
use crate::cursor_capabilities::index_access::{CursorCanWriteToIndex, CursorCanReadIndex};
use crate::cursor_capabilities::traversal::CursorCanTraverse;
impl <T>Drop for Store<T> {
fn drop(&mut self) {