Visualisation of an RRB-Tree

Improving RRB-Tree Performance through Transience

So I finally managed to recover from my 8 week long all-nighter where I finished my thesis, immediately followed by moving halfway across a very long country[1]. Source code is available at

My master's thesis is available at and the abstract is below:


The RRB-tree is a confluently persistent data structure based on the persistent vector, with efficient concatenation and slicing, and effectively constant time indexing, updates and iteration. Although efficient appends have been discussed, they have not been properly studied.

This thesis formally describes the persistent vector and the RRB-tree, and presents three optimisations for the RRB-tree which have been successfully used in the persistent vector. The differences between the implementations are discussed, and the performance is measured. To measure the performance, the C library librrb is implemented with the proposed optimisations.

Results shows that the optimisations improves the append performance of the RRB-tree considerably, and suggests that its performance is comparable to mutable array lists in certain situations.


I think it should be noted that I do not know any type theory at all, so take the notation in Chapter 4 and 7 with a grain of salt. The intention is not to introduce proper type theory notation, but rather explain what transience/transients are. I'd love some feedback on how to improve those parts by seasoned type theorists.

Intended Audience

If you just want a basic understanding of how the persistent vector works, have a look at my blogpost series on the persistent vector instead. Additionally, I'd recommend going to the persistent data structure presentation by Dann Toliver on StrangeLoop this year (2014) if you're going. I do not know the guy, but I know visualisation helped me incredibly much with understanding how they worked.

If you want to understand the RRB-tree, you can do one of two things:

  1. Read the original paper on RRB-trees and watch this youtube video. If it's still not evident (I found it somewhat dense), attempt to read my thesis.
  2. Wait for me to write a blogpost series on the RRB-tree. (No guarantees!)

Why do I mention this? Well, it turns out that most theses are intended for academics, and this one is not an exception. It's not that I want the thing to be unreadable – far from it – but I felt the need to prove a considerable amount of stuff to back up my claims. As a result, my thesis is very math-y and there are a lot of details in it. While it's not necessarily a problem, I don't want people unfamiliar with mathematical notation to be scared away from the persistent vector data structure family.

The mathematics is not "advanced", mind you. If you want to follow the proofs, you have to understand geometric series, logarithmic identities, and L'Hôpital's rule. Additionally, you should be familiar with computational complexity theory (understanding what Big-O notation is, and its cousin Theta notation). It's probably not easy to understand it all at first read, but I think it's not really required if you want to skim through the thesis. I try to give an informal explanation alongside the formal one to make it understandable for everyone.

If you want to really understand these data structures, or want to implement them, I think you should read it regardless of your background. Apart from the math parts described above, the thesis is designed to not require much background knowledge. The only thing you have to know is the trie data structure.

What's Next for RRB-Trees?

First and foremost, I want to release librrb. I do need to clean up a couple of things; I want to make the source code understandable before publishing it. The source will be released under the MIT license, and hopefully it should be relatively easy to port it to other languages. Edit: The source code is now available!

Secondly, transience is actually a really easy concept, so I'd like to do a quick explanation on how it works. It's the final piece for explaining the Clojure's persistent vector blog series[2].

My thesis does not contain anything about the core.rrb-vector library, as I unfortunately didn't get enough time to write a good comparison: There's sadly no explanation on how the optimisations in core.rrb-vector works, and deciphering imperative Clojure code is not my strongest skill. I think that's the biggest weakness of my thesis, because Michał Marczyk has done an amazing job on the library.

But from what I gather, the core.rrb-vector has a tail and support for transients. It does not seem to use the direct append technique, but does something very similar. I'll have to look at the implementation in detail and attempt to comprehend it whenever I get time enough to do so, so that I can learn the differences and do a writeup on it.

I also have some thoughts on visualising the persistent vector and the RRB-tree, but I'll wait until Dann Toliver presents his talk. No need to reinvent the wheel if it's already good enough :)


I'd be happy to get feedback/errata and answer any questions you might have. Please email me with them: I'll fix them whenever I get time, and upload a new version with some revision history added.

Additional Information

The design of my thesis was initially stolen from Bastian Müller, from his thesis "Efficient Dynamic Method Dispatch on the Java Virtual Machine", which was an attempt to replicate the design of Dave Hermann's dissertation "A Theory of Typed Hygienic Macros". It's very similar to the template I've open sourced as tethysthesis, but there are a couple of (mostly unnoticeable) changes I need to merge in.

If you want to refer to my thesis, the BibTeX entry is here:

    author = {L'orange, Jean Niklas},
    title  = {{Improving RRB-Tree Performance through Transience}},
    school = {Norwegian University of Science and Technology},
    year   = {2014},
    month  = {June}

If you want to host my thesis at your webpage or parts of it, you're of course free to do so. I'd be happy if you refer to the original as I will update it to fix errata (

[1] And not being able to join EuroClojure for that exact reason. :(

[2] Not the last piece in the series though – I want to explain displays which exist in Scala, and give some performance measurements as well. But all in due time.

Tagged with: clojure, algdat.