diff --git a/src/datastructures/mod.rs b/src/datastructures/mod.rs index 62b2434..0637479 100644 --- a/src/datastructures/mod.rs +++ b/src/datastructures/mod.rs @@ -1,3 +1,4 @@ pub mod btree; pub mod queue; pub mod string; +pub mod vector; diff --git a/src/datastructures/string.rs b/src/datastructures/string.rs index 530ccb3..f8105db 100644 --- a/src/datastructures/string.rs +++ b/src/datastructures/string.rs @@ -4,39 +4,31 @@ use crate::{ transaction, FilePointer, FileRange, RawFilePointer, ReaderTrait, TransactionHandle, U64, }; +use super::vector::Vector; + #[derive(Clone, Copy, FromBytes, FromZeroes, AsBytes, Unaligned)] #[repr(transparent)] -pub struct Str { - data: FileRange, -} +pub struct Str(Vector); impl Str { - fn new() -> Self { - Self { - data: RawFilePointer::null().range(0), - } + pub fn new() -> Self { + Self(Vector::new()) + } +} + +impl Default for Str { + fn default() -> Self { + Self::new() } } impl Str { pub fn set(self, transaction: &mut TransactionHandle, s: &str) -> Self { - let data = if s.is_empty() { - Str::new().data - } else { - let (range, data) = transaction.allocate_range(s.len() as u64); - data.copy_from_slice(s.as_bytes()); - range - }; - - if self.data.len() != 0 { - transaction.free_range(self.data); - } - - Str { data } + Self(self.0.set(transaction, s.as_bytes())) } pub fn get(self, reader: &impl ReaderTrait) -> &str { - std::str::from_utf8(reader.read_raw(self.data)).unwrap() + std::str::from_utf8(self.0.get(reader)).unwrap() } } diff --git a/src/datastructures/vector.rs b/src/datastructures/vector.rs new file mode 100644 index 0000000..6b4fd0f --- /dev/null +++ b/src/datastructures/vector.rs @@ -0,0 +1,60 @@ +use zerocopy::{AsBytes, FromBytes, FromZeroes, Unaligned}; + +use crate::{ + transaction, FilePointer, FileRange, RawFilePointer, ReaderTrait, TransactionHandle, U64, +}; + +#[derive(Clone, Copy, FromBytes, FromZeroes, AsBytes, Unaligned)] +#[repr(transparent)] +pub struct Vector { + data: FileRange, +} + +impl Vector { + pub fn new() -> Self { + Self { + data: RawFilePointer::null().range(0), + } + } +} + +impl Default for Vector { + fn default() -> Self { + Self::new() + } +} + +impl Vector { + pub fn set(self, transaction: &mut TransactionHandle, s: &[u8]) -> Self { + let data = if s.is_empty() { + Vector::new().data + } else { + let (range, data) = transaction.allocate_range(s.len() as u64); + data.copy_from_slice(s.as_bytes()); + range + }; + + if self.data.len() != 0 { + transaction.free_range(self.data); + } + + Vector { data } + } + + pub fn get(self, reader: &impl ReaderTrait) -> &[u8] { + reader.read_raw(self.data) + } +} + +impl FilePointer { + pub fn set(self, transaction: &mut TransactionHandle, s: &[u8]) -> FilePointer { + let new_str = transaction.read::(self).set(transaction, s); + let (ptr, data) = transaction.modify(self); + *data = new_str; + ptr + } + + pub fn get(self, reader: &impl ReaderTrait) -> &[u8] { + reader.read(self).get(reader) + } +}