use std::{
collections::hash_map::DefaultHasher,
hash::{Hash, Hasher},
};
use super::{sequential::SequentialSearchST, ST};
pub struct SeparateChainingHashST<K: PartialOrd, V> {
len: usize,
m: usize,
st: Vec<SequentialSearchST<K, V>>,
}
impl<K: Ord + Default + Hash, V: Default> SeparateChainingHashST<K, V> {
pub fn new(cap: usize) -> Self {
let st = Self::new_st(cap);
SeparateChainingHashST { len: 0, m: cap, st }
}
pub fn hash(&self, k: &K) -> usize {
Self::hash_for_m(k, self.m)
}
pub fn hash_for_m(k: &K, m: usize) -> usize {
let mut hasher = DefaultHasher::new();
k.hash(&mut hasher);
hasher.finish() as usize % m
}
fn resize(&mut self, m: usize) {
let enumerate = &mut self.st;
let mut st = Self::new_st(m);
for item in enumerate {
for (key, value) in item.iter_mut() {
let i = Self::hash_for_m(&key, m);
st[i].put(key, value)
}
}
self.m = m;
self.st = st;
}
fn new_st(cap: usize) -> Vec<SequentialSearchST<K, V>> {
let mut st = Vec::with_capacity(cap);
for _ in 0..cap {
st.push(SequentialSearchST::default());
}
st
}
fn need_resize(&self) -> bool {
self.len > 10 * self.m
}
}
impl<K: Ord + Default + Hash, V: Default> ST<K, V> for SeparateChainingHashST<K, V> {
fn put(&mut self, key: K, value: V) {
if self.need_resize() {
self.resize(2 * self.m)
}
assert!(!self.need_resize(), "len:{},m:{}", self.len, self.m);
if !self.contains(&key) {
self.len += 1;
}
let i = self.hash(&key);
self.st[i].put(key, value)
}
fn get(&self, key: &K) -> Option<&V> {
self.st[self.hash(key)].get(key)
}
fn delete(&mut self, key: &K) {
if self.contains(key) {
self.len -= 1;
}
let i = self.hash(key);
self.st[i].delete(key)
}
fn is_empty(&self) -> bool {
self.len == 0
}
fn size(&self) -> usize {
self.len
}
fn min(&self) -> Option<&K> {
if self.is_empty() {
None
} else {
self.st
.iter()
.filter(|it| !it.is_empty())
.map(|it| it.min().unwrap())
.min()
}
}
fn max(&self) -> Option<&K> {
let ans = if self.is_empty() {
None
} else {
self.st
.iter()
.filter(|it| !it.is_empty())
.map(|it| it.max().unwrap())
.max()
};
ans
}
fn floor(&self, key: &K) -> Option<&K> {
if self.is_empty() {
None
} else {
self.st
.iter()
.filter(|it| !it.is_empty())
.map(|it| it.floor(key))
.filter(|it| it.is_some())
.max()
.unwrap()
}
}
fn ceiling(&self, key: &K) -> Option<&K> {
if self.is_empty() {
None
} else {
self.st
.iter()
.filter(|it| !it.is_empty())
.map(|it| it.ceiling(key))
.filter(|it| it.is_some())
.min()
.unwrap()
}
}
fn rank(&self, key: &K) -> usize {
self.st.iter().map(|it| it.rank(key)).sum()
}
fn select(&self, k: usize) -> Option<&K> {
let mut current_i = 0;
let mut indexes = vec![0usize; self.m];
let mut changed: bool;
loop {
if let Some((i, key)) = self
.st
.iter()
.enumerate()
.map(|(i, f)| (i, f.select(indexes[i])))
.filter(|f| f.1.is_some())
.min_by(|a, b| a.1.cmp(&b.1))
{
if current_i == k {
return key;
}
changed = true;
indexes[i] += 1;
current_i += 1;
} else {
changed = false;
}
if !changed {
return None;
}
}
}
}
#[cfg(test)]
mod test {
use rand::seq::SliceRandom;
use crate::search::ST;
use super::SeparateChainingHashST;
#[test]
fn test() {
let mut st = SeparateChainingHashST::new(1);
let mut rng = rand::thread_rng();
let n = 530;
let mut arr: Vec<usize> = (1..=n).collect();
arr.shuffle(&mut rng);
for (i, key) in arr.iter().enumerate() {
assert_eq!(st.get(key), None);
st.put(key.clone(), key + 10);
assert_eq!(st.get(key), Some(&(key + 10)));
assert_eq!(st.size(), i + 1);
}
let mut arr: Vec<usize> = (1..=n).collect();
arr.shuffle(&mut rng);
for (i, key) in arr.iter().enumerate() {
assert_eq!(st.get(key), Some(&(key + 10)));
st.delete(&key);
assert_eq!(st.get(key), None);
assert_eq!(st.size(), arr.len() - i - 1);
}
}
}