First pass at porting MVCC architecture from hlld
First pass at porting MVCC architecture from hlld

Since bloomd/hlld share a similar internal architecture,
we are porting the hlld improved MVCC system. Here is the
changelist from that system:

The old MVCC architecture was based on having multiple concurrent
'versions'. Each version is associated with an ART tree, and
potentially a set that should be deleted. The vacuum thread
would then opportunistically clean old versions and delete old filters.
The reads would always be against the latest version in a non-blocking
manner.

The main difficulty with this is that the creation of a new version
was expensive, and grows more so as the number of filters increases.
This is due to the expensive copy of the ART tree.

To avoid this, we now switch to a lighter MVCC architecture.
There are still versions, but now there are only 2 ART trees.
The "primary" and "alternate". Reads against the primary are
non-locked, and done by the clients. The "alternate" is only
accessed by the vacuum thread. Instead, we add a new "delta"
list. This delta list contains filters that have been created
or deleted but not yet merged into the ART tree.

When searching for a filter, we search the tree first, and then
the delta list on a miss. The vacuum thread periodically merges
the delta updates into the alternate tree, and atomically swaps
trees.

Once the tree is swapped, it waits until all clients stop using
the old primary, and then merges the delta updates into that
tree as well, so that both trees are in sync.

This new architecture means that creating a new version is
O(1), as we just add a new delta update. It also means the memory
overhead is fixed at 2 ART trees, instead of being largely unbounded.

mcanthony/bloomd,armon/bloomd,mcanthony/bloomd,mcanthony/bloomd,armon/bloomd,armon/bloomd