#![deny(missing_docs)]
extern crate num_traits;
use num_traits::identities::{One, Zero};
use std::borrow::Borrow;
use std::collections::HashMap;
use std::collections::hash_map::{Drain, IntoIter, Iter, IterMut, Keys, RandomState, Values};
use std::hash::{BuildHasher, Hash};
use std::iter::FromIterator;
use std::ops::{Add, Index};
#[derive(Clone, Debug)]
pub struct CountMap<K, C = u64, S = RandomState>
where
K: Eq + Hash,
S: BuildHasher,
{
map: HashMap<K, C, S>,
}
impl<K, C> CountMap<K, C, RandomState>
where
K: Eq + Hash,
{
pub fn new() -> Self {
Self::default()
}
pub fn with_capacity(cap: usize) -> Self {
Self { map: HashMap::with_capacity(cap) }
}
}
impl<K, C, S> CountMap<K, C, S>
where
K: Eq + Hash,
C: One + Zero + Copy + Clone + Add<Output = C>,
S: BuildHasher,
{
pub fn with_hasher(hash_builder: S) -> Self {
Self { map: HashMap::with_hasher(hash_builder) }
}
pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> Self {
Self { map: HashMap::with_capacity_and_hasher(capacity, hash_builder) }
}
pub fn hasher(&self) -> &S {
self.map.hasher()
}
pub fn capacity(&self) -> usize {
self.map.capacity()
}
pub fn reserve(&mut self, additional: usize) {
self.map.reserve(additional)
}
pub fn shrink_to_fit(&mut self) {
self.map.shrink_to_fit()
}
pub fn keys(&self) -> Keys<K, C> {
self.map.keys()
}
pub fn values(&self) -> Values<K, C> {
self.map.values()
}
pub fn insert_or_increment(&mut self, element: K) -> C {
self.insert_or_increment_by(element, C::one())
}
pub fn insert_or_increment_by(&mut self, element: K, diff: C) -> C {
let count = self.map.entry(element).or_insert(C::zero());
*count = *count + diff;
*count
}
pub fn increment(&mut self, element: &K) -> Option<C> {
self.increment_by(element, C::one())
}
pub fn increment_by(&mut self, element: &K, diff: C) -> Option<C> {
let entry = self.map.get_mut(element);
match entry {
Some(count) => {
*count = *count + diff;
Some(*count)
}
None => None,
}
}
pub fn get_count(&self, element: &K) -> Option<C> {
self.map.get(element).cloned()
}
pub fn iter(&self) -> Iter<K, C> {
self.map.iter()
}
pub fn iter_mut(&mut self) -> IterMut<K, C> {
self.map.iter_mut()
}
pub fn len(&self) -> usize {
self.map.len()
}
pub fn is_empty(&self) -> bool {
self.map.is_empty()
}
pub fn drain(&mut self) -> Drain<K, C> {
self.map.drain()
}
pub fn clear(&mut self) {
self.map.clear()
}
pub fn contains_key(&self, k: &K) -> bool {
self.map.contains_key(k)
}
pub fn remove(&mut self, k: &K) -> Option<C> {
self.map.remove(k)
}
pub fn retain<F>(&mut self, f: F)
where
F: FnMut(&K, &mut C) -> bool,
{
self.map.retain(f)
}
}
impl<K, C> Default for CountMap<K, C>
where
K: Eq + Hash,
{
fn default() -> Self {
Self { map: HashMap::new() }
}
}
impl<K> PartialEq for CountMap<K>
where
K: Eq + Hash,
{
fn eq(&self, other: &CountMap<K>) -> bool {
self.map == other.map
}
}
impl<K> Eq for CountMap<K>
where
K: Eq + Hash,
{
}
impl<'a, K, C> IntoIterator for &'a CountMap<K, C>
where
K: Eq + Hash,
{
type Item = (&'a K, &'a C);
type IntoIter = Iter<'a, K, C>;
fn into_iter(self) -> Self::IntoIter {
self.map.iter()
}
}
impl<'a, K, C> IntoIterator for &'a mut CountMap<K, C>
where
K: Eq + Hash,
{
type Item = (&'a K, &'a mut C);
type IntoIter = IterMut<'a, K, C>;
fn into_iter(self) -> Self::IntoIter {
self.map.iter_mut()
}
}
impl<'a, K, C> IntoIterator for CountMap<K, C>
where
K: Eq + Hash,
{
type Item = (K, C);
type IntoIter = IntoIter<K, C>;
fn into_iter(self) -> Self::IntoIter {
self.map.into_iter()
}
}
impl<'a, K, C, Q> Index<&'a Q> for CountMap<K, C>
where
K: Eq + Hash + Borrow<Q>,
Q: ?Sized + Eq + Hash,
{
type Output = C;
fn index(&self, index: &Q) -> &Self::Output {
&self.map[index]
}
}
impl<K, C> FromIterator<(K, C)> for CountMap<K, C>
where
K: Eq + Hash,
C: Clone + Copy + One + Zero,
{
fn from_iter<T>(iter: T) -> Self
where
T: IntoIterator<Item = (K, C)>,
{
let iter = iter.into_iter();
let mut map = CountMap::with_capacity(iter.size_hint().0);
for (k, v) in iter {
map.insert_or_increment_by(k, v);
}
map
}
}
impl<K> FromIterator<K> for CountMap<K>
where
K: Eq + Hash,
{
fn from_iter<T>(iter: T) -> Self
where
T: IntoIterator<Item = K>,
{
let iter = iter.into_iter();
let mut map = CountMap::with_capacity(iter.size_hint().0);
for item in iter {
map.insert_or_increment(item);
}
map
}
}
impl<K, C> Extend<(K, C)> for CountMap<K, C>
where
K: Eq + Hash,
C: Clone + Copy + One + Zero,
{
fn extend<T>(&mut self, iter: T)
where
T: IntoIterator<Item = (K, C)>,
{
let iter = iter.into_iter();
let reserve = if self.is_empty() {
iter.size_hint().0
} else {
(iter.size_hint().0 + 1) / 2
};
self.reserve(reserve);
for (k, v) in iter {
self.insert_or_increment_by(k, v);
}
}
}
impl<'a, K, C> Extend<(&'a K, &'a C)> for CountMap<K, C>
where
K: 'a + Eq + Hash + Copy,
C: 'a + Clone + Copy + One + Zero,
{
fn extend<T>(&mut self, iter: T)
where
T: IntoIterator<Item = (&'a K, &'a C)>,
{
self.extend(iter.into_iter().map(|(&key, &value)| (key, value)));
}
}
impl<K> Extend<K> for CountMap<K>
where
K: Eq + Hash,
{
fn extend<T>(&mut self, iter: T)
where
T: IntoIterator<Item = K>,
{
let iter = iter.into_iter();
let reserve = if self.is_empty() {
iter.size_hint().0
} else {
(iter.size_hint().0 + 1) / 2
};
self.reserve(reserve);
for k in iter {
self.insert_or_increment(k);
}
}
}
impl<'a, K> Extend<&'a K> for CountMap<K>
where
K: 'a + Eq + Hash + Copy,
{
fn extend<T>(&mut self, iter: T)
where
T: IntoIterator<Item = &'a K>,
{
self.extend(iter.into_iter().cloned());
}
}