Am I passing a pointer to the same data or copying something around?

#1

I have the following type

RwLock<HashMap<String, Arc<RwLock<User>>>>

The idea is to make sure there are no concurrent inserts to the map and to be able to edit the actual entry of the user by unlocking the map in read mode.

In go what i want would look like

struct{
    sync.RWMutex
    users:map[string]*struct{
        sync.RWMutex,
        *User
    }
}

The main goal is to make the user internally mutable while still being able to use guarantees of rust at compile time.

PS.
These are methods im using to update the original user


    pub fn get_mut(&self, uid: &str) -> Option<Arc<RwLock<User>>>
    {
        if let Some(u) = self.users.read().unwrap().get(uid)
        {
            Some(u.clone())
        }
        else
        {
            None
        }
    }

    pub fn update_token(&self, uid: &str, token: &str)
    {
        if let Some(u) = self.get_mut(uid)
        {
            u.write().unwrap().token = token.to_string();
        }
    }
#2

Hi, if your question is about Some(u.clone()), you are just copying the Arc, the only copying I see is token.to_string().
But I don’t think your data structure do what you expect, I made a playground.

#3

Some people write Arc::clone(&u) instead to make it clearer that it’s just reference count increase, not a clone of the data.

BTW, there is a convenience method that can replace your match:

self.users.read().unwrap().get(uid).map(|u| u.clone())
1 Like
#4

Your playground example is identical to mine am i missing something?

#5

I just wanted to point out that the HashMap’s lock is only locked during get_mut()

if let Some(u) = self.get_mut(uid)
{
    // self isn't locked anymore
    // an other thread can do anything with it
    u.write().unwrap().token = token.to_string();
}

I don’t know if it’s important.

#6

thats exactly what i want. I am updating the user data internally so some other piece of the data should and must be accessed meanwhile and it is safe @leudz