diff --git a/storage_engine/src/error.rs b/storage_engine/src/error.rs index 7c213f3..898be3a 100644 --- a/storage_engine/src/error.rs +++ b/storage_engine/src/error.rs @@ -10,6 +10,7 @@ pub enum Error { pub enum DecodeErrorKind { StoreHeaderNumberOfColumns, StoreHeaderDeletedCount, + StoreHeaderTotalCount, EntryData, EntryIsDeleted, EntryDataSize diff --git a/storage_engine/src/main.rs b/storage_engine/src/main.rs index ac6fa88..6518649 100644 --- a/storage_engine/src/main.rs +++ b/storage_engine/src/main.rs @@ -77,14 +77,14 @@ async fn main() -> Result<()> { // let entry0: Entry = Entry::new(vec![99, 98, 97, 96, 95]); // append_entry(&mut store, &entry0).await?; - store.read_entries(4).await.map_err(|e| e.to_io_or_panic())?; - + store.read_entries(3).await.map_err(|e| e.to_io_or_panic())?; // let entry2: StoreEntry = StoreEntry::new_deleted(vec![3, 2, 1]); // let cursor2 = store.append_entry(&entry2).await.map_err(|e| e.to_io_or_panic())?; // println!("cursor2 = {}", cursor2); - // println!("{:?}", store); + + println!("{:?}", store); println!("DONE"); diff --git a/storage_engine/src/storage_engine.rs b/storage_engine/src/storage_engine.rs index d947d14..9e12041 100644 --- a/storage_engine/src/storage_engine.rs +++ b/storage_engine/src/storage_engine.rs @@ -36,11 +36,17 @@ pub struct Store { pub struct StoreHeader { number_of_columns: usize, deleted_count: usize, + total_count: usize, } impl StoreHeader { const NUMBER_OF_COLUMNS_SIZE: usize = size_of::(); const DELETED_COUNT_SIZE: usize = size_of::(); - const SIZE: usize = Self::NUMBER_OF_COLUMNS_SIZE + Self::DELETED_COUNT_SIZE; + const TOTAL_COUNT_SIZE: usize = size_of::(); + const SIZE: usize = Self::NUMBER_OF_COLUMNS_SIZE + Self::DELETED_COUNT_SIZE + Self::TOTAL_COUNT_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; } #[derive(Debug)] @@ -153,6 +159,7 @@ impl Store { let header = StoreHeader { number_of_columns, deleted_count: 0, + total_count: 0, }; let encoded_header: Vec = header.encode()?; @@ -192,17 +199,46 @@ impl Store { } // ===Append Entry=== + async fn increment_total_count(&mut self) -> Result<()> { + self.seek_to_start().await?; + self.seek_to(StoreHeader::TOTAL_COUNT_OFFSET as u64).await?; + let new_count = self.header.increment_total_count(); + self.write_bytes(&encode::(&new_count)?).await?; + Ok(()) + } + + async fn increment_deleted_count(&mut self) -> Result<()> { + self.seek_to_start().await?; + self.seek_to(StoreHeader::DELETED_COUNT_OFFSET as u64).await?; + let new_count = self.header.increment_deleted_count(); + self.write_bytes(&encode::(&new_count)?).await?; + Ok(()) + } + // Moves cursor to the end. pub async fn append_entry(&mut self, entry: &Entry) -> Result where T: Encode { + self.increment_total_count().await?; + let encoded_entry: Vec = entry.encode()?; self.seek_to_end().await?; let cursor: Cursor = self.current_cursor().await?; self.write_bytes(&encoded_entry).await?; + Ok(cursor) } + // ===Deletion=== + pub async fn mark_deleted_at(&mut self, cursor: Cursor) -> Result<()> { + self.increment_deleted_count().await?; + + self.seek_to(cursor).await?; + + // TODO: Now you need to mutate the entry itself + todo!() + } + // ===Lookup=== // WARNING: The cursor has to be at the start of an entry. Otherwise garbage data will be @@ -266,6 +302,7 @@ impl StoreHeader { // FORMAT: First Number of Columns, Then Deleted Count. let mut result = encode(&self.number_of_columns)?; result.append(&mut encode(&self.deleted_count)?); + result.append(&mut encode(&self.total_count)?); Ok(result) } @@ -274,20 +311,35 @@ impl StoreHeader { } async fn decode(result: &mut [u8]) -> Result { - let offset = 0; - let (number_of_columns, offset) = - decode::(&result[offset..offset + Self::NUMBER_OF_COLUMNS_SIZE]) + let (number_of_columns, _) = + decode::(&result[Self::NUMBER_OF_COLUMNS_OFFSET..Self::NUMBER_OF_COLUMNS_OFFSET + Self::NUMBER_OF_COLUMNS_SIZE]) .map_err(|e| Error::DecodeError(DecodeErrorKind::StoreHeaderNumberOfColumns, e))?; let (deleted_count, _) = - decode::(&result[offset..offset + Self::DELETED_COUNT_SIZE]) + decode::(&result[Self::DELETED_COUNT_OFFSET..Self::DELETED_COUNT_OFFSET + Self::DELETED_COUNT_SIZE]) .map_err(|e| Error::DecodeError(DecodeErrorKind::StoreHeaderDeletedCount, e))?; + let (total_count, _offset) = + decode::(&result[Self::TOTAL_COUNT_OFFSET..Self::TOTAL_COUNT_OFFSET + Self::TOTAL_COUNT_SIZE]) + .map_err(|e| Error::DecodeError(DecodeErrorKind::StoreHeaderTotalCount, e))?; let header = StoreHeader { number_of_columns, deleted_count, + total_count, }; Ok(header) } + + // returns new count + fn increment_total_count(&mut self) -> usize { + self.total_count += 1; + self.total_count + } + + // returns new count + fn increment_deleted_count(&mut self) -> usize { + self.deleted_count += 1; + self.deleted_count + } } // ====Entry====