Page MenuHome

BLI WAVL Tree implementation
Needs ReviewPublic

Authored by Falk David (filedescriptor) on Mar 10 2020, 11:38 AM.

Details

Summary

This patch implements the WAVL tree data structure introduced in this paper.
It also includes a set of 27 tests.

Time complexity in Big-O notation:

FunctionAverageWorst-Case
SearchO(log(n))O(log(n))
InsertionO(log(n))O(log(n))
DeletionO(log(n))O(log(n))
Access MinO(1)*O(1)*
Access MaxO(1)*O(1)*
Access PredecessorO(1)*O(1)*
Access SuccessorO(1)*O(1)*

*For every insertion and deletion, we can update the min, max, predecessor and successor of the given node. This allows us to look up these nodes (access of O(1)) but adds +O(1) to every insertion and deletion (it's basically an insertion/deletion into/from a double linked list).

Explanation as to why this is needed:
The red and black tree implementation is fine. But it's missing some things that I needed: Deletion of a node, accessing successor and predecessor in O(1) and having tests. Because doing a new implementation would take me as long as to add to the current implementation, I decided to do it this way. Additionally WAVL trees combine some of the better properties of both red and black trees and AVL trees. Namely a constant number of tree rotations for deleting and inserting a node and the fact that they are more balanced on average than red and black trees.

Diff Detail

Event Timeline

Fixed deletion of last test to be the right node

Can you explain the purpose of this? In which case is this better than our existing data structures? What do you plan to use it for?

The red and black tree implementation is fine. But it's missing some things that I need: Deletion of a node, accessing successor and predecessor in O(1) and having tests. Because doing a new implementation would take me as long as to add to the current implementation, I decided to do it this way. Additionally WAVL trees combine some of the better properties of both red and black trees and AVL trees. Namely a constant number of tree rotations for deleting and inserting a node and the fact that they are more balanced on average than red and black trees.

I plan to use this in an implementation for a sweep-line algorithm. I work on the grease pencil fill improvements with Antonio.

Remove access after free and test if tree is empty after free.

Fix dangling pointer bug and double free; update tests

Fix: tree rotations, setting a parent pointer correctly now

Fixed rebalancing the tree after deletion.
Fixed updating a node.
Added more tests.

The 27 tests I have should cover close to 100% of the code.
I think the patch is ready for review.

Falk David (filedescriptor) retitled this revision from WIP: BLI WAVL Tree implementation to BLI WAVL Tree implementation.Mar 19 2020, 8:29 AM

Sounds like this is better and more complete implementation comparing to what we have.
If it's going to be used in Blender I do not see a reason why not to add it.

Thing is, we already have a whole RB tree implementation that is only used in one or two places afaict…

Since that WAVL new thing seems to basically super-set RB algorithm (essentially allowing for same or better performances, with better handling of some operations), would it be possible to use it as well for existing RB usages? Then we could fully ditch the RB code, and not have two things doing almost the same thing to maintain?

If that would be the goal, then I suggest we compare the two in terms of time and memory performance, to make sure there are no issues there. As I stated in the description, I needed constant access time to predecessor and successor, which gives a slight increase in time performance when inserting or deleting a node. But I wouldn't know how much this affects things, so I think it might be good to compare them. If it turns out that it its noticeable, I could implement a 'simple' version of the tree, that does not give constant access to pred/succ and optimizes for fast search/insertion/deletion.