
The Skip list - VeXocide
http://en.wikipedia.org/wiki/Skip_list
======
silentbicycle
Previously: <http://news.ycombinator.com/item?id=229668>

First things first, read Pugh's original paper
(ftp://ftp.cs.umd.edu/pub/skipLists/skiplists.pdf). That would be the better
link, but HN doesn't let you submit links to FTP sites.

Also: A lecture I watched compared skip lists to subway routes with multiple
(randomly routed) express lines. That's one of the best metaphors for a data
structure I've ever heard.

~~~
jaydub
_A lecture I watched compared skip lists to subway routes with multiple
(randomly routed) express lines._

I had Prof. Pugh for an honors CS course @ UMD and that's how he first
described it to the class.

------
CoryOndrejka
I read Pugh's original paper in the late 90's and thought skip lists were a
heck of lot simpler than red-black trees. Ended up using them all over Second
Life's original code base. By 2004 or so we switched the code over the STL and
the LLSkipList class was retired to the dark depths of the CVS/SVN repository.

~~~
tptacek
Maybe simpler, but better? Probably not so much. I wanted red-blacks on a
project that couldn't use STL, and found that porting STLPort's <map> red-
black to C-with-void*'s was pretty straightforward. Didn't even have to write
and debug a red-black tree: <map> is bulletproof.

~~~
eru
You can even let the type system guarantee the red-black-tree laws. That's
even better than idiot-proof.
(<http://www.cs.kent.ac.uk/people/staff/smk/redblack/rb.html> has an
implementation in Haskell.)

Shouldn't trees be a nightmare to maintain without a GC? (Are you modifying
in-place?)

------
antirez
Redis sorted sets are implemented using skip lists (augmented skip lists for
O(log(N)) Rank operation in Redid master).

Redis Sorted Sets additional info here:
<http://code.google.com/p/redis/wiki/SaddCommand>

~~~
ntoshev
I was looking at Redis yesterday and noticed this. Is there any particular
reason you chose skip list instead of btrees except for simplicity? Skip lists
consume more memory in pointers and are generally slower than btrees because
of poor memory locality so traversing them means lots of cache misses.

I also suggested a way to improve throughput when you guarantee each command's
durability (at the end of the wiki page):
<http://code.google.com/p/redis/wiki/AppendOnlyFileHowto>

Also, have you thought about accommodating read-only traffic in an additional
thread as a way to utilize at least two cores efficiently while sharing the
same memory?

~~~
crux_
Without knowing how Redis works, maybe they were chosen because it's really
quite easy to build a highly concurrent (lock-free) skip list?

~~~
ntoshev
No, Redis is single-threaded so they sidestep all concurrency issues. This and
persisting the data in a forked process are my favorite parts of Redis'
architecture.

------
eru
How do you develop a persistent (i.e. purely functional) version of them?

~~~
camccann
Brief nitpicking: "persistent" and "purely functional" are not really the same
thing.

On the "purely functional" end, any stochastic algorithm is by definition not
pure in the "referentially transparent" sense, so that's right out, and
building a PRNG into the data structure is probably suboptimal.

As far as persistence/immutability go, the skip list doesn't seem well suited
to that, either--any time you change an element, you'd have to replace all the
elements with pointers to it, and elements with pointers to those, and so on
recursively. There are standard solutions to this, but all would entail
nontrivial changes to the structure.

In the end, it would be easy to make something not obviously broken that
_looked_ like a skip list, but I don't know whether it would have the same
performance characteristics, or even worthwhile performance at all.

Given that skip lists are, in essence, a way of retrofitting some of the
benefits of a tree structure onto a linked list, I suspect it would be more
worthwhile to find an existing immutable, functional tree structure and
retrofit some of the benefits of a linked list onto it.

~~~
eru
> Brief nitpicking: "persistent" and "purely functional" are not really the
> same thing.

You are right about that. But I did not have time for a longer explanation and
some people take "persistent" to mean "can be saved to disk".

For stochastic algorithms you will probably use the same trick as with monadic
I/O --- you can make the description of the algorithm purely functional, but
not its execution.

~~~
camccann
_For stochastic algorithms you will probably use the same trick as with
monadic I/O --- you can make the description of the algorithm purely
functional, but not its execution._

Certainly possible, but how well this works depends on how, and to what
extent, referential transparency is enforced by the language.

For instance, in Haskell, there really isn't a satisfying solution that I'm
aware of. Threading a PRNG (as with the state monad) keeps the code "pure",
but enforces a strict sequencing on use of the structure, wrecking laziness.
On the other hand, any nondeterminism without threading a PRNG probably
requires unsafePerformIO.

~~~
chancho
'Probabilistic' doesn't have to mean 'nondeterministic'. Hash tables are
deterministic and probabilistic. You could probably do the same with a skip
list: hash the key to see what level of the skip list it gets promoted to.

------
pkrumins
MIT Algorithms Video Lecture on skip lists:

[http://www.catonmat.net/blog/mit-introduction-to-
algorithms-...](http://www.catonmat.net/blog/mit-introduction-to-algorithms-
part-eight/)

------
keefe
It's certainly a very interesting data structure. However, I don't think this
level of an optimization should show up in your code often. I prefer coding to
Map<K,V> and constructing the particular instance in some function that starts
with a hash table and gets optimized later depending on exactly where
performance problems are.

------
lucifer
There is a very nice implementation of a concurrent skiplist map in Java
collections:
[http://java.sun.com/javase/6/docs/api/java/util/concurrent/C...](http://java.sun.com/javase/6/docs/api/java/util/concurrent/ConcurrentSkipListMap.html)

------
__bjoernd
Is this the week of posting Wikipedia links to HN then?

Interesting, though.

