Locks on dynamically allocated memory

Hello world ! Here is the situation in which I am:

I have a certain list of objects, that will evolve during runtime. So I store them in a vector or a hash table.

Can a change in one object cause a global reallocation of the whole vector ? If it could, then My plan to prevent that is to replace a vector of objects with a vector of pointers to objects (through dynamic allocation). Can you suggest better ideas ?

Several threads of my program will need to read and write to my objects simultaneously. I would like to place a lock on each object rather than on the global vector, to make things go faster. But how can I achieve that ??

If you need to modify the HashMap, then use a structure like HashMap<Key, Arc<Mutex<Object>>>. The Arc allows each thread to (safely) have its own independent owning pointer to the value it is manipulating, and therefore not care what the HashMap is doing.

1 Like

If you modify one value inside the vector, that won't cause the vector's buffer itself to be reallocated.

Why do you care though? You shouldn't need to worry about this.

Create a Vec<Mutex<T>>.

1 Like

Thank you.

Why do you care though?

The objects are huge. Then a global realloc would be an heavy op.

The objects are huge. Then a global realloc would be an heavy op.

Two things that might be useful to notice in this case:

First, it's rare to actually have a relevantly large object without indirection. For example, a struct with many, many fields might be large, or an array might be large, but more complex structures often have at least one pointer indirection (Box, Vec, String, etc.). When a value is moved (which, yes, does happen when a Vec or HashMap grows its capacity), the indirect part isn't moved.

Second, you write “Several threads of my program will need to read and write to my objects simultaneously.” If that's the case, then Rust's thread-safety rules will require that either:

  1. &muts into elements of the container (Vec or HashMap) are given to each thread but the container itself will not be modified in a way that causes a reallocation, or

  2. The container contains some kind of cloneable pointer, like Arc<T> or &T, so reallocating the container will not interfere with continuing use of the elements.

Therefore, given that you are writing code with threads, you don't actually have to worry about expensive reallocations and moves — either in case (1) there cannot be any reallocations, or in case (2) the reallocations will not be of large structures.

1 Like

Wow. Thanks for this enlightenment !

When a value is moved the indirect part isn't moved

Happy to learn that.

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.