Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use std::hash::Hash;
- use std::pin::Pin;
- use std::ptr::NonNull;
- use std::collections::HashMap;
- use std::marker::Unpin;
- use std::ops::Deref;
- use std::ops::DerefMut;
- trait MultiLookup {
- type FirstKey: Hash + Eq + Clone;
- type SecondKey: Hash + Eq + Clone;
- fn index_one(&self) -> Self::FirstKey;
- fn index_two(&self) -> Self::SecondKey;
- }
- struct MultiLookupMap<K>
- where K: MultiLookup {
- by_one: HashMap<K::FirstKey, Pin<Box<K>>>,
- by_two: HashMap<K::SecondKey, NonNull<K>>,
- }
- impl<K> MultiLookupMap<K>
- where K: MultiLookup + Unpin {
- pub fn new() -> Self {
- MultiLookupMap{ by_one: HashMap::new(), by_two: HashMap::new() }
- }
- pub fn insert(&mut self, val: K) {
- let idx_one = val.index_one();
- let idx_two = val.index_two();
- let mut pinned = Box::pin(val);
- self.by_one.insert(idx_one.clone(), pinned);
- //let mut inserted: &Pin<Box<K>> = self.by_one.get_mut(&idx_one).unwrap();
- let ptr = unsafe { Pin::deref_mut(self.by_one.get_mut(&idx_one).unwrap()) as *mut K};
- self.by_two.insert(idx_two, unsafe { NonNull::new_unchecked(ptr) });
- }
- pub fn get(&self, key: &K::FirstKey) -> Option<&K> {
- match self.by_one.get(key) {
- Some(val) => Some(unsafe { val.deref() }),
- None => None,
- }
- }
- pub fn get_second(&self, key: &K::SecondKey) -> Option<&K> {
- match self.by_two.get(key) {
- Some(val) => Some(unsafe{ val.as_ref() }),
- None => None,
- }
- }
- }
- #[derive(Debug)]
- struct Example {
- first: usize,
- second: u32,
- val: bool,
- }
- impl MultiLookup for Example {
- type FirstKey = usize;
- type SecondKey = u32;
- fn index_one(&self) -> usize {
- self.first
- }
- fn index_two(&self) -> u32 {
- self.second
- }
- }
- fn main() {
- let ex1 = Example{first: 10, second: 20, val: true};
- let ex2 = Example{first:4, second: 12, val: false};
- let mut map: MultiLookupMap<Example> = MultiLookupMap::new();
- map.insert(ex1);
- map.insert(ex2);
- println!("{:?}", map.get(&10));
- println!("{:?}", map.get_second(&20));
- println!("{:?}", map.get(&4));
- println!("{:?}", map.get_second(&12));
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement