There's more...

Internally, you can imagine the HashMap as being implemented as two vectors: a table, and a buffer. Of course, we're simplifying here; there are actually no vectors in the implementation. But this analogy is accurate enough.

If you want to look at the actual implementation, feel free to do so, as Rust is completely open source: https://github.com/rust-lang/rust/blob/master/src/libstd/collections/hash/table.rs.

In the background, the buffer stores our values in a sequential fashion. In the front, we have a table storing buckets that don't do much more than point to the element they stand for. When you insert a key-value pair, what happens is:

  1. The value gets put in the buffer.
  2. The key goes through a hashing function and becomes an index.
  3. The table creates a bucket at said index that points to the actual value:
Rust's hashing algorithm doesn't actually generate unique indices, for performance reasons. Instead, Rust uses a clever way to handle hash collisions called Robin Hood bucket stealing (http://codecapsule.com/2013/11/11/robin-hood-hashing/).

The default hashing algorithm of the standard library has been chosen specifically to protect you from HashDoS attacks (https://cryptanalysis.eu/blog/2011/12/28/effective-dos-attacks-against-web-application-plattforms-hashdos/). If you want to squeeze out every bit of performance, you can do that, of your HashMap without caring about this particular risk, or you can specify a custom hasher by constructing it with with_hasher.

Many people have already implemented various hashers on crates.io, so make sure to check them out before rolling with your own solution.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.116.118.229