| ▲ | cremer 2 days ago | |
Redis sorted sets are probably the most widely deployed example. Redis uses a skiplist for range queries and ordered iteration paired with a hash table for O(1) lookups. Together they cover the full API at the right complexity for each operation Skiplists also win over balanced BSTs when it comes to concurrent access. Lock-free implementations are much simplier to reason about and get right. ConcurrentSkipListMap has been in the standard library since Java 6 for exactly this reason and it holds up well under high contention | ||
| ▲ | antirez 2 days ago | parent | next [-] | |
Yep, and it was simple in Redis to augment them with the "span" in order to support ranking, that is, given al element, tell me its position in the ordered collection. | ||
| ▲ | zelphirkalt 14 hours ago | parent | prev | next [-] | |
Binary search trees, at least the ones I am thinking of, have known purely functional, and therefore lock free implementations. I am currently looking into AVL trees and they don't seem that complicated of an implementation for example. | ||
| ▲ | nulltrace a day ago | parent | prev | next [-] | |
Rebalancing is what really kills you. A CAS loop on a flat list is pretty straightforward, you get it working and move on. But rotations? You've got threads mid-insert on nodes you're about to move around. It gets ugly fast. Skiplists just sidestep the whole thing since level assignment is basically a coin flip, nothing you need to keep consistent. Cache locality is worse, sure, but honestly on write-heavy paths I've never seen that be the actual bottleneck. | ||
| ▲ | maerF0x0 2 days ago | parent | prev | next [-] | |
A source: https://stackoverflow.com/a/46841708 | ||
| ▲ | ignoramous 2 days ago | parent | prev [-] | |
> Skiplists also win over balanced BSTs when it comes to concurrent access. Balanced Skiplists search better than plain Skiplists which may skew (but balancing itself is expensive). Also, I've have found that finger search (especially with doubly-linked skiplist with million+ entries) instead of always looking for elements from the root/head is an even bigger win. > ConcurrentSkipListMap has been in the standard library since Java 6 for exactly this reason and it holds up well under high contention An amusing observation I lifted from OCaml's implementation (which inturn quotes Donald Knuth): MSBs of PRNG values have more "randomness" than LSBs (randomness affects "balance"): https://github.com/ocaml/ocaml/blob/389121d3/runtime/lf_skip... --- Some neat refs from our codebase: - Skip lists: Done right (2016), https://ticki.github.io/blog/skip-lists-done-right / https://archive.is/kwhnG - An analysis of skip lists, https://eugene-eeo.github.io/blog/skip-lists.html / https://archive.is/ffCDr - Skip lists, http://web.archive.org/web/20070212103148/http://eternallyco... / https://archive.is/nl3G8 | ||