Best approch for two key hashmap?

I'm trying to create a struct similar to Hashmap but which can lookup via either key A or key B.
If found two possible solutions:

  • Using Rc, but it make impossible to get a mut ref on Entry
  • Using a B to A hashmap, but it's involves two lookup to get the entry

Since I'm pretty new to Rust, I don't know if two lookup it's that bad or if there is a more elegant way to solve this.

pub struct Entry<A, B, T> {
    pub value: T,
    pub key_a: A,
    pub key_b: B,

pub struct Register<A, B, T>
    a: HashMap<A, Rc<Entry<A, B, T>>>,
    b: HashMap<B, Rc<Entry<A, B, T>>>

pub struct Register2<A, B, T>
    a: HashMap<A, Entry<A, B, T>>,
    b_to_a: HashMap<B, A>

I don't know what the best approach is. There's even more alternatives (I'm not claiming that any of those are necessarily better, either); you could something like qcell::QCell to re-gain the ability to mutate entries for your Rc approach

pub struct Register3<A, B, T>
    owner: QCellOwner,
    a: HashMap<A, Rc<QCell<Entry<A, B, T>>>>,
    b: HashMap<B, Rc<QCell<Entry<A, B, T>>>>,

you could store the entries in a vector and use the hash maps to get the index

pub struct Register4<A, B, T>
    a: HashMap<A, usize>,
    b: HashMap<B, usize>,
    data: Vec<Entry<A, B, T>>,

(in this case, removing items could use swap_remove on the vec and would need to update the index entries in the hash maps for both the removed item (removing the entries) and the one swapped into its place (updating the entries), unless the removed item was the last item)

1 Like

You could have two hashmaps that map key to an index, and a Vec that stores the items at the given index. It's simple if you're only appending, and requires a bit of extra bookkeeping if you support removal.

Rust's generics and borrow checking add a layer of complexity here, but apart from that the problem is fundamental: where the data is stored, which of the keys is the primary key if any (for locality of access), and how do you ensure consistency across two indexes of the data.


This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.