/// A HashMap implementation backed by a HashIndex. /// Uses more memory than FlatMap, but gives faster lookup. use crate::flatbuffers::containers::{ fb_index::FbIndex, flat_serialize::{FlatBuilder, FlatMapBuilderOutput, FlatSerialize}, hash_index::{FbHashKey, HashIndexBuilder, HashIndexView, HashKey}, }; /// A builder for a HashMap that can be serialized into a flatbuffer. /// A default key is used to mark empty slots, so (default_key, _) pair /// can't be added. #[derive(Default)] pub(crate) struct HashMapBuilder { builder: HashIndexBuilder, } impl HashMapBuilder { #[allow(unused)] pub fn insert(&mut self, key: I, value: V) { self.builder.insert(key, value, false /* allow_duplicate */); } pub fn get_or_insert(&mut self, key: I, value: V) -> &mut V { self.builder.get_or_insert(key, value) } pub fn finish<'b, B: FlatBuilder<'b>>( value: Self, builder: &mut B, ) -> FlatMapBuilderOutput<'b, I, V, B> where I: FlatSerialize<'b, B>, V: FlatSerialize<'b, B>, { let (indexes, values) = HashIndexBuilder::consume(value.builder); let keys = indexes .into_iter() .map(|i| FlatSerialize::serialize(i, builder)) .collect::>(); let values = values .into_iter() .map(|v| FlatSerialize::serialize(v, builder)) .collect::>(); let keys = builder.raw_builder().create_vector(&keys); let values = builder.raw_builder().create_vector(&values); FlatMapBuilderOutput { keys, values } } } /// A view of a HashMap stored in a flatbuffer. /// The default key is considered as an empty slot, `get(default_key)` always /// returns None. pub(crate) struct HashMapView where I: FbHashKey, Keys: FbIndex, Values: FbIndex, { view: HashIndexView, } impl HashMapView where I: FbHashKey, Keys: FbIndex, Values: FbIndex, { pub fn new(keys: Keys, values: Values) -> Self { assert_eq!(keys.len(), values.len()); Self { view: HashIndexView::new(keys, values), } } pub fn get(&self, key: I) -> Option { self.view.get_single(key) } #[cfg(test)] pub fn capacity(&self) -> usize { self.view.capacity() } #[cfg(test)] pub fn len(&self) -> usize { self.view.len() } } pub type HashMapStringView<'a, V> = HashMapView< &'a str, V, flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<&'a str>>, flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<>::Inner>>, >; #[cfg(test)] #[path = "../../../tests/unit/flatbuffers/containers/hash_map.rs"] mod unit_tests;