extern crate stable_deref_trait;
extern crate vec_drain_where;
use std::collections::HashMap;
use std::{vec, slice};
use std::hash::Hash;
use std::cmp::{Eq, PartialEq};
use std::iter::{ Extend, FromIterator };
use std::fmt::{self, Debug};
use std::ops::DerefMut;
use stable_deref_trait::StableDeref;
use self::utils::DebugIterableOpaque;
pub use self::iter::*;
pub use self::entry::*;
pub use self::map_iter::*;
#[macro_use]
mod utils;
mod iter;
mod entry;
mod map_iter;
pub struct TotalOrderMultiMap<K, V>
where V: StableDeref + DerefMut, K: Hash + Eq + Copy
{
vec_data: Vec<(K, V)>,
map_access: HashMap<K, Vec<*mut V::Target>>,
}
impl<K, V> Default for TotalOrderMultiMap<K, V>
where K: Hash + Eq + Copy,
V: StableDeref + DerefMut
{
fn default() -> Self {
TotalOrderMultiMap {
vec_data: Default::default(),
map_access: Default::default()
}
}
}
impl<K, V> TotalOrderMultiMap<K, V>
where K: Hash+Eq+Copy,
V: StableDeref + DerefMut
{
pub fn new() -> Self {
Default::default()
}
pub fn with_capacity(capacity: usize) -> Self {
TotalOrderMultiMap {
vec_data: Vec::with_capacity(capacity),
map_access: HashMap::with_capacity(capacity),
}
}
pub fn capacity(&self) -> usize {
self.vec_data.capacity()
}
pub fn reserve(&mut self, additional: usize) {
self.vec_data.reserve(additional);
self.map_access.reserve(additional);
}
pub fn reverse(&mut self) {
self.vec_data.reverse();
for (_, val) in self.map_access.iter_mut() {
val.reverse()
}
}
pub fn shrink_to_fit(&mut self) {
self.vec_data.shrink_to_fit();
self.map_access.shrink_to_fit();
for (_, val) in self.map_access.iter_mut() {
val.shrink_to_fit()
}
}
pub fn len(&self) -> usize {
self.vec_data.len()
}
pub fn key_count(&self) -> usize {
self.map_access.len()
}
pub fn is_empty(&self) -> bool {
self.vec_data.is_empty()
}
pub fn clear(&mut self) {
self.map_access.clear();
self.vec_data.clear();
}
pub fn contains_key(&self, k: K) -> bool {
self.map_access.contains_key(&k)
}
pub fn get(&self, k: K) -> EntryValues<V::Target> {
self.map_access.get(&k)
.map(|vec| EntryValues::new(vec.iter()))
.unwrap_or_else(|| EntryValues::empty())
}
pub fn get_mut(&mut self, k: K) -> EntryValuesMut<V::Target> {
self.map_access.get_mut(&k)
.map(|vec| EntryValuesMut::new(vec.iter_mut()))
.unwrap_or_else(|| EntryValuesMut::empty())
}
pub fn add(&mut self, key: K, value: V) -> EntryValuesMut<V::Target> {
self.entry(key).add(value)
}
pub fn set(&mut self, key: K, value: V) -> Vec<V> {
self.entry(key).set(value)
}
pub fn pop(&mut self) -> Option<(K, V)> {
if let Some(&(k, ref val)) = self.vec_data.last() {
Self::delete_last_inserted_from_map_with_same_ptr(
&mut self.map_access, k, val);
} else {
return None;
}
self.vec_data.pop()
}
pub fn truncate(&mut self, to_len: usize) {
if to_len >= self.len() {
return;
}
{
let mut to_delete_iter = self.vec_data[to_len..].iter();
while let Some(&(key, ref val)) = to_delete_iter.next_back() {
Self::delete_last_inserted_from_map_with_same_ptr(
&mut self.map_access, key, &val);
}
}
self.vec_data.truncate(to_len);
}
fn delete_last_inserted_from_map_with_same_ptr(
map: &mut HashMap<K, Vec<*mut V::Target>>,
key: K,
val: &V::Target
)
{
let exp_ptr: *const V::Target = val;
let bucket = map.get_mut(&key)
.expect("[BUG] key in vec_data but not map_access");
let to_remove_idx = bucket.iter()
.rposition(|ptr| *ptr as *const _ == exp_ptr)
.expect("[BUG] no ptr for value in map_access");
bucket.remove(to_remove_idx);
}
pub fn remove_all(&mut self, key_to_remove: K) -> bool {
if let Some(_) = self.map_access.remove(&key_to_remove) {
self.vec_data.retain(|&(key, _)| key != key_to_remove);
true
} else {
false
}
}
pub fn retain<FN>(&mut self, mut func: FN)
where FN: FnMut(K, &V::Target) -> bool
{
let mut to_remove_ptr = Vec::new();
let mut to_remove_idx = Vec::new();
for (idx, (key, val)) in self.iter().enumerate() {
if !func(key, val) {
let vptr: *const V::Target = val;
to_remove_idx.push(idx);
to_remove_ptr.push((key, vptr));
}
}
if to_remove_idx.is_empty() {
return
}
for (key, ptr) in to_remove_ptr.into_iter() {
let needs_key_removal;
{
if let Some(values) = self.map_access.get_mut(&key) {
match values.iter().position(|x| *x as *const _ == ptr) {
Some(idx) => {
values.remove(idx);
},
None => unreachable!(
"[BUG] inconsistent state, value is not in map_access but in vec_data")
}
needs_key_removal = values.is_empty();
} else {
unreachable!(
"[BUG] inconsistent state, value is not in map_access but in vec_data")
}
}
if needs_key_removal {
self.map_access.remove(&key);
}
}
let mut idx = 0;
let mut next_removal = to_remove_idx[0];
let mut to_remove_idx = &to_remove_idx[1..];
self.vec_data.retain(|_| {
let retain =
if idx == next_removal {
if to_remove_idx.is_empty() {
next_removal = 0;
} else {
next_removal = to_remove_idx[0];
to_remove_idx = &to_remove_idx[1..];
}
false
} else {
true
};
idx += 1;
retain
})
}
}
impl<K, V> Debug for TotalOrderMultiMap<K, V>
where K: Hash + Eq + Copy + Debug,
V: StableDeref + DerefMut + Debug
{
fn fmt(&self, fter: &mut fmt::Formatter) -> fmt::Result {
write!(fter, "TotalOrderMultiMap {{ ")?;
for &(key, ref val_cont) in self.vec_data.iter() {
write!(fter, "{:?} => {:?},", key, val_cont)?;
}
write!(fter, " }}")
}
}
impl<K, V> Clone for TotalOrderMultiMap<K, V>
where K: Hash + Eq + Copy,
V: StableDeref + DerefMut + Clone
{
fn clone(&self) -> Self {
let vec_data = Vec::with_capacity(self.vec_data.len());
let map_access = HashMap::with_capacity(self.map_access.len());
let mut map = TotalOrderMultiMap { map_access, vec_data};
for &(k, ref val) in self.vec_data.iter() {
map.add(k, val.clone());
}
map
}
}
impl<K, V> PartialEq<Self> for TotalOrderMultiMap<K, V>
where K: Hash + Eq + Copy,
V: StableDeref + DerefMut + PartialEq<V>,
{
#[inline]
fn eq(&self, other: &Self) -> bool {
self.vec_data.eq(&other.vec_data)
}
}
impl<K, V> Eq for TotalOrderMultiMap<K, V>
where K: Hash + Eq + Copy,
V: StableDeref + DerefMut + Eq,
{}
impl<K, V> IntoIterator for TotalOrderMultiMap<K, V>
where K: Hash + Eq + Copy,
V: StableDeref + DerefMut,
{
type Item = (K, V);
type IntoIter = vec::IntoIter<(K, V)>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
let TotalOrderMultiMap { vec_data, map_access } = self;
drop(map_access);
vec_data.into_iter()
}
}
impl<K, V> FromIterator<(K, V)> for TotalOrderMultiMap<K, V>
where K: Hash + Eq + Copy,
V: StableDeref + DerefMut,
{
fn from_iter<I: IntoIterator<Item=(K,V)>>(src: I) -> Self {
let src_iter = src.into_iter();
let mut out = {
let (min, _) = src_iter.size_hint();
if min > 0 {
Self::with_capacity(min)
} else {
Self::default()
}
};
<Self as Extend<(K,V)>>::extend(&mut out, src_iter);
out
}
}
impl<K, V> Extend<(K, V)> for TotalOrderMultiMap<K, V>
where K: Hash + Eq + Copy,
V: StableDeref + DerefMut
{
fn extend<I>(&mut self, src: I)
where I: IntoIterator<Item=(K,V)>
{
for (key, value) in src.into_iter() {
self.add(key, value);
}
}
}
pub struct EntryValues<'a, T: ?Sized+'a>{
inner_iter: Option<slice::Iter<'a, *mut T>>,
}
impl<'a, T> EntryValues<'a, T>
where T: ?Sized + 'a
{
pub fn empty() -> Self {
EntryValues { inner_iter: None }
}
fn new(inner_iter: slice::Iter<'a, *mut T>) -> Self {
EntryValues { inner_iter: Some(inner_iter) }
}
}
impl<'a, T: ?Sized + 'a> Clone for EntryValues<'a, T> {
fn clone(&self) -> Self {
EntryValues {
inner_iter: self.inner_iter.clone(),
}
}
}
impl<'a, T: ?Sized + 'a> Iterator for EntryValues<'a, T> {
type Item = &'a T;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.inner_iter
.as_mut()
.map(|iter| iter.next().map(|&ptr| unsafe { &*ptr }))
.unwrap_or(None)
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner_iter
.as_ref()
.map(|iter| iter.size_hint())
.unwrap_or((0, Some(0)))
}
}
impl<'a, T: ?Sized + 'a> ExactSizeIterator for EntryValues<'a, T> {
#[inline]
fn len(&self) -> usize {
self.inner_iter
.as_ref()
.map(|iter| iter.len())
.unwrap_or(0)
}
}
impl<'a, T> Debug for EntryValues<'a, T>
where T: ?Sized + Debug + 'a
{
fn fmt(&self, fter: &mut fmt::Formatter) -> fmt::Result {
let metoo = DebugIterableOpaque::new(self.clone());
fter.debug_struct("EntryValues")
.field("inner_iter", &metoo)
.finish()
}
}
pub struct EntryValuesMut<'a, T: ?Sized+'a>{
inner_iter: Option<slice::IterMut<'a, *mut T>>,
}
impl<'a, T: ?Sized + 'a> From<EntryValuesMut<'a, T>> for EntryValues<'a, T> {
fn from(valmut: EntryValuesMut<'a, T>) -> Self {
let EntryValuesMut { inner_iter } = valmut;
let inner_iter = inner_iter.map(|iter_mut| {
let as_slice = iter_mut.into_slice();
as_slice.iter()
});
EntryValues { inner_iter }
}
}
impl<'a, T> EntryValuesMut<'a, T>
where T: ?Sized + 'a
{
pub fn empty() -> Self {
EntryValuesMut { inner_iter: None }
}
fn new(inner_iter: slice::IterMut<'a, *mut T>) -> Self {
EntryValuesMut { inner_iter: Some(inner_iter) }
}
}
impl<'a, T: ?Sized + 'a> Iterator for EntryValuesMut<'a, T> {
type Item = &'a mut T;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.inner_iter
.as_mut()
.map(|iter| iter.next().map(|&mut ptr| unsafe { &mut *ptr }))
.unwrap_or(None)
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner_iter
.as_ref()
.map(|iter| iter.size_hint())
.unwrap_or((0, Some(0)))
}
}
impl<'a, T: ?Sized + 'a> ExactSizeIterator for EntryValuesMut<'a, T> {
#[inline]
fn len(&self) -> usize {
self.inner_iter
.as_ref()
.map(|iter| iter.len())
.unwrap_or(0)
}
}
impl<'a, T> Debug for EntryValuesMut<'a, T>
where T: ?Sized + Debug + 'a
{
fn fmt(&self, fter: &mut fmt::Formatter) -> fmt::Result {
fter.write_str("EntryValuesMut(..)")
}
}
unsafe impl<K, V> Send for TotalOrderMultiMap<K, V>
where SyncSendHelper<K,V>: Send, V: StableDeref + DerefMut, K: Hash + Eq + Copy {}
unsafe impl<K, V> Sync for TotalOrderMultiMap<K, V>
where SyncSendHelper<K,V>: Sync, V: StableDeref + DerefMut, K: Hash + Eq + Copy {}
pub struct SyncSendHelper<K, V>{ _p: ::std::marker::PhantomData<(K, V)> }
#[cfg(test)]
mod test {
use std::mem;
use std::collections::HashSet;
use super::*;
#[test]
fn convert_entry_values_mut_to_non_mut() {
let mut map = TotalOrderMultiMap::new();
map.add("k1", "v1".to_owned());
let iter: EntryValues<_> = map.get_mut("k1").into();
assert_eq!(
vec!["v1"],
iter.collect::<Vec<_>>()
);
}
#[test]
fn clone_works_fine() {
let obj_single = Box::new("hy".to_owned());
let obj_multi_a = Box::new("there".to_owned());
let obj_multi_b = Box::new("so".to_owned());
let mut used_addresses = HashSet::new();
used_addresses.insert(&*obj_single as *const String as usize);
used_addresses.insert(&*obj_multi_a as *const String as usize);
used_addresses.insert(&*obj_multi_b as *const String as usize);
let mut map = TotalOrderMultiMap::with_capacity(10);
map.add("k1", obj_single);
map.add("k2", obj_multi_a);
map.add("k2", obj_multi_b);
let map2 = map.clone();
let __map = map;
for val in map2.get("k1") {
let ptr = val as *const String as usize;
assert!(!used_addresses.contains(&ptr));
}
for val in map2.get("k2") {
let ptr = val as *const String as usize;
assert!(!used_addresses.contains(&ptr));
}
for (_k, v) in map2.iter() {
let ptr = v as *const String as usize;
assert!(!used_addresses.contains(&ptr));
used_addresses.insert(ptr);
}
assert_eq!(used_addresses.len(), 2 * map2.len());
mem::drop(__map);
mem::drop(map2);
}
#[test]
fn aux_fns() {
let mut map = TotalOrderMultiMap::with_capacity(10);
assert_eq!(true, map.is_empty());
map.add("key1", Box::new(13u32));
assert_eq!(false, map.is_empty());
map.add("key2", Box::new(1));
assert_eq!(10, map.capacity());
assert_eq!(2, map.len());
map.shrink_to_fit();
assert_eq!(2, map.capacity());
map.reserve(1);
assert!(map.capacity() >= 3);
map.add("key1", Box::new(44));
map.add("key1", Box::new(44));
assert_eq!(4, map.len());
assert!(map.capacity() >= 4);
map.clear();
assert_eq!(true, map.is_empty());
assert_eq!(0, map.len());
}
#[test]
fn works_with_trait_objects() {
use std::fmt::Debug;
let mut map = TotalOrderMultiMap::<&'static str, Box<Debug>>::new();
map.add("hy", Box::new("h".to_owned()));
map.add("hy", Box::new(2));
map.add("ho", Box::new("o".to_owned()));
let view = map.values().collect::<Vec<_>>();
assert_eq!(
"\"h\" 2 \"o\"",
format!("{:?} {:?} {:?}", view[0], view[1], view[2])
)
}
#[test]
fn get_set() {
let mut map = TotalOrderMultiMap::new();
let a = "a".to_owned();
map.add("k1", a.clone());
map.add("k1", a.clone());
map.add("k2", a.clone());
map.add("k3", "y".to_owned());
map.add("k4", "z".to_owned());
map.add("k4", "a".to_owned());
map.add("k1", "e".to_owned());
let val_k1 = map.get("k1");
assert_eq!(3, val_k1.len());
assert_eq!((3, Some(3)), val_k1.size_hint());
assert_eq!(
["a", "a", "e"],
val_k1.collect::<Vec<_>>().as_slice()
);
}
#[test]
fn get_mut() {
let ka = "aa";
let kb = "bb";
let a: Box<u32> = Box::new(12u32);
let b: Box<u32> = Box::new(13u32);
let mut map = TotalOrderMultiMap::new();
map.add(ka, a);
map.add(kb, b);
{
let mut a_vals = map.get_mut(ka);
let ref_a = a_vals.next().unwrap();
*ref_a = 44;
}
assert_eq!(2, map.len());
assert_eq!(vec![44], map.get(ka).map(|v|*v).collect::<Vec<_>>());
assert_eq!(vec![13], map.get(kb).map(|v|*v).collect::<Vec<_>>());
assert_eq!(0, map.get(&ka[..1]).len());
}
#[test]
fn truncate_longer() {
let mut map = TotalOrderMultiMap::new();
map.add("a", "hy".to_owned());
map.add("b", "ho".to_owned());
map.add("a", "urgs".to_owned());
map.truncate(10);
assert_eq!(
vec![("a", "hy"), ("b", "ho"), ("a", "urgs")],
map.iter().collect::<Vec<_>>()
);
assert_eq!(
vec!["hy", "urgs"],
map.get("a").collect::<Vec<_>>()
);
assert_eq!(
vec!["ho"],
map.get("b").collect::<Vec<_>>()
);
}
#[test]
fn truncate_a_view_elements() {
let mut map = TotalOrderMultiMap::new();
map.add("a", "hy".to_owned());
map.add("b", "ho".to_owned());
map.add("a", "urgs".to_owned());
map.add("c", "cirgs".to_owned());
map.truncate(2);
assert_eq!(
vec![("a", "hy"), ("b", "ho")],
map.iter().collect::<Vec<_>>()
);
assert_eq!(
vec!["hy"],
map.get("a").collect::<Vec<_>>()
);
assert_eq!(
vec!["ho"],
map.get("b").collect::<Vec<_>>()
);
assert_eq!(
Vec::<&'static str>::new(),
map.get("c").collect::<Vec<_>>()
);
}
#[test]
fn pop() {
let mut map = TotalOrderMultiMap::new();
map.add("k1", "hy".to_owned());
map.add("k2", "ho".to_owned());
map.add("k1", "last".to_owned());
let last = map.pop();
assert_eq!(
Some(("k1", "last".to_owned())),
last
);
}
#[test]
fn reverse() {
let mut map = TotalOrderMultiMap::new();
map.add("k1", "ok".to_owned());
map.add("k2", "why not?".to_owned());
map.reverse();
assert_eq!(
[("k2", "why not?"), ("k1", "ok")],
map.iter().collect::<Vec<_>>().as_slice()
);
}
#[test]
fn remove_all() {
let mut map = TotalOrderMultiMap::new();
map.add("k1", "ok".to_owned());
map.add("k2", "why not?".to_owned());
map.add("k1", "run".to_owned());
map.add("k2", "jump".to_owned());
let did_rm = map.remove_all("k1");
assert_eq!(true, did_rm);
assert_eq!(false, map.remove_all("not_a_key"));
assert_eq!(
[("k2", "why not?"), ("k2", "jump")],
map.iter().collect::<Vec<_>>().as_slice()
);
}
#[test]
fn retain() {
let mut map = TotalOrderMultiMap::new();
map.add("k1", "ok".to_owned());
map.add("k2", "why not?".to_owned());
map.add("k1", "run".to_owned());
map.add("k2", "uh".to_owned());
map.retain(|key, val| {
assert!(key.len() == 2);
val.len() > 2
});
assert_eq!(
[("k2", "why not?"), ("k1", "run")],
map.iter().collect::<Vec<_>>().as_slice()
);
}
trait AssertSend: Send {}
impl<K: Send, V: Send> AssertSend for TotalOrderMultiMap<K, V>
where V: StableDeref + DerefMut, K: Hash + Eq + Copy, V::Target: Sync {}
trait AssertSync: Sync {}
impl<K: Sync, V: Sync> AssertSync for TotalOrderMultiMap<K, V>
where V: StableDeref + DerefMut, K: Hash + Eq + Copy, V::Target: Sync {}
}