Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I store multiple elements in a Rust HashMap for the same key?

I have a HashMap<u32, Sender>. Sender is a open connection object and the key is a user id. Each user can connect from multiple devices. I need to store all possible open connections for the same user id. After this I can iterate and send messages to all open connections for same user.

The above HashMap only stores each user id and connection once. I need to get one key with multiple values. How can I make the value into a list or an array, so I can see which connections exist and send to them all?

I am not talking about different value types, like enums. I am talking about the same type values but more than one. Maybe HashMap is not designed for this?

Alternative ideas are also welcomed.

like image 415
Dennis Avatar asked Jul 29 '18 21:07

Dennis


People also ask

Can a map have two values with the same key?

However, none of the existing Java core Map implementations allow a Map to handle multiple values for a single key. As we can see, if we try to insert two values for the same key, the second value will be stored, while the first one will be dropped.

How do Hashmaps work rust?

Hashmap in rust is a structure which comprises of the look-up table and data in it in form of key and value pair which will be used for storing and retrieving data continuously. Hashmap needs to be explicitly imported from the rust inbuilt library collection before that can be used within the program.

Is HashMap ordered rust?

HashMap s are inherently unordered collections, and BTree s are inherently ordered by their keys.

What are Hashmaps good for?

Hashmaps are probably the most commonly used implementation of the concept of a map. They allow arbitrary objects to be associated with other arbitrary objects. This can be very useful for doing things like grouping or joining data together by some common attribute.


1 Answers

To do this with a HashMap you should use a Vec as the values, so that each key can point to multiple Senders. The type then would be HashMap<u32, Vec<Sender>>.

Using this structure, just using insert() can get clunky when you need to mutate the values like this, but instead you can use the Entry API for retrieving and updating records in one go. For example:

let mut hash_map: HashMap<u32, Vec<Sender>> = HashMap::new();

hash_map.entry(3)
    // If there's no entry for key 3, create a new Vec and return a mutable ref to it
    .or_default()
    // and insert the item onto the Vec
    .push(sender); 

You could also use the multimap crate, which does something similar under the hood, but adds a layer of abstraction. You might find it easier to work with:

let mut multi_map = MultiMap::new();

multi_map.insert(3, sender_1);
multi_map.insert(3, sender_2);

The method multi_map.get(key) will the first value with that key, while multi_map.get_vec(key) will retrieve all of them.

like image 152
Peter Hall Avatar answered Oct 02 '22 11:10

Peter Hall