rust_ds/hash_table/
mod.rs1mod errors;
2
3pub(super) use errors::{Error, Result};
4use std::collections::hash_map::DefaultHasher;
5use std::fmt::Debug;
6use std::hash::{Hash, Hasher};
7
8type KeyPointer<K, V> = Option<(K, V)>;
9
10#[derive(Debug)]
12pub struct Table<K, V>
13where
14 K: Clone,
15 V: Clone,
16{
17 pub elements: Vec<KeyPointer<K, V>>,
18 capacity: usize,
19}
20
21impl<K, V> Table<K, V>
22where
23 K: Hash + Eq + Debug + Clone,
24 V: Debug + Clone,
25{
26 pub fn new(capacity: usize) -> Self {
28 Self {
29 elements: vec![None; capacity],
30 capacity,
31 }
32 }
33 fn hash<Q>(&self, key: &Q) -> usize
35 where
36 K: std::borrow::Borrow<Q>,
37 Q: Hash + ?Sized,
38 {
39 let mut hasher = DefaultHasher::new();
40 key.hash(&mut hasher);
41 (hasher.finish() as usize) % self.capacity
42 }
43 pub fn insert(&mut self, key: K, value: V) {
45 let index = self.hash(&key);
46 self.elements[index] = Some((key, value));
47 }
48 pub fn get(&self, key: &K) -> Result<&V> {
50 let index = self.hash(key);
51 self.elements[index]
52 .as_ref()
53 .map(|(_, v)| v)
54 .ok_or(Error::KeyNotFound)
55 }
56 pub fn remove(&mut self, key: &K) -> Result<V> {
58 if self.capacity == 0 {
59 return Err(Error::EmptyTable);
60 }
61 let index = self.hash(key);
62 if let Some((_, value)) = self.elements[index].take() {
63 Ok(value)
64 } else {
65 Err(Error::KeyNotFound)
66 }
67 }
68 pub fn update(&mut self, key: &K) -> Result<&mut V> {
70 if self.capacity == 0 {
71 return Err(Error::EmptyTable);
72 }
73 let index = self.hash(key);
74 self.elements[index]
75 .as_mut()
76 .map(|(_, v)| v)
77 .ok_or(Error::KeyNotFound)
78 }
79 pub fn resize(&mut self, new_capacity: usize) -> Result<()> {
81 if new_capacity == 0 {
82 return Err(Error::InvalidCapacity);
83 }
84
85 let mut new_table = Table::new(new_capacity);
86 for element in self.elements.iter().filter_map(|e| e.as_ref()) {
87 new_table.insert(element.0.clone(), element.1.clone());
88 }
89 self.elements = new_table.elements;
90 self.capacity = new_capacity;
91 Ok(())
92 }
93}
94impl<K, V> Default for Table<K, V>
96where
97 K: Hash + Eq + Debug + Clone,
98 V: Debug + Clone,
99{
100 fn default() -> Self {
101 Self::new(64)
102 }
103}
104
105#[cfg(test)]
107mod tests {
108 use super::*;
109
110 #[test]
111 fn test_hash_table_ops() {
112 let mut table = Table::new(16);
113 table.insert("key1", "value1");
114 assert_eq!(table.get(&"key1").unwrap(), &"value1");
115 table.remove(&"key1").unwrap();
116 assert!(table.get(&"key1").is_err());
117 table.insert("key2", "value2");
118 if let Ok(v) = table.update(&"key2") {
119 *v = "value3";
120 }
121 assert_eq!(table.get(&"key2").unwrap(), &"value3");
122 }
123
124 #[test]
125 fn test_hash_table_errors() {
126 let mut table: Table<&str, &str> = Table::new(16);
127 assert!(table.get(&"key1").is_err());
128 assert!(table.remove(&"key1").is_err());
129 assert!(table.update(&"key1").is_err());
130 assert!(table.resize(0).is_err());
131 }
132}
133