0

Hello Im a RUST begginer Im dealing with some Borrowing issues that I can't solve

I want to make a Concurrent Map, I saw some examples to do it where I need it and it works, but now I want to generalize the solution writing my own mod.

Here it is

use std::collections::HashMap;
use std::hash::Hash;
use std::sync::Mutex;

pub struct ConcurrentMap<K, V> {
    elems: Mutex<HashMap<K, V>>,
}

impl<K: Hash + Eq, V> ConcurrentMap<K, V> {
    pub fn new() -> ConcurrentMap<K, V> {
        let map: HashMap<K, V> = HashMap::new();
        ConcurrentMap {
            elems: Mutex::new(map),
        }
    }

    pub fn get(&self, k: &K) -> Option<&V> {
        let map = self.elems.lock();
        match map {
            Ok(t) => {
                return match t.get(k) {
                    None => None,
                    Some(v) => Some(v),
                }
            }
            Err(e) => panic!("GET Concurrent Map Error: {}", e),
        }
    }
}

My problem is in Some(v) => Some(v) line, I dont know how to copy the value.

If I make that V implement Copy trait then I can't use this Map to store String because String does not implement Copy trait.

Maybe the last matching is not necessary but is the last thing I tried.

Germán Faller
  • 546
  • 7
  • 15

1 Answers1

0

As @loganfsmyth suggested, I implemented Clone insted of Copy trait in V(alue) type.

Also, as I mention, I changed last matching with a simple Map combinator

So this is how it looks now

use std::collections::HashMap;
use std::hash::Hash;
use std::sync::Mutex;

pub struct ConcurrentMap<K, V> {
    elems: Mutex<HashMap<K, V>>,
}

impl<K: Hash + Eq, V: Clone> ConcurrentMap<K, V> {
    pub fn new() -> ConcurrentMap<K, V> {
        let map: HashMap<K, V> = HashMap::new();
        ConcurrentMap {
            elems: Mutex::new(map),
        }
    }

    pub fn insert(&self, k: K, v: V) {
        let map = self.elems.lock();
        match map {
            Ok(mut t) => t.insert(k, v),
            Err(e) => panic!("INSERT Concurrent Map Error: {}", e),
        };
    }

    pub fn get(&self, k: K) -> Option<V> {
        let map = self.elems.lock();
        match map {
            Ok(t) => t.get(&k).map(|v| v.clone()),           
            Err(e) => panic!("GET Concurrent Map Error: {}", e),
        }
    }
}

Usage example:

lazy_static! {
    static ref PROPERTIES: ConcurrentMap<String, String> = ConcurrentMap::new();
}

PROPERTIES.insert("Key".to_string(), "val".to_string());
PROPERTIES.get("Key".to_string()).unwrap().to_string();
Germán Faller
  • 546
  • 7
  • 15