Advertisement
theultraman20

lib.rs

Jul 21st, 2024
438
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 4.77 KB | None | 0 0
  1.  
  2. use std::hash::{DefaultHasher, Hash, Hasher};
  3.  
  4. #[cfg(test)]
  5. mod tests {
  6.     use super::*;
  7.     use tremor::HashTable;
  8.  
  9.     use rand::{distributions::Alphanumeric, Rng};
  10.     fn rand_string() -> String {
  11.         let s: String = rand::thread_rng()
  12.             .sample_iter(&Alphanumeric)
  13.             .take(10)
  14.             .map(char::from)
  15.             .collect();
  16.  
  17.         s
  18.     }
  19. /*
  20.     struct BadHashObject {
  21.         hash_val: u64
  22.     }
  23.  
  24.     impl Hash for BadHashObject {
  25.  
  26.     }
  27. */
  28.     #[test]
  29.     fn normal() {
  30.         let mut hash_table = HashTable::new();
  31.         hash_table.insert("greeting".to_string(), "hello world!".to_string());
  32.         hash_table.insert("album".to_string(), "https://open.spotify.com/album/1PQDjdBpHPikAodJqjzm6a".to_string());
  33.         hash_table.insert("SSN".to_string(), "574-48-XXXX".to_string());
  34.  
  35.         for i in 0..100 {
  36.             hash_table.insert(rand_string(), rand_string());
  37.         }
  38.  
  39.         println!("{:?}", hash_table.search("greeting".to_string()));
  40.  
  41.         assert_eq!(hash_table.search("greeting".to_string()), Some(&mut "hello world!".to_string()));
  42.         assert_eq!(hash_table.search("album".to_string()), Some(&mut "https://open.spotify.com/album/1PQDjdBpHPikAodJqjzm6a".to_string()));
  43.         assert_eq!(hash_table.search("SSN".to_string()), Some(&mut "574-48-6969".to_string()));
  44.  
  45.         //shouldn't have been stored there in the first place...
  46.         hash_table.remove("SSN".to_string());
  47.         assert_eq!(hash_table.search("SSN".to_string()), None);
  48.     }
  49. }
  50.  
  51. mod tremor {
  52.     use Cell::*;
  53.     use crate::DefaultHasher;
  54.     use crate::Hash;
  55.     use crate::Hasher;
  56.  
  57.     #[derive(Clone, PartialEq)]
  58.     struct Entry<K, V> {
  59.         key: K,
  60.         value: V,
  61.     }
  62.  
  63.     impl<K, V> Entry<K, V> {
  64.         fn new(key: K, value: V) -> Self {
  65.             Entry { key: key, value: value }
  66.         }
  67.     }
  68.  
  69.     #[derive(Clone, PartialEq)]
  70.     enum Cell<K, V> {
  71.         Filled(Entry<K, V>),
  72.         Empty,
  73.         Removed,
  74.     }
  75.  
  76.     pub struct HashTable<K, V> {
  77.         cells: Vec<Cell<K, V>>,
  78.         num_entries: usize,
  79.     }
  80.  
  81.     impl<K, V> HashTable<K, V>
  82.     where
  83.         K: Hash + Eq + Clone,
  84.         V: Clone + PartialEq,
  85.     {
  86.  
  87.         const START_SIZE: usize = 256; //256 just seems like a cool number
  88.         const MAX_LOAD_FACTOR: f32 = 0.5;
  89.  
  90.         pub fn new() -> Self {
  91.             HashTable {
  92.                 cells: vec![Empty; Self::START_SIZE],
  93.                 num_entries: 0,
  94.             }
  95.         }
  96.  
  97.         fn get_idx(&mut self, key: &K) -> usize {
  98.             let mut hasher = DefaultHasher::new();
  99.             key.hash(&mut hasher);
  100.             hasher.finish() as usize % self.cells.len()
  101.         }
  102.  
  103.         pub fn get_cell(&mut self, key: K) -> Option<&mut Cell<K, V>> {
  104.             let initial_idx = self.get_idx(&key);
  105.             let mut idx = initial_idx;
  106.  
  107.             loop {
  108.                 match self.cells[idx] {
  109.                     Filled(ref mut entry) => {
  110.                         if entry.key == key {
  111.                             return Some(&mut self.cells[idx]);
  112.                         }
  113.                     },
  114.                     Removed => {},
  115.                     Empty => { return None; }
  116.                 }
  117.                 idx += 1;
  118.                 if idx == self.cells.len() { idx = 0; }
  119.             }
  120.         }
  121.  
  122.  
  123.         fn resize(&mut self) {
  124.             panic!("Don't feel like implementing");
  125.         }
  126.  
  127.         pub fn insert(&mut self, key: K, value: V) {
  128.             if self.num_entries as f32 / self.cells.len() as f32 > Self::MAX_LOAD_FACTOR {
  129.                 self.resize();
  130.             }
  131.  
  132.             let mut idx = self.get_idx(&key);
  133.             while matches!(self.cells[idx], Filled(_)) {
  134.                 idx += 1;
  135.                 if idx == self.cells.len() { idx = 0; }
  136.             }
  137.  
  138.             self.cells[idx] = Filled(Entry::new(key, value));
  139.             self.num_entries += 1;
  140.         }
  141.  
  142.         pub fn remove(&mut self, key: K) -> Option<V> {
  143.             /*
  144.             if let Some(cell) = self.get_cell(key) {
  145.                 *cell = Removed;
  146.                 self.num_entries -= 1;
  147.             }  
  148.             */
  149.             let cell = self.get_cell(key);
  150.  
  151.             match cell {
  152.                 Some(Filled(entry)) => {
  153.                     let value = entry.value;
  154.                     *cell.unwrap() = Removed;
  155.                     self.num_entries -= 1;
  156.                     Some(value)
  157.                 },
  158.                 _ => None,
  159.             }
  160.         }
  161.  
  162.         pub fn search(&mut self, key: K) -> Option<&mut V> {
  163.             if let Some(Filled(cell)) = self.get_cell(key) {
  164.                 Some(&mut cell.value)
  165.             } else {
  166.                 None
  167.             }
  168.         }
  169.     }
  170. }
  171.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement