use std::hash::Hash;
use std::fmt::Debug;
use Mphf;
#[derive(Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct BoomHashMap<K: Hash, D> {
mphf: Mphf<K>,
keys: Vec<K>,
values: Vec<D>,
}
impl<K, D> BoomHashMap<K, D>
where
K: Clone + Hash + Debug + PartialEq,
D: Debug,
{
fn create_map(mut keys: Vec<K>, mut data: Vec<D>, mphf: Mphf<K>) -> BoomHashMap<K, D> {
for i in 0..keys.len() {
loop {
let kmer_slot = mphf.hash(&keys[i]) as usize;
if i == kmer_slot {
break;
}
keys.swap(i, kmer_slot);
data.swap(i, kmer_slot);
}
}
BoomHashMap {
mphf: mphf,
keys: keys,
values: data,
}
}
pub fn new(keys: Vec<K>, data: Vec<D>) -> BoomHashMap<K, D> {
let mphf = Mphf::new(1.7, &keys);
Self::create_map(keys, data, mphf)
}
pub fn get(&self, kmer: &K) -> Option<&D> {
let maybe_pos = self.mphf.try_hash(kmer);
match maybe_pos {
Some(pos) => {
let hashed_kmer = &self.keys[pos as usize];
if *kmer == hashed_kmer.clone() {
Some(&self.values[pos as usize])
} else {
None
}
}
None => None,
}
}
pub fn get_key_id(&self, kmer: &K) -> Option<usize> {
let maybe_pos = self.mphf.try_hash(&kmer);
match maybe_pos {
Some(pos) => {
let hashed_kmer = &self.keys[pos as usize];
if *kmer == hashed_kmer.clone() {
Some(pos as usize)
} else {
None
}
}
None => None,
}
}
pub fn len(&self) -> usize {
self.keys.len()
}
pub fn get_key(&self, id: usize) -> Option<&K> {
let max_key_id = self.len();
if id > max_key_id {
None
} else {
Some(&self.keys[id])
}
}
pub fn iter(&self) -> BoomIterator<K, D> {
BoomIterator {
hash: self,
index: 0,
}
}
}
impl<K, D> BoomHashMap<K, D>
where
K: Clone + Hash + Debug + PartialEq + Send + Sync,
D: Debug,
{
pub fn new_parallel(keys: Vec<K>, data: Vec<D>) -> BoomHashMap<K, D> {
let mphf = Mphf::new_parallel(1.7, &keys, None);
Self::create_map(keys, data, mphf)
}
}
pub struct BoomIterator<'a, K: Hash + 'a, D: 'a> {
hash: &'a BoomHashMap<K, D>,
index: usize,
}
impl<'a, K: Hash, D> Iterator for BoomIterator<'a, K, D> {
type Item = (&'a K, &'a D);
fn next(&mut self) -> Option<Self::Item> {
if self.index == self.hash.keys.len() {
return None;
}
let elements = Some((&self.hash.keys[self.index], &self.hash.values[self.index]));
self.index += 1;
elements
}
}
impl<'a, K: Hash, D> IntoIterator for &'a BoomHashMap<K, D> {
type Item = (&'a K, &'a D);
type IntoIter = BoomIterator<'a, K, D>;
fn into_iter(self) -> BoomIterator<'a, K, D> {
BoomIterator {
hash: self,
index: 0,
}
}
}
#[derive(Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct BoomHashMap2<K: Hash, D1, D2> {
mphf: Mphf<K>,
keys: Vec<K>,
values: Vec<D1>,
aux_values: Vec<D2>,
}
pub struct Boom2Iterator<'a, K: Hash + 'a, D1: 'a, D2: 'a> {
hash: &'a BoomHashMap2<K, D1, D2>,
index: usize,
}
impl<'a, K: Hash, D1, D2> Iterator for Boom2Iterator<'a, K, D1, D2> {
type Item = (&'a K, &'a D1, &'a D2);
fn next(&mut self) -> Option<Self::Item> {
if self.index == self.hash.keys.len() {
return None;
}
let elements = Some((
&self.hash.keys[self.index],
&self.hash.values[self.index],
&self.hash.aux_values[self.index],
));
self.index += 1;
elements
}
}
impl<'a, K: Hash, D1, D2> IntoIterator for &'a BoomHashMap2<K, D1, D2> {
type Item = (&'a K, &'a D1, &'a D2);
type IntoIter = Boom2Iterator<'a, K, D1, D2>;
fn into_iter(self) -> Boom2Iterator<'a, K, D1, D2> {
Boom2Iterator {
hash: self,
index: 0,
}
}
}
impl<K, D1, D2> BoomHashMap2<K, D1, D2>
where
K: Clone + Hash + Debug + PartialEq,
D1: Debug,
D2: Debug,
{
fn create_map(mut keys: Vec<K>, mut data: Vec<D1>, mut aux_data: Vec<D2>, mphf: Mphf<K>) -> BoomHashMap2<K, D1, D2> {
for i in 0..keys.len() {
loop {
let kmer_slot = mphf.hash(&keys[i]) as usize;
if i == kmer_slot {
break;
}
keys.swap(i, kmer_slot);
data.swap(i, kmer_slot);
aux_data.swap(i, kmer_slot);
}
}
BoomHashMap2 {
mphf: mphf,
keys: keys,
values: data,
aux_values: aux_data,
}
}
pub fn new(
keys: Vec<K>,
values: Vec<D1>,
aux_values: Vec<D2>,
) -> BoomHashMap2<K, D1, D2> {
let mphf = Mphf::new(1.7, &keys);
Self::create_map(keys, values, aux_values, mphf)
}
pub fn get(&self, kmer: &K) -> Option<(&D1, &D2)> {
let maybe_pos = self.mphf.try_hash(kmer);
match maybe_pos {
Some(pos) => {
let hashed_kmer = &self.keys[pos as usize];
if *kmer == hashed_kmer.clone() {
Some((&self.values[pos as usize], &self.aux_values[pos as usize]))
} else {
None
}
}
None => None,
}
}
pub fn get_key_id(&self, kmer: &K) -> Option<usize> {
let maybe_pos = self.mphf.try_hash(&kmer);
match maybe_pos {
Some(pos) => {
let hashed_kmer = &self.keys[pos as usize];
if *kmer == hashed_kmer.clone() {
Some(pos as usize)
} else {
None
}
}
None => None,
}
}
pub fn len(&self) -> usize {
self.keys.len()
}
pub fn iter(&self) -> Boom2Iterator<K, D1, D2> {
Boom2Iterator {
hash: self,
index: 0,
}
}
pub fn get_key(&self, id: usize) -> Option<&K> {
let max_key_id = self.len();
if id > max_key_id {
None
} else {
Some(&self.keys[id])
}
}
}
impl<K, D1, D2> BoomHashMap2<K, D1, D2>
where
K: Clone + Hash + Debug + PartialEq + Send + Sync,
D1: Debug,
D2: Debug,
{
pub fn new_parallel(
keys: Vec<K>,
data: Vec<D1>,
aux_data: Vec<D2>,
) -> BoomHashMap2<K, D1, D2> {
let mphf = Mphf::new_parallel(1.7, &keys, None);
Self::create_map(keys, data, aux_data, mphf)
}
}
#[derive(Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct NoKeyBoomHashMap<K, D1> {
pub mphf: Mphf<K>,
pub values: Vec<D1>,
}
impl<K, D1> NoKeyBoomHashMap<K, D1>
where
K: Clone + Hash + Debug + PartialEq + Send + Sync,
D1: Debug,
{
pub fn new_parallel(
mut keys: Vec<K>,
mut data: Vec<D1>,
) -> NoKeyBoomHashMap<K, D1> {
let mphf = Mphf::new_parallel(1.7, &keys, None);
for i in 0..keys.len() {
loop {
let kmer_slot = mphf.hash(&keys[i]) as usize;
if i == kmer_slot {
break;
}
keys.swap(i, kmer_slot);
data.swap(i, kmer_slot);
}
}
NoKeyBoomHashMap {
mphf: mphf,
values: data,
}
}
pub fn new_with_mphf(
mphf: Mphf<K>,
data: Vec<D1>,
) -> NoKeyBoomHashMap<K, D1> {
NoKeyBoomHashMap {
mphf: mphf,
values: data,
}
}
pub fn get(&self, kmer: &K) -> Option<&D1> {
let maybe_pos = self.mphf.try_hash(kmer);
match maybe_pos {
Some(pos) => Some(&self.values[pos as usize]),
_ => None,
}
}
}
#[derive(Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct NoKeyBoomHashMap2<K, D1, D2> {
pub mphf: Mphf<K>,
pub values: Vec<D1>,
pub aux_values: Vec<D2>,
}
impl<K, D1, D2> NoKeyBoomHashMap2<K, D1, D2>
where
K: Clone + Hash + Debug + PartialEq + Send + Sync,
D1: Debug,
D2: Debug,
{
pub fn new_parallel(
mut keys: Vec<K>,
mut data: Vec<D1>,
mut aux_data: Vec<D2>,
) -> NoKeyBoomHashMap2<K, D1, D2> {
let mphf = Mphf::new_parallel(1.7, &keys, None);
for i in 0..keys.len() {
loop {
let kmer_slot = mphf.hash(&keys[i]) as usize;
if i == kmer_slot {
break;
}
keys.swap(i, kmer_slot);
data.swap(i, kmer_slot);
aux_data.swap(i, kmer_slot);
}
}
NoKeyBoomHashMap2 {
mphf: mphf,
values: data,
aux_values: aux_data,
}
}
pub fn new_with_mphf(
mphf: Mphf<K>,
data: Vec<D1>,
aux_data: Vec<D2>,
) -> NoKeyBoomHashMap2<K, D1, D2> {
NoKeyBoomHashMap2 {
mphf: mphf,
values: data,
aux_values: aux_data,
}
}
pub fn get(&self, kmer: &K) -> Option<(&D1, &D2)> {
let maybe_pos = self.mphf.try_hash(kmer);
match maybe_pos {
Some(pos) => Some((&self.values[pos as usize], &self.aux_values[pos as usize])),
_ => None,
}
}
}