2018-11-29 00:12:24 +08:00
|
|
|
use std::hash::Hash;
|
|
|
|
|
2018-12-02 20:11:02 +08:00
|
|
|
use hashbrown::HashMap;
|
|
|
|
|
2018-11-29 00:12:24 +08:00
|
|
|
pub struct DistinctMap<K> {
|
|
|
|
inner: HashMap<K, usize>,
|
|
|
|
limit: usize,
|
|
|
|
len: usize,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<K: Hash + Eq> DistinctMap<K> {
|
|
|
|
pub fn new(limit: usize) -> Self {
|
|
|
|
DistinctMap {
|
|
|
|
inner: HashMap::new(),
|
|
|
|
limit: limit,
|
|
|
|
len: 0,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-13 18:54:09 +08:00
|
|
|
pub fn register(&mut self, key: K) -> bool {
|
2018-11-29 00:12:24 +08:00
|
|
|
let seen = self.inner.entry(key).or_insert(0);
|
|
|
|
if *seen < self.limit {
|
|
|
|
*seen += 1;
|
|
|
|
self.len += 1;
|
|
|
|
true
|
|
|
|
} else {
|
|
|
|
false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-13 18:54:09 +08:00
|
|
|
pub fn register_without_key(&mut self) -> bool {
|
2018-11-29 00:12:24 +08:00
|
|
|
self.len += 1;
|
|
|
|
true
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn len(&self) -> usize {
|
|
|
|
self.len
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn easy_distinct_map() {
|
|
|
|
let mut map = DistinctMap::new(2);
|
|
|
|
for x in &[1, 1, 1, 2, 3, 4, 5, 6, 6, 6, 6, 6] {
|
2018-12-13 18:54:09 +08:00
|
|
|
map.register(x);
|
2018-11-29 00:12:24 +08:00
|
|
|
}
|
|
|
|
assert_eq!(map.len(), 8);
|
|
|
|
|
|
|
|
let mut map = DistinctMap::new(2);
|
2018-12-13 18:54:09 +08:00
|
|
|
assert_eq!(map.register(1), true);
|
|
|
|
assert_eq!(map.register(1), true);
|
|
|
|
assert_eq!(map.register(1), false);
|
|
|
|
assert_eq!(map.register(1), false);
|
2018-11-29 00:12:24 +08:00
|
|
|
|
2018-12-13 18:54:09 +08:00
|
|
|
assert_eq!(map.register(2), true);
|
|
|
|
assert_eq!(map.register(3), true);
|
|
|
|
assert_eq!(map.register(2), true);
|
|
|
|
assert_eq!(map.register(2), false);
|
2018-11-29 00:12:24 +08:00
|
|
|
|
|
|
|
assert_eq!(map.len(), 5);
|
|
|
|
}
|
|
|
|
}
|