Advertisement
theultraman20

hash_map.rs

Aug 4th, 2024
362
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 4.46 KB | None | 0 0
  1.  
  2. use std::hash::{DefaultHasher, Hash, Hasher};
  3. use std::mem;
  4. use Cell::*;
  5.  
  6. macro_rules! get_cell {
  7.     ($self:expr, $key:expr, $($borrow:tt)+) => {
  8.         let initial_idx = $self.get_idx(&$key);
  9.         let mut idx = initial_idx;
  10.         loop {
  11.             match $($borrow)+ $self.cells[idx] {
  12.                 Filled(entry) if entry.key == $key => return Some($($borrow)+ $self.cells[idx]),
  13.                 Filled(_) | Removed => {},
  14.                 Empty => return None,
  15.             }
  16.             idx = (idx + 1) % $self.cells.len();
  17.         }
  18.     };
  19. }
  20.  
  21.  
  22. #[derive(Clone, PartialEq)]
  23. pub struct Entry<K, V> {
  24.     key: K,
  25.     value: V,
  26. }
  27.  
  28. impl<K, V> Entry<K, V> {
  29.     fn new(key: K, value: V) -> Self {
  30.         Entry {
  31.             key: key,
  32.             value: value,
  33.         }
  34.     }
  35. }
  36.  
  37. #[derive(Clone, PartialEq)]
  38. pub enum Cell<K, V> {
  39.     Empty,
  40.     Filled(Entry<K, V>),
  41.     Removed,
  42. }
  43.  
  44. impl<K, V> Default for Cell<K, V> {
  45.     fn default() -> Cell<K, V> { Empty }
  46. }
  47.  
  48. pub struct HashMap<K, V> {
  49.     cells: Vec<Cell<K, V>>,
  50.     num_entries: usize,
  51. }
  52.  
  53. impl<K, V> HashMap<K, V>
  54. where
  55.     K: Hash + Eq,
  56.     V: PartialEq,
  57. {
  58.     const START_SIZE: usize = 256;//256 just seems like a cool number
  59.     const MAX_LOAD_FACTOR: f32 = 0.5;
  60.  
  61.     pub fn new() -> Self {
  62.         HashMap {
  63.             cells: vec![Empty; Self::START_SIZE],
  64.             num_entries: 0,
  65.         }
  66.     }
  67.  
  68.     pub fn clear(&mut self) {
  69.         self.cells.clear();
  70.         self.num_entries = 0;
  71.     }
  72.  
  73.     fn get_cell(&self, key: K) -> Option<&Cell<K, V>> {
  74.         get_cell!(self, key, &);
  75.     }
  76.  
  77.     fn get_cell_mut(&mut self, key: K) -> Option<&mut Cell<K, V>> {
  78.         get_cell!(self, key, &mut);
  79.     }
  80.  
  81.     fn get_idx(&self, key: &K) -> usize {
  82.         let mut hasher = DefaultHasher::new();
  83.         key.hash(&mut hasher);
  84.         hasher.finish() as usize % self.cells.len()
  85.     }
  86.  
  87.     pub fn get(&self, key: K) -> Option<&V> {
  88.         match self.get_cell(key) {
  89.             Some(Filled(cell)) => Some(&cell.value),
  90.             _ => None,
  91.         }
  92.     }
  93.  
  94.     pub fn get_mut(&mut self, key: K) -> Option<&mut V> {
  95.         match self.get_cell_mut(key) {
  96.             Some(Filled(cell)) => Some(&mut cell.value),
  97.             _ => None,
  98.         }
  99.     }
  100.  
  101.     fn resize(&mut self) {
  102.         let mut old_cells = std::mem::take(&mut self.cells);
  103.         //allocate twice as much memory as before
  104.         self.cells = Vec::with_capacity(old_cells.len()*2);
  105.         self.cells.resize(self.cells.capacity(), Empty);
  106.        
  107.         for cell in old_cells {
  108.             if let Filled(entry) = cell {
  109.                 self.insert(entry.key, entry.value);
  110.             }
  111.         }
  112.     }
  113.  
  114.     pub fn insert(&mut self, key: K, value: V) -> &mut V {
  115.         if self.num_entries as f32 / self.cells.len() as f32 > Self::MAX_LOAD_FACTOR {
  116.             self.resize();
  117.         }
  118.  
  119.         let mut idx = self.get_idx(&key);
  120.         while matches!(self.cells[idx], Filled(_)) {
  121.             idx += 1;
  122.             if idx == self.cells.len() {
  123.                 idx = 0;
  124.             }
  125.         }
  126.  
  127.         self.cells[idx] = Filled(Entry::new(key, value));
  128.         self.num_entries += 1;
  129.  
  130.         match &mut self.cells[idx] {
  131.             Filled(entry) => &mut entry.value,
  132.             _ => unreachable!(),
  133.         }
  134.     }
  135.  
  136.     pub fn remove(&mut self, key: K) -> Option<V> {
  137.         let cell = self.get_cell_mut(key);
  138.  
  139.         match cell {
  140.             Some(Filled(_)) => {
  141.                 let Filled(entry) = mem::replace(cell.unwrap(), Removed) else { unreachable!() };
  142.                 self.num_entries -= 1;
  143.                 Some(entry.value)
  144.             }
  145.             _ => None,
  146.         }
  147.     }
  148.  
  149.     pub fn iter(&self) -> HashMapIter<K, V> {
  150.         HashMapIter {
  151.             hash_table: &self,
  152.             idx: 0,
  153.         }
  154.     }
  155.  
  156. }
  157.  
  158. pub struct HashMapIter<'a, K, V> {
  159.    pub hash_table: &'a HashMap<K, V>,
  160.     idx: usize,
  161. }
  162.  
  163. impl<'a, K, V> Iterator for HashMapIter<'a, K, V> {
  164.     type Item = (&'a K, &'a V);
  165.  
  166.     fn next(&mut self) -> Option<(&'a K, &'a V)> {
  167.  
  168.         while self.idx < self.hash_table.cells.len() {
  169.  
  170.             if let Filled(entry) = &self.hash_table.cells[self.idx] {
  171.                 self.idx = self.idx + 1;
  172.                 return Some((&entry.key, &entry.value));
  173.             }
  174.  
  175.             self.idx = self.idx + 1;
  176.         }
  177.  
  178.         None
  179.     }
  180. }
  181.  
  182.  
  183. /*
  184. impl IntoIterator for HashMap {
  185.     fn into_iter() -> {
  186.  
  187.     }
  188. }
  189. */
  190.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement