Swiss Tables
abseil.io
abseil.io
position = (hash>>4) & mask
test = set1_16x8(hash&0xf) | 0xf0e0d0c0b0a090807060504030201000
candidates = eq_16x8(load_16x8(table + position), test)
// convert candidates to mask and test each optionhttps://www.bytesizego.com/blog/go-124-swiss-table-maps
I'd be interested to see how the new Tiny Pointers algorithm would perform against Swiss Tables, specially when occupation rate is high.
https://www.quantamagazine.org/undergraduate-upends-a-40-yea...
> The team’s results may not lead to any immediate applications, but that’s not all that matters, Conway said. “It’s important to understand these kinds of data structures better. You don’t know when a result like this will unlock something that lets you do better in practice.”
This was a Closed Addressing aka Separate Chaining table. The idea is easy enough that it's actually an Advent Of Code problem one year which is why this design is much older than the modern efficient Open Addressing tables. In C++ with std::unordered_map you are guaranteed that the address of items in the table won't change while they're in the table, this works because they're not actually stored directly in the table. You also provided an API to work with these chains of related items and to fiddle with "how full" the table is.
This API makes complete sense for a Closed Addressing table, but both the API functions and the pointer stability guarantee don't make any sense for Open Addressing.
If you only need the pointer stability you can pay just for that, Abseil offers a compatible type with that property, but if you need all the Chaining APIs (and you might in principle) then it doesn't have those, too bad.
It's design is clearly inspired by abseil::flat_map but improves it in a few aspects.
boost::unordered_map is a drop-in replacement for std::unordered_map and as such uses seperate chaining.
Anyway, thanks for the video!
It seems to be a way to arrange a hashtable so you use most of the hashed value (H1) to identify a range of cells in your table, and the rest of the hashed value (H2) as metadata. In the metadata for a cell it's tagged as empty/full/deleted and a full cell is also tagged with its H2 value
So when looking up things you find the range with H1, then you check H2 against the metadata for that range, to see which of the cells might contain the right value.
I imagine the benefit is that checking H2 against warm metadata is cache friendly and can use vector instructions, whereas with regular double hashing you'd need to lookup cold memory to check the key, and then perhaps do it again a couple of times
Do correct me if I am wrong
If those phrases don't make sense, Wikipedia has entries on Open Addressing and on SIMD which can help you.
so there is a kinda sorta "balancing" of the linear probing lengths.
CppCon 2017: Matt Kulukundis “Designing a Fast, Efficient, Cache-friendly Hash Table, Step by Step” : https://www.youtube.com/watch?v=ncHmEUmJZf4
As swiss tables are new to me I looked around a bit and found this to be a better explanation