84 lines
2.3 KiB
Rust
84 lines
2.3 KiB
Rust
struct HashMap<'a, K: PartialEq, V> {
|
|
table: Vec<Option<Vec<(&'a K, &'a V)>>>,
|
|
hash_fn: fn(&K) -> usize,
|
|
}
|
|
|
|
impl<'a, K: PartialEq, V> HashMap<'a, K, V> {
|
|
fn new(hash_fn: fn(&K) -> usize) -> Self {
|
|
HashMap {
|
|
table: vec![None; 16],
|
|
hash_fn,
|
|
}
|
|
}
|
|
|
|
|
|
fn with_capacity(capacity: usize, hash_fn: fn(&K) -> usize) -> Self {
|
|
HashMap {
|
|
table: vec![None; capacity],
|
|
hash_fn
|
|
}
|
|
}
|
|
|
|
fn put(&mut self, k: &'a K, v: &'a V) {
|
|
let hash = (self.hash_fn)(&k);
|
|
let target_index = hash % self.table.capacity();
|
|
match self.table[target_index].take() {
|
|
None => {
|
|
let new_container = vec![(k, v)];
|
|
self.table.insert(target_index, Some(new_container));
|
|
},
|
|
Some(mut container) => {
|
|
container.push((k, v));
|
|
self.table.insert(target_index, Some(container));
|
|
}
|
|
}
|
|
}
|
|
|
|
fn get(&mut self, k: &K) -> Option<&V> {
|
|
let hash = (self.hash_fn)(&k);
|
|
let target_index = hash % self.table.capacity();
|
|
let container_opt = self.table[target_index].take();
|
|
if container_opt.is_none() {
|
|
None
|
|
} else {
|
|
let container = container_opt.unwrap();
|
|
for item in container.iter() {
|
|
if item.0 == k {
|
|
let result = Some(item.1);
|
|
self.table[target_index] = Some(container);
|
|
return result;
|
|
}
|
|
}
|
|
self.table[target_index] = Some(container);
|
|
None
|
|
}
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod hash_map_tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn simple_put_and_get() {
|
|
let jesse = String::from("Jesse");
|
|
let brault = String::from("Brault");
|
|
let mut map: HashMap<String, String> = HashMap::new(|s| s.len());
|
|
map.put(&jesse, &brault);
|
|
assert_eq!(map.get(&jesse), Some(&brault));
|
|
}
|
|
|
|
#[test]
|
|
fn put_and_get_with_str() {
|
|
let jesse = "Jesse";
|
|
let brault = "Brault";
|
|
let mut map: HashMap<&str, &str> = HashMap::new(|s| s.len());
|
|
map.put(&jesse, &brault);
|
|
assert_eq!(map.get(&jesse), Some(&brault));
|
|
}
|
|
}
|
|
|
|
fn main() {
|
|
println!("Hello, world!");
|
|
}
|