Skip to content

Add LowerBound to allow range scans#24

Merged
banks merged 4 commits intomasterfrom
lower-bound
May 22, 2019
Merged

Add LowerBound to allow range scans#24
banks merged 4 commits intomasterfrom
lower-bound

Conversation

@banks
Copy link
Copy Markdown
Contributor

@banks banks commented May 11, 2019

This PR adds a SeekLowerBound method to Iterator which allows for range scans of the radix tree. Lower bound seeks the iterator to the first key that is greater than or equal to some search key. The iterator can then be used to iterate in order over the rest of the values. A caller can simply stop when the result is "to high" to bound the range at the upper end.

For example, assume radix trees are sorted fixed length representation of an integer such as "00001" (these might represent timestamps or some other sparse, monotonically increasing value).

// Keys 00001 00002 00005 00006
it := tree.Root().Iterator()
it.SeekLowerBound([]byte("00003")
for key, _, ok := it.Next(); ok; key, _, ok = it.Next() {
  fmt.Printf("%s", key)
}
// Output:
//   00005
//   00006

Limitations

There is no *Watch variant of this seek method because in general there is no single node that is guaranteed to be updated when the lower bound changes (other than the root). Note that even if such an algorithm could be found, it likely isn't what callers want when using this for range scans because it only tells them that the start of the range changed not about any changes in the middle or end of the range.

Callers that need to be notified of changes must arrange for that separately, for example by watching another key that is always updated when events they care about occur, or watching the root node and comparing changes to the lower bound.

Testing

This was surprisingly subtle to get right with prefix compression. An initial implementation passed a range of example-based table tests but I wasn't confident still so wrote a Fuzz test using testing/quick which caught several fundamental flaws.

This implementation now passes table tests, including some based on simplified cases caught by fuzz testing, as well as property-based fuzz testing with random keys and comparison to a simple/naive implementation with a sorted list.

Co-Authored-By: Hans Hasselberg <me@hans.io>
Copy link
Copy Markdown
Contributor

@kyhavlov kyhavlov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great @banks! One comment typo but the implementation/tests look solid.

Co-Authored-By: Kyle Havlovitz <kylehav@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants