diff --git a/crates/dictionary/src/dictionary_data.rs b/crates/dictionary/src/dictionary_data.rs index 1fe40426..0fbee788 100644 --- a/crates/dictionary/src/dictionary_data.rs +++ b/crates/dictionary/src/dictionary_data.rs @@ -1,3 +1,5 @@ +use crate::dictionary_index::DictionaryIndex; + use super::dictionary_value::DictionaryValue; use agdb_db_error::DbError; use agdb_serialize::Serialize; @@ -9,14 +11,18 @@ where { fn capacity(&self) -> u64; fn commit(&mut self) -> Result<(), DbError>; - fn indexes(&self, hash: u64) -> Result, DbError>; - fn insert(&mut self, hash: u64, index: i64) -> Result<(), DbError>; - fn hash(&self, index: i64) -> Result; - fn meta(&self, index: i64) -> Result; - fn remove(&mut self, hash: u64, index: i64) -> Result<(), DbError>; - fn set_hash(&mut self, index: i64, hash: u64) -> Result<(), DbError>; - fn set_meta(&mut self, index: i64, meta: i64) -> Result<(), DbError>; - fn set_value(&mut self, index: i64, value: DictionaryValue) -> Result<(), DbError>; + fn indexes(&self, hash: u64) -> Result, DbError>; + fn insert(&mut self, hash: u64, index: &DictionaryIndex) -> Result<(), DbError>; + fn hash(&self, index: &DictionaryIndex) -> Result; + fn meta(&self, index: &DictionaryIndex) -> Result; + fn remove(&mut self, hash: u64, index: &DictionaryIndex) -> Result<(), DbError>; + fn set_hash(&mut self, index: &DictionaryIndex, hash: u64) -> Result<(), DbError>; + fn set_meta(&mut self, index: &DictionaryIndex, meta: i64) -> Result<(), DbError>; + fn set_value( + &mut self, + index: &DictionaryIndex, + value: DictionaryValue, + ) -> Result<(), DbError>; fn transaction(&mut self); - fn value(&self, index: i64) -> Result, DbError>; + fn value(&self, index: &DictionaryIndex) -> Result, DbError>; } diff --git a/crates/dictionary/src/dictionary_data_memory.rs b/crates/dictionary/src/dictionary_data_memory.rs index e61358fc..5d898439 100644 --- a/crates/dictionary/src/dictionary_data_memory.rs +++ b/crates/dictionary/src/dictionary_data_memory.rs @@ -1,5 +1,6 @@ -use super::dictionary_data::DictionaryData; -use super::dictionary_value::DictionaryValue; +use crate::dictionary_data::DictionaryData; +use crate::dictionary_index::DictionaryIndex; +use crate::dictionary_value::DictionaryValue; use agdb_db_error::DbError; use agdb_multi_map::MultiMap; use agdb_serialize::Serialize; @@ -9,7 +10,7 @@ pub struct DictionaryDataMemory where T: Clone + Default + Eq + PartialEq + StableHash + Serialize, { - pub(crate) index: MultiMap, + pub(crate) index: MultiMap, pub(crate) values: Vec>, } @@ -25,45 +26,49 @@ where Ok(()) } - fn indexes(&self, hash: u64) -> Result, DbError> { + fn indexes(&self, hash: u64) -> Result, DbError> { self.index.values(&hash) } - fn insert(&mut self, hash: u64, index: i64) -> Result<(), DbError> { - self.index.insert(hash, index) + fn insert(&mut self, hash: u64, index: &DictionaryIndex) -> Result<(), DbError> { + self.index.insert(hash, index.clone()) } - fn hash(&self, index: i64) -> Result { - Ok(self.values[index as usize].hash) + fn hash(&self, index: &DictionaryIndex) -> Result { + Ok(self.values[index.as_usize()].hash) } - fn meta(&self, index: i64) -> Result { - Ok(self.values[index as usize].meta) + fn meta(&self, index: &DictionaryIndex) -> Result { + Ok(self.values[index.as_usize()].meta) } - fn remove(&mut self, hash: u64, index: i64) -> Result<(), DbError> { - self.index.remove_value(&hash, &index)?; + fn remove(&mut self, hash: u64, index: &DictionaryIndex) -> Result<(), DbError> { + self.index.remove_value(&hash, index)?; Ok(()) } - fn set_hash(&mut self, index: i64, hash: u64) -> Result<(), DbError> { - self.values[index as usize].hash = hash; + fn set_hash(&mut self, index: &DictionaryIndex, hash: u64) -> Result<(), DbError> { + self.values[index.as_usize()].hash = hash; Ok(()) } - fn set_meta(&mut self, index: i64, meta: i64) -> Result<(), DbError> { - self.values[index as usize].meta = meta; + fn set_meta(&mut self, index: &DictionaryIndex, meta: i64) -> Result<(), DbError> { + self.values[index.as_usize()].meta = meta; Ok(()) } - fn set_value(&mut self, index: i64, value: DictionaryValue) -> Result<(), DbError> { - if self.capacity() == index as u64 { + fn set_value( + &mut self, + index: &DictionaryIndex, + value: DictionaryValue, + ) -> Result<(), DbError> { + if self.capacity() == index.as_u64() { self.values.push(value); } else { - self.values[index as usize] = value; + self.values[index.as_usize()] = value; } Ok(()) @@ -71,7 +76,7 @@ where fn transaction(&mut self) {} - fn value(&self, index: i64) -> Result, DbError> { - Ok(self.values[index as usize].clone()) + fn value(&self, index: &DictionaryIndex) -> Result, DbError> { + Ok(self.values[index.as_usize()].clone()) } } diff --git a/crates/dictionary/src/dictionary_data_memory_default.rs b/crates/dictionary/src/dictionary_data_memory_default.rs index 327dc8a1..37d8fbef 100644 --- a/crates/dictionary/src/dictionary_data_memory_default.rs +++ b/crates/dictionary/src/dictionary_data_memory_default.rs @@ -1,4 +1,5 @@ use crate::dictionary_data_memory::DictionaryDataMemory; +use crate::dictionary_index::DictionaryIndex; use crate::dictionary_value::DictionaryValue; use agdb_multi_map::MultiMap; use agdb_serialize::Serialize; @@ -10,7 +11,7 @@ where { fn default() -> Self { Self { - index: MultiMap::::new(), + index: MultiMap::::new(), values: vec![DictionaryValue::::default()], } } diff --git a/crates/dictionary/src/dictionary_data_storage.rs b/crates/dictionary/src/dictionary_data_storage.rs index 46d7404d..d0139e46 100644 --- a/crates/dictionary/src/dictionary_data_storage.rs +++ b/crates/dictionary/src/dictionary_data_storage.rs @@ -1,5 +1,6 @@ -use super::dictionary_data::DictionaryData; -use super::dictionary_value::DictionaryValue; +use crate::dictionary_data::DictionaryData; +use crate::dictionary_index::DictionaryIndex; +use crate::dictionary_value::DictionaryValue; use agdb_db_error::DbError; use agdb_multi_map::StorageMultiMap; use agdb_serialize::Serialize; @@ -16,10 +17,10 @@ where T: Clone + Default + Eq + PartialEq + StableHash + Serialize, Data: Storage, { - pub(super) storage: Rc>, - pub(super) storage_index: StorageIndex, - pub(super) index: StorageMultiMap, - pub(super) values: StorageVec, Data>, + pub(crate) storage: Rc>, + pub(crate) storage_index: StorageIndex, + pub(crate) index: StorageMultiMap, + pub(crate) values: StorageVec, Data>, } impl DictionaryData for DictionaryDataStorage @@ -35,57 +36,61 @@ where self.storage.borrow_mut().commit() } - fn indexes(&self, hash: u64) -> Result, DbError> { + fn indexes(&self, hash: u64) -> Result, DbError> { self.index.values(&hash) } - fn insert(&mut self, hash: u64, index: i64) -> Result<(), DbError> { - self.index.insert(hash, index) + fn insert(&mut self, hash: u64, index: &DictionaryIndex) -> Result<(), DbError> { + self.index.insert(hash, index.clone()) } - fn hash(&self, index: i64) -> Result { + fn hash(&self, index: &DictionaryIndex) -> Result { let values_index = self.values.storage_index(); self.storage.borrow_mut().value_at::( &values_index, - StorageVec::>::value_offset(index as u64) + i64::serialized_size(), + StorageVec::>::value_offset(index.as_u64()) + i64::serialized_size(), ) } - fn meta(&self, index: i64) -> Result { + fn meta(&self, index: &DictionaryIndex) -> Result { let values_index = self.values.storage_index(); self.storage.borrow_mut().value_at::( &values_index, - StorageVec::>::value_offset(index as u64), + StorageVec::>::value_offset(index.as_u64()), ) } - fn remove(&mut self, hash: u64, index: i64) -> Result<(), DbError> { + fn remove(&mut self, hash: u64, index: &DictionaryIndex) -> Result<(), DbError> { self.index.remove_value(&hash, &index) } - fn set_hash(&mut self, index: i64, hash: u64) -> Result<(), DbError> { + fn set_hash(&mut self, index: &DictionaryIndex, hash: u64) -> Result<(), DbError> { let values_index = self.values.storage_index(); self.storage.borrow_mut().insert_at( &values_index, - StorageVec::>::value_offset(index as u64) + u64::serialized_size(), + StorageVec::>::value_offset(index.as_u64()) + u64::serialized_size(), &hash, ) } - fn set_meta(&mut self, index: i64, meta: i64) -> Result<(), DbError> { + fn set_meta(&mut self, index: &DictionaryIndex, meta: i64) -> Result<(), DbError> { let values_index = self.values.storage_index(); self.storage.borrow_mut().insert_at( &values_index, - StorageVec::>::value_offset(index as u64), + StorageVec::>::value_offset(index.as_u64()), &meta, ) } - fn set_value(&mut self, index: i64, value: DictionaryValue) -> Result<(), DbError> { - if self.capacity() == index as u64 { + fn set_value( + &mut self, + index: &DictionaryIndex, + value: DictionaryValue, + ) -> Result<(), DbError> { + if self.capacity() == index.as_u64() { self.values.push(&value) } else { - self.values.set_value(index as u64, &value) + self.values.set_value(index.as_u64(), &value) } } @@ -93,7 +98,7 @@ where self.storage.borrow_mut().transaction() } - fn value(&self, index: i64) -> Result, DbError> { - self.values.value(index as u64) + fn value(&self, index: &DictionaryIndex) -> Result, DbError> { + self.values.value(index.as_u64()) } } diff --git a/crates/dictionary/src/dictionary_data_storage_indexes.rs b/crates/dictionary/src/dictionary_data_storage_indexes.rs index c5390f96..7f4f42e6 100644 --- a/crates/dictionary/src/dictionary_data_storage_indexes.rs +++ b/crates/dictionary/src/dictionary_data_storage_indexes.rs @@ -3,9 +3,9 @@ use agdb_serialize::Serialize; use agdb_storage::StorageIndex; use std::mem::size_of; -pub(super) struct DictionaryDataStorageIndexes { - pub(super) index: StorageIndex, - pub(super) values: StorageIndex, +pub(crate) struct DictionaryDataStorageIndexes { + pub(crate) index: StorageIndex, + pub(crate) values: StorageIndex, } impl Serialize for DictionaryDataStorageIndexes { diff --git a/crates/dictionary/src/dictionary_impl.rs b/crates/dictionary/src/dictionary_impl.rs index b4da26ef..80c3d5a2 100644 --- a/crates/dictionary/src/dictionary_impl.rs +++ b/crates/dictionary/src/dictionary_impl.rs @@ -1,5 +1,6 @@ -use super::dictionary_data::DictionaryData; -use super::dictionary_value::DictionaryValue; +use crate::dictionary_data::DictionaryData; +use crate::dictionary_index::DictionaryIndex; +use crate::dictionary_value::DictionaryValue; use agdb_db_error::DbError; use agdb_serialize::Serialize; use agdb_utilities::StableHash; @@ -19,7 +20,7 @@ where T: Clone + Default + Eq + PartialEq + StableHash + Serialize, Data: DictionaryData, { - pub fn count(&self, index: i64) -> Result, DbError> { + pub fn count(&self, index: &DictionaryIndex) -> Result, DbError> { let mut c = None; if self.is_valid_index(index) { @@ -34,10 +35,10 @@ where } pub fn len(&self) -> Result { - self.data.hash(0) + self.data.hash(&DictionaryIndex::default()) } - pub fn index(&self, value: &T) -> Result, DbError> { + pub fn index(&self, value: &T) -> Result, DbError> { let hash = value.stable_hash(); if let Some(value) = self.find_value(hash, value)? { @@ -47,7 +48,7 @@ where Ok(None) } - pub fn insert(&mut self, value: &T) -> Result { + pub fn insert(&mut self, value: &T) -> Result { let hash = value.stable_hash(); let index; @@ -55,7 +56,7 @@ where if let Some(value) = self.find_value(hash, value)? { index = value.0; - self.data.set_meta(index, value.1 + 1)?; + self.data.set_meta(&index, value.1 + 1)?; } else { index = self.insert_new(hash, value)?; } @@ -65,7 +66,7 @@ where Ok(index) } - pub fn remove(&mut self, index: i64) -> Result<(), DbError> { + pub fn remove(&mut self, index: &DictionaryIndex) -> Result<(), DbError> { if self.is_valid_index(index) { let value = self.data.meta(index)?; @@ -83,7 +84,7 @@ where Ok(()) } - pub fn value(&self, index: i64) -> Result, DbError> { + pub fn value(&self, index: &DictionaryIndex) -> Result, DbError> { let mut v = None; if self.is_valid_index(index) { @@ -97,9 +98,9 @@ where Ok(v) } - fn find_value(&self, hash: u64, value: &T) -> Result, DbError> { + fn find_value(&self, hash: u64, value: &T) -> Result, DbError> { for index in self.data.indexes(hash)? { - let dictionary_value = self.data.value(index)?; + let dictionary_value = self.data.value(&index)?; if dictionary_value.value == *value { return Ok(Some((index, dictionary_value.meta))); @@ -109,31 +110,33 @@ where Ok(None) } - fn free_index(&mut self, index: i64) -> Result<(), DbError> { - let next_free_index = self.data.meta(0)?; + fn free_index(&mut self, index: &DictionaryIndex) -> Result<(), DbError> { + let next_free_index = self.data.meta(&DictionaryIndex::default())?; self.data.set_meta(index, next_free_index)?; - self.data.set_meta(0, -index) + self.data + .set_meta(&DictionaryIndex::default(), -index.value()) } - fn get_free_index(&mut self) -> Result { - let mut free_index = -self.data.meta(0)?; + fn get_free_index(&mut self) -> Result { + let mut free_index = -self.data.meta(&DictionaryIndex::default())?; if free_index == 0 { free_index = self.data.capacity() as i64; } else { - let next_free_index = self.data.meta(free_index)?; - self.data.set_meta(0, next_free_index)?; + let next_free_index = self.data.meta(&DictionaryIndex::from(free_index))?; + self.data + .set_meta(&DictionaryIndex::default(), next_free_index)?; } - Ok(free_index) + Ok(DictionaryIndex::from(free_index)) } - fn insert_new(&mut self, hash: u64, value: &T) -> Result { + fn insert_new(&mut self, hash: u64, value: &T) -> Result { let index = self.get_free_index()?; - self.data.insert(hash, index)?; + self.data.insert(hash, &index)?; self.data.set_value( - index, + &index, DictionaryValue:: { meta: 1, hash, @@ -142,23 +145,23 @@ where )?; let len = self.len()?; - self.data.set_hash(0, len + 1)?; + self.data.set_hash(&DictionaryIndex::default(), len + 1)?; Ok(index) } - fn is_valid_index(&self, index: i64) -> bool { - 0 < index && index < self.data.capacity() as i64 + fn is_valid_index(&self, index: &DictionaryIndex) -> bool { + index.is_valid() && index.value() < self.data.capacity() as i64 } - fn remove_value(&mut self, index: i64) -> Result<(), DbError> { + fn remove_value(&mut self, index: &DictionaryIndex) -> Result<(), DbError> { let hash = self.data.hash(index)?; self.data.remove(hash, index)?; self.free_index(index)?; let len = self.len()?; - self.data.set_hash(0, len - 1)?; + self.data.set_hash(&DictionaryIndex::default(), len - 1)?; Ok(()) } diff --git a/crates/dictionary/src/dictionary_index.rs b/crates/dictionary/src/dictionary_index.rs new file mode 100644 index 00000000..eedad3d3 --- /dev/null +++ b/crates/dictionary/src/dictionary_index.rs @@ -0,0 +1,22 @@ +#[derive(Clone, Debug, Default, Eq, PartialEq)] +pub struct DictionaryIndex { + pub(crate) index: i64, +} + +impl DictionaryIndex { + pub fn as_u64(&self) -> u64 { + self.value() as u64 + } + + pub fn as_usize(&self) -> usize { + self.value() as usize + } + + pub fn is_valid(&self) -> bool { + 0 < self.index + } + + pub fn value(&self) -> i64 { + self.index + } +} diff --git a/crates/dictionary/src/dictionary_index_from.rs b/crates/dictionary/src/dictionary_index_from.rs new file mode 100644 index 00000000..37e2555c --- /dev/null +++ b/crates/dictionary/src/dictionary_index_from.rs @@ -0,0 +1,7 @@ +use crate::dictionary_index::DictionaryIndex; + +impl From for DictionaryIndex { + fn from(index: i64) -> Self { + Self { index } + } +} diff --git a/crates/dictionary/src/dictionary_index_serialize.rs b/crates/dictionary/src/dictionary_index_serialize.rs new file mode 100644 index 00000000..62ca49d2 --- /dev/null +++ b/crates/dictionary/src/dictionary_index_serialize.rs @@ -0,0 +1,15 @@ +use crate::dictionary_index::DictionaryIndex; +use agdb_db_error::DbError; +use agdb_serialize::Serialize; + +impl Serialize for DictionaryIndex { + fn deserialize(bytes: &[u8]) -> Result { + Ok(Self { + index: i64::deserialize(bytes)?, + }) + } + + fn serialize(&self) -> Vec { + self.index.serialize() + } +} diff --git a/crates/dictionary/src/lib.rs b/crates/dictionary/src/lib.rs index 961c491a..ffbbb1a2 100644 --- a/crates/dictionary/src/lib.rs +++ b/crates/dictionary/src/lib.rs @@ -6,10 +6,14 @@ mod dictionary_data_storage; mod dictionary_data_storage_indexes; mod dictionary_default; mod dictionary_impl; +mod dictionary_index; +mod dictionary_index_from; +mod dictionary_index_serialize; mod dictionary_value; mod dictionary_value_serialize; mod storage_dictionary; mod storage_dictionary_try_from; pub use dictionary::Dictionary; +pub use dictionary_index::DictionaryIndex; pub use storage_dictionary::StorageDictionary; diff --git a/crates/dictionary/src/storage_dictionary_try_from.rs b/crates/dictionary/src/storage_dictionary_try_from.rs index fdd66449..7722400c 100644 --- a/crates/dictionary/src/storage_dictionary_try_from.rs +++ b/crates/dictionary/src/storage_dictionary_try_from.rs @@ -1,6 +1,7 @@ -use super::dictionary_data_storage::DictionaryDataStorage; -use super::dictionary_data_storage_indexes::DictionaryDataStorageIndexes; -use super::dictionary_value::DictionaryValue; +use crate::dictionary_data_storage::DictionaryDataStorage; +use crate::dictionary_data_storage_indexes::DictionaryDataStorageIndexes; +use crate::dictionary_index::DictionaryIndex; +use crate::dictionary_value::DictionaryValue; use crate::StorageDictionary; use agdb_db_error::DbError; use agdb_multi_map::StorageMultiMap; @@ -21,7 +22,7 @@ where type Error = DbError; fn try_from(storage: Rc>) -> Result { - let index = StorageMultiMap::::try_from(storage.clone())?; + let index = StorageMultiMap::::try_from(storage.clone())?; let mut values = StorageVec::, Data>::try_from(storage.clone())?; values.push(&DictionaryValue::default())?; @@ -56,7 +57,7 @@ where .0 .borrow_mut() .value::(&storage_with_index.1)?; - let index = StorageMultiMap::::try_from(( + let index = StorageMultiMap::::try_from(( storage_with_index.0.clone(), indexes.index, ))?; diff --git a/crates/dictionary/tests/dictionary_get_index_test.rs b/crates/dictionary/tests/dictionary_get_index_test.rs new file mode 100644 index 00000000..ed801b62 --- /dev/null +++ b/crates/dictionary/tests/dictionary_get_index_test.rs @@ -0,0 +1,66 @@ +use agdb_dictionary::Dictionary; +use agdb_test_utilities::CollidedValue; + +#[test] +fn index() { + let mut dictionary = Dictionary::::new(); + + let index = dictionary.insert(&10).unwrap(); + + assert_eq!(dictionary.index(&10_i64), Ok(Some(index))); +} + +#[test] +fn index_missing_value() { + let dictionary = Dictionary::::new(); + + assert_eq!(dictionary.index(&10), Ok(None)); +} + +#[test] +fn index_removed_value() { + let mut dictionary = Dictionary::::new(); + + let index = dictionary.insert(&10).unwrap(); + dictionary.remove(&index).unwrap(); + + assert_eq!(dictionary.index(&10), Ok(None)); +} + +#[test] +fn index_reuse() { + let mut dictionary = Dictionary::::new(); + + let index1 = dictionary.insert(&5).unwrap(); + let index2 = dictionary.insert(&10).unwrap(); + let index3 = dictionary.insert(&7).unwrap(); + + dictionary.remove(&index2).unwrap(); + dictionary.remove(&index1).unwrap(); + dictionary.remove(&index3).unwrap(); + + assert_eq!(dictionary.count(&index1), Ok(None)); + assert_eq!(dictionary.count(&index2), Ok(None)); + assert_eq!(dictionary.count(&index3), Ok(None)); + + assert_eq!(dictionary.insert(&3), Ok(index3.clone())); + assert_eq!(dictionary.insert(&2), Ok(index1.clone())); + assert_eq!(dictionary.insert(&1), Ok(index2.clone())); + + assert_eq!(dictionary.value(&index1), Ok(Some(2))); + assert_eq!(dictionary.value(&index2), Ok(Some(1))); + assert_eq!(dictionary.value(&index3), Ok(Some(3))); +} + +#[test] +fn index_with_collisions() { + let mut dictionary = Dictionary::>::new(); + + let index1 = dictionary.insert(&CollidedValue::new(1)).unwrap(); + let index2 = dictionary.insert(&CollidedValue::new(2)).unwrap(); + let index3 = dictionary.insert(&CollidedValue::new(3)).unwrap(); + + assert_eq!(dictionary.index(&CollidedValue::new(1)), Ok(Some(index1))); + assert_eq!(dictionary.index(&CollidedValue::new(2)), Ok(Some(index2))); + assert_eq!(dictionary.index(&CollidedValue::new(3)), Ok(Some(index3))); +} diff --git a/crates/dictionary/tests/dictionary_index_test.rs b/crates/dictionary/tests/dictionary_index_test.rs index 6078f83e..b8e43966 100644 --- a/crates/dictionary/tests/dictionary_index_test.rs +++ b/crates/dictionary/tests/dictionary_index_test.rs @@ -1,66 +1,8 @@ -use agdb_dictionary::Dictionary; -use agdb_test_utilities::CollidedValue; +use agdb_dictionary::DictionaryIndex; #[test] -fn index() { - let mut dictionary = Dictionary::::new(); +fn derived_from_debug() { + let index = DictionaryIndex::default(); - let index = dictionary.insert(&10).unwrap(); - - assert_eq!(dictionary.index(&10), Ok(Some(index))); -} - -#[test] -fn index_missing_value() { - let dictionary = Dictionary::::new(); - - assert_eq!(dictionary.index(&10), Ok(None)); -} - -#[test] -fn index_removed_value() { - let mut dictionary = Dictionary::::new(); - - let index = dictionary.insert(&10).unwrap(); - dictionary.remove(index).unwrap(); - - assert_eq!(dictionary.index(&10), Ok(None)); -} - -#[test] -fn index_reuse() { - let mut dictionary = Dictionary::::new(); - - let index1 = dictionary.insert(&5).unwrap(); - let index2 = dictionary.insert(&10).unwrap(); - let index3 = dictionary.insert(&7).unwrap(); - - dictionary.remove(index2).unwrap(); - dictionary.remove(index1).unwrap(); - dictionary.remove(index3).unwrap(); - - assert_eq!(dictionary.count(index1), Ok(None)); - assert_eq!(dictionary.count(index2), Ok(None)); - assert_eq!(dictionary.count(index3), Ok(None)); - - assert_eq!(dictionary.insert(&3), Ok(index3)); - assert_eq!(dictionary.insert(&2), Ok(index1)); - assert_eq!(dictionary.insert(&1), Ok(index2)); - - assert_eq!(dictionary.value(index1), Ok(Some(2))); - assert_eq!(dictionary.value(index2), Ok(Some(1))); - assert_eq!(dictionary.value(index3), Ok(Some(3))); -} - -#[test] -fn index_with_collisions() { - let mut dictionary = Dictionary::>::new(); - - let index1 = dictionary.insert(&CollidedValue::new(1)).unwrap(); - let index2 = dictionary.insert(&CollidedValue::new(2)).unwrap(); - let index3 = dictionary.insert(&CollidedValue::new(3)).unwrap(); - - assert_eq!(dictionary.index(&CollidedValue::new(1)), Ok(Some(index1))); - assert_eq!(dictionary.index(&CollidedValue::new(2)), Ok(Some(index2))); - assert_eq!(dictionary.index(&CollidedValue::new(3)), Ok(Some(index3))); + format!("{:?}", index); } diff --git a/crates/dictionary/tests/dictionary_insert_test.rs b/crates/dictionary/tests/dictionary_insert_test.rs index 673ae665..004a68e6 100644 --- a/crates/dictionary/tests/dictionary_insert_test.rs +++ b/crates/dictionary/tests/dictionary_insert_test.rs @@ -7,8 +7,8 @@ fn insert() { let index = dictionary.insert(&10).unwrap(); assert_eq!(dictionary.len(), Ok(1)); - assert_eq!(dictionary.value(index), Ok(Some(10_i64))); - assert_eq!(dictionary.count(index), Ok(Some(1))); + assert_eq!(dictionary.value(&index), Ok(Some(10_i64))); + assert_eq!(dictionary.count(&index), Ok(Some(1))); } #[test] @@ -21,14 +21,14 @@ fn insert_multiple() { assert_eq!(dictionary.len(), Ok(3)); - assert_eq!(dictionary.value(index1).unwrap(), Some(10_i64)); - assert_eq!(dictionary.count(index1), Ok(Some(1))); + assert_eq!(dictionary.value(&index1).unwrap(), Some(10_i64)); + assert_eq!(dictionary.count(&index1), Ok(Some(1))); - assert_eq!(dictionary.value(index2).unwrap(), Some(15_i64)); - assert_eq!(dictionary.count(index2), Ok(Some(1))); + assert_eq!(dictionary.value(&index2).unwrap(), Some(15_i64)); + assert_eq!(dictionary.count(&index2), Ok(Some(1))); - assert_eq!(dictionary.value(index3).unwrap(), Some(20_i64)); - assert_eq!(dictionary.count(index3), Ok(Some(1))); + assert_eq!(dictionary.value(&index3).unwrap(), Some(20_i64)); + assert_eq!(dictionary.count(&index3), Ok(Some(1))); } #[test] @@ -45,5 +45,5 @@ fn insert_same() { dictionary.insert(&20).unwrap(); assert_eq!(dictionary.len(), Ok(3)); - assert_eq!(dictionary.count(index2), Ok(Some(3))); + assert_eq!(dictionary.count(&index2), Ok(Some(3))); } diff --git a/crates/dictionary/tests/dictionary_remove_test.rs b/crates/dictionary/tests/dictionary_remove_test.rs index 188e3786..221a5594 100644 --- a/crates/dictionary/tests/dictionary_remove_test.rs +++ b/crates/dictionary/tests/dictionary_remove_test.rs @@ -1,14 +1,15 @@ use agdb_dictionary::Dictionary; +use agdb_dictionary::DictionaryIndex; #[test] fn remove() { let mut dictionary = Dictionary::::new(); let index = dictionary.insert(&10).unwrap(); - dictionary.remove(index).unwrap(); + dictionary.remove(&index).unwrap(); - assert_eq!(dictionary.value(index), Ok(None)); - assert_eq!(dictionary.count(index), Ok(None)); + assert_eq!(dictionary.value(&index), Ok(None)); + assert_eq!(dictionary.count(&index), Ok(None)); } #[test] @@ -19,19 +20,19 @@ fn remove_duplicated() { dictionary.insert(&10).unwrap(); dictionary.insert(&10).unwrap(); - assert_eq!(dictionary.value(index), Ok(Some(10))); - assert_eq!(dictionary.count(index), Ok(Some(3))); + assert_eq!(dictionary.value(&index), Ok(Some(10))); + assert_eq!(dictionary.count(&index), Ok(Some(3))); - dictionary.remove(index).unwrap(); + dictionary.remove(&index).unwrap(); - assert_eq!(dictionary.value(index), Ok(Some(10))); - assert_eq!(dictionary.count(index), Ok(Some(2))); + assert_eq!(dictionary.value(&index), Ok(Some(10))); + assert_eq!(dictionary.count(&index), Ok(Some(2))); - dictionary.remove(index).unwrap(); - dictionary.remove(index).unwrap(); + dictionary.remove(&index).unwrap(); + dictionary.remove(&index).unwrap(); - assert_eq!(dictionary.value(index), Ok(None)); - assert_eq!(dictionary.count(index), Ok(None)); + assert_eq!(dictionary.value(&index), Ok(None)); + assert_eq!(dictionary.count(&index), Ok(None)); } #[test] @@ -42,7 +43,9 @@ fn remove_missing() { assert_eq!(dictionary.len(), Ok(1)); - dictionary.remove(index + 1).unwrap(); + dictionary + .remove(&DictionaryIndex::from(index.value() + 1)) + .unwrap(); assert_eq!(dictionary.len(), Ok(1)); } diff --git a/crates/dictionary/tests/dictionary_test.rs b/crates/dictionary/tests/dictionary_test.rs index 929f3639..d4496337 100644 --- a/crates/dictionary/tests/dictionary_test.rs +++ b/crates/dictionary/tests/dictionary_test.rs @@ -1,14 +1,21 @@ use agdb_dictionary::Dictionary; +use agdb_dictionary::DictionaryIndex; #[test] fn count_invalid_index() { let dictionary = Dictionary::::new(); - assert_eq!(dictionary.count(-1), Ok(None)); - assert_eq!(dictionary.count(0), Ok(None)); + assert_eq!(dictionary.count(&DictionaryIndex::default()), Ok(None)); + assert_eq!(dictionary.count(&DictionaryIndex::from(-1_i64)), Ok(None)); } #[test] fn default() { let _dictionary = Dictionary::::default(); } + +#[test] +fn value_missing_index() { + let dictionary = Dictionary::::new(); + assert_eq!(dictionary.value(&DictionaryIndex::from(1_i64)), Ok(None)); +} diff --git a/crates/dictionary/tests/storage_dictionary_index_test.rs b/crates/dictionary/tests/storage_dictionary_get_index_test.rs similarity index 71% rename from crates/dictionary/tests/storage_dictionary_index_test.rs rename to crates/dictionary/tests/storage_dictionary_get_index_test.rs index 409c0758..568d54ee 100644 --- a/crates/dictionary/tests/storage_dictionary_index_test.rs +++ b/crates/dictionary/tests/storage_dictionary_get_index_test.rs @@ -38,7 +38,7 @@ fn index_removed_value() { let mut dictionary = StorageDictionary::::try_from(storage).unwrap(); let index = dictionary.insert(&10).unwrap(); - dictionary.remove(index).unwrap(); + dictionary.remove(&index).unwrap(); assert_eq!(dictionary.index(&10), Ok(None)); } @@ -55,21 +55,21 @@ fn index_reuse() { let index2 = dictionary.insert(&10).unwrap(); let index3 = dictionary.insert(&7).unwrap(); - dictionary.remove(index2).unwrap(); - dictionary.remove(index1).unwrap(); - dictionary.remove(index3).unwrap(); + dictionary.remove(&index2).unwrap(); + dictionary.remove(&index1).unwrap(); + dictionary.remove(&index3).unwrap(); - assert_eq!(dictionary.count(index1), Ok(None)); - assert_eq!(dictionary.count(index2), Ok(None)); - assert_eq!(dictionary.count(index3), Ok(None)); + assert_eq!(dictionary.count(&index1), Ok(None)); + assert_eq!(dictionary.count(&index2), Ok(None)); + assert_eq!(dictionary.count(&index3), Ok(None)); - assert_eq!(dictionary.insert(&3), Ok(index3)); - assert_eq!(dictionary.insert(&2), Ok(index1)); - assert_eq!(dictionary.insert(&1), Ok(index2)); + assert_eq!(dictionary.insert(&3), Ok(index3.clone())); + assert_eq!(dictionary.insert(&2), Ok(index1.clone())); + assert_eq!(dictionary.insert(&1), Ok(index2.clone())); - assert_eq!(dictionary.value(index1), Ok(Some(2))); - assert_eq!(dictionary.value(index2), Ok(Some(1))); - assert_eq!(dictionary.value(index3), Ok(Some(3))); + assert_eq!(dictionary.value(&index1), Ok(Some(2))); + assert_eq!(dictionary.value(&index2), Ok(Some(1))); + assert_eq!(dictionary.value(&index3), Ok(Some(3))); } #[test] @@ -88,14 +88,3 @@ fn index_with_collisions() { assert_eq!(dictionary.index(&CollidedValue::new(2)), Ok(Some(index2))); assert_eq!(dictionary.index(&CollidedValue::new(3)), Ok(Some(index3))); } - -#[test] -fn value_missing_index() { - let test_file = TestFile::new(); - let storage = Rc::new(RefCell::new( - StorageFile::try_from(test_file.file_name().clone()).unwrap(), - )); - let dictionary = StorageDictionary::::try_from(storage).unwrap(); - - assert_eq!(dictionary.value(1), Ok(None)); -} diff --git a/crates/dictionary/tests/storage_dictionary_insert_test.rs b/crates/dictionary/tests/storage_dictionary_insert_test.rs index b5fd416a..e1c83416 100644 --- a/crates/dictionary/tests/storage_dictionary_insert_test.rs +++ b/crates/dictionary/tests/storage_dictionary_insert_test.rs @@ -15,8 +15,8 @@ fn insert() { let index = dictionary.insert(&10).unwrap(); assert_eq!(dictionary.len(), Ok(1)); - assert_eq!(dictionary.value(index), Ok(Some(10_i64))); - assert_eq!(dictionary.count(index), Ok(Some(1))); + assert_eq!(dictionary.value(&index), Ok(Some(10_i64))); + assert_eq!(dictionary.count(&index), Ok(Some(1))); } #[test] @@ -33,14 +33,14 @@ fn insert_multiple() { assert_eq!(dictionary.len(), Ok(3)); - assert_eq!(dictionary.value(index1).unwrap(), Some(10_i64)); - assert_eq!(dictionary.count(index1), Ok(Some(1))); + assert_eq!(dictionary.value(&index1).unwrap(), Some(10_i64)); + assert_eq!(dictionary.count(&index1), Ok(Some(1))); - assert_eq!(dictionary.value(index2).unwrap(), Some(15_i64)); - assert_eq!(dictionary.count(index2), Ok(Some(1))); + assert_eq!(dictionary.value(&index2).unwrap(), Some(15_i64)); + assert_eq!(dictionary.count(&index2), Ok(Some(1))); - assert_eq!(dictionary.value(index3).unwrap(), Some(20_i64)); - assert_eq!(dictionary.count(index3), Ok(Some(1))); + assert_eq!(dictionary.value(&index3).unwrap(), Some(20_i64)); + assert_eq!(dictionary.count(&index3), Ok(Some(1))); } #[test] @@ -61,5 +61,5 @@ fn insert_same() { dictionary.insert(&20).unwrap(); assert_eq!(dictionary.len(), Ok(3)); - assert_eq!(dictionary.count(index2), Ok(Some(3))); + assert_eq!(dictionary.count(&index2), Ok(Some(3))); } diff --git a/crates/dictionary/tests/storage_dictionary_remove_test.rs b/crates/dictionary/tests/storage_dictionary_remove_test.rs index 874b98a7..595f44b7 100644 --- a/crates/dictionary/tests/storage_dictionary_remove_test.rs +++ b/crates/dictionary/tests/storage_dictionary_remove_test.rs @@ -1,3 +1,4 @@ +use agdb_dictionary::DictionaryIndex; use agdb_dictionary::StorageDictionary; use agdb_storage::StorageFile; use agdb_test_utilities::TestFile; @@ -13,10 +14,10 @@ fn remove() { let mut dictionary = StorageDictionary::::try_from(storage).unwrap(); let index = dictionary.insert(&10).unwrap(); - dictionary.remove(index).unwrap(); + dictionary.remove(&index).unwrap(); - assert_eq!(dictionary.value(index), Ok(None)); - assert_eq!(dictionary.count(index), Ok(None)); + assert_eq!(dictionary.value(&index), Ok(None)); + assert_eq!(dictionary.count(&index), Ok(None)); } #[test] @@ -31,19 +32,19 @@ fn remove_duplicated() { dictionary.insert(&10).unwrap(); dictionary.insert(&10).unwrap(); - assert_eq!(dictionary.value(index), Ok(Some(10))); - assert_eq!(dictionary.count(index), Ok(Some(3))); + assert_eq!(dictionary.value(&index), Ok(Some(10))); + assert_eq!(dictionary.count(&index), Ok(Some(3))); - dictionary.remove(index).unwrap(); + dictionary.remove(&index).unwrap(); - assert_eq!(dictionary.value(index), Ok(Some(10))); - assert_eq!(dictionary.count(index), Ok(Some(2))); + assert_eq!(dictionary.value(&index), Ok(Some(10))); + assert_eq!(dictionary.count(&index), Ok(Some(2))); - dictionary.remove(index).unwrap(); - dictionary.remove(index).unwrap(); + dictionary.remove(&index).unwrap(); + dictionary.remove(&index).unwrap(); - assert_eq!(dictionary.value(index), Ok(None)); - assert_eq!(dictionary.count(index), Ok(None)); + assert_eq!(dictionary.value(&index), Ok(None)); + assert_eq!(dictionary.count(&index), Ok(None)); } #[test] @@ -58,7 +59,9 @@ fn remove_missing() { assert_eq!(dictionary.len(), Ok(1)); - dictionary.remove(index + 1).unwrap(); + dictionary + .remove(&DictionaryIndex::from(index.value() + 1)) + .unwrap(); assert_eq!(dictionary.len(), Ok(1)); } diff --git a/crates/dictionary/tests/storage_dictionary_test.rs b/crates/dictionary/tests/storage_dictionary_test.rs index 9f272734..06f43dd4 100644 --- a/crates/dictionary/tests/storage_dictionary_test.rs +++ b/crates/dictionary/tests/storage_dictionary_test.rs @@ -1,3 +1,4 @@ +use agdb_dictionary::DictionaryIndex; use agdb_dictionary::StorageDictionary; use agdb_storage::StorageFile; use agdb_test_utilities::TestFile; @@ -12,7 +13,7 @@ fn count_invalid_index() { )); let dictionary = StorageDictionary::::try_from(storage).unwrap(); - assert_eq!(dictionary.count(-1), Ok(None)); + assert_eq!(dictionary.count(&DictionaryIndex::from(-1_i64)), Ok(None)); } #[test] @@ -37,15 +38,25 @@ fn restore_from_file() { index2 = dictionary.insert(&15).unwrap(); index3 = dictionary.insert(&7).unwrap(); index4 = dictionary.insert(&20).unwrap(); - dictionary.remove(index2).unwrap(); + dictionary.remove(&index2).unwrap(); } let dictionary = StorageDictionary::::try_from((storage, storage_index)).unwrap(); assert_eq!(dictionary.len(), Ok(3)); - assert_eq!(dictionary.count(index1), Ok(Some(2))); - assert_eq!(dictionary.value(index1), Ok(Some(10))); - assert_eq!(dictionary.value(index2), Ok(None)); - assert_eq!(dictionary.value(index3), Ok(Some(7))); - assert_eq!(dictionary.value(index4), Ok(Some(20))); + assert_eq!(dictionary.count(&index1), Ok(Some(2))); + assert_eq!(dictionary.value(&index1), Ok(Some(10))); + assert_eq!(dictionary.value(&index2), Ok(None)); + assert_eq!(dictionary.value(&index3), Ok(Some(7))); + assert_eq!(dictionary.value(&index4), Ok(Some(20))); +} + +#[test] +fn value_missing_index() { + let test_file = TestFile::new(); + let storage = Rc::new(RefCell::new( + StorageFile::try_from(test_file.file_name().clone()).unwrap(), + )); + let dictionary = StorageDictionary::::try_from(storage).unwrap(); + assert_eq!(dictionary.value(&DictionaryIndex::from(1_i64)), Ok(None)); } diff --git a/crates/storage_index/src/storage_index_from.rs b/crates/storage_index/src/storage_index_from.rs index 64f149eb..0dc587d6 100644 --- a/crates/storage_index/src/storage_index_from.rs +++ b/crates/storage_index/src/storage_index_from.rs @@ -2,13 +2,13 @@ use crate::storage_index::StorageIndex; impl From for StorageIndex { fn from(index: i64) -> Self { - StorageIndex { index } + Self { index } } } impl From for StorageIndex { fn from(index: u64) -> Self { - StorageIndex { + Self { index: index as i64, } } @@ -16,7 +16,7 @@ impl From for StorageIndex { impl From for StorageIndex { fn from(index: usize) -> Self { - StorageIndex { + Self { index: index as i64, } }