Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/krasun/rbytree
Red-black tree implementation for Go with byte-slice keys and values
https://github.com/krasun/rbytree
bst bst-tree bstree map redblack-tree redblacktree redblacktrees searchtrees tree
Last synced: 15 days ago
JSON representation
Red-black tree implementation for Go with byte-slice keys and values
- Host: GitHub
- URL: https://github.com/krasun/rbytree
- Owner: krasun
- License: mit
- Created: 2021-04-29T06:05:26.000Z (over 3 years ago)
- Default Branch: main
- Last Pushed: 2022-01-09T12:33:04.000Z (almost 3 years ago)
- Last Synced: 2024-12-09T17:00:36.915Z (17 days ago)
- Topics: bst, bst-tree, bstree, map, redblack-tree, redblacktree, redblacktrees, searchtrees, tree
- Language: Go
- Homepage:
- Size: 49.8 KB
- Stars: 2
- Watchers: 3
- Forks: 2
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# **rb**y**tree**
[![Build](https://github.com/krasun/rbytree/actions/workflows/build.yml/badge.svg?branch=main)](https://github.com/krasun/rbytree/actions/workflows/build.yml)
[![codecov](https://codecov.io/gh/krasun/rbytree/branch/main/graph/badge.svg?token=8NU6LR4FQD)](https://codecov.io/gh/krasun/rbytree)
[![Go Report Card](https://goreportcard.com/badge/github.com/krasun/rbytree)](https://goreportcard.com/report/github.com/krasun/rbytree)
[![GoDoc](https://godoc.org/https://godoc.org/github.com/krasun/rbytree?status.svg)](https://godoc.org/github.com/krasun/rbytree)A [red-black tree](https://en.wikipedia.org/wiki/Red%E2%80%93black_tree) implementation for Go with byte-slice keys and values.
## Installation
To install, run:
```
go get github.com/krasun/rbytree
```## Quickstart
Feel free to play:
```go
package mainimport (
"fmt""github.com/krasun/rbytree"
)func main() {
tree := rbytree.New()tree.Put([]byte("apple"), []byte("sweet"))
tree.Put([]byte("banana"), []byte("honey"))
tree.Put([]byte("cinnamon"), []byte("savoury"))banana, ok := tree.Get([]byte("banana"))
if ok {
fmt.Printf("banana = %s\n", string(banana))
} else {
fmt.Println("value for banana not found")
}tree.ForEach(func(key, value []byte) {
fmt.Printf("key = %s, value = %s\n", string(key), string(value))
})// Output:
// banana = honey
// key = apple, value = sweet
// key = banana, value = honey
// key = cinnamon, value = savoury
}
```You can use an iterator:
```go
package mainimport (
"fmt""github.com/krasun/rbytree"
)func main() {
tree := rbytree.New()tree.Put([]byte("apple"), []byte("sweet"))
tree.Put([]byte("banana"), []byte("honey"))
tree.Put([]byte("cinnamon"), []byte("savoury"))banana, ok := tree.Get([]byte("banana"))
if ok {
fmt.Printf("banana = %s\n", string(banana))
} else {
fmt.Println("value for banana not found")
}for it := tree.Iterator(); it.HasNext(); {
key, value := it.Next()
fmt.Printf("key = %s, value = %s\n", string(key), string(value))
}// Output:
// banana = honey
// key = apple, value = sweet
// key = banana, value = honey
// key = cinnamon, value = savoury
}
```An iterator is stateful. You can have multiple iterators without any impact on each other, but make sure to synchronize access to them and the tree in a concurrent environment.
Caution! `Next` panics if there is no next element. Make sure to test for the next element with `HasNext` before.
## Use cases
1. When you want to use []byte as a key in the map.
2. When you want to iterate over keys in map in sorted order.## Limitations
**Caution!** To guarantee that the red-black tree properties are not violated, keys are copied.
You should clearly understand what []byte slice is and why it is dangerous to use it as a key. Go language authors do prohibit using byte slice ([]byte) as a map key for a reason. The point is that you can change the values of the key and thus violate the invariants of map:
```go
// if it worked
b := []byte{1}
m := make(map[[]byte]int)
m[b] = 1b[0] = 2 // it would violate the invariants
m[[]byte{1}] // what do you expect to receive?
```So to make sure that this situation does not occur in the tree, the key is copied byte by byte.
## Benchmark
Regular Go map is as twice faster for put and get than red-black tree. But if you
need to iterate over keys in sorted order, the picture is sligthly different:```
$ go test -benchmem -bench .
goos: darwin
goarch: amd64
pkg: github.com/krasun/rbytree
BenchmarkTreePut-8 330 3573752 ns/op 1040040 B/op 49902 allocs/op
BenchmarkMapPut-8 496 2477226 ns/op 1732586 B/op 20151 allocs/op
BenchmarkTreePutRandomized-8 260 4394145 ns/op 1040029 B/op 49901 allocs/op
BenchmarkMapPutRandomized-8 630 1890784 ns/op 981565 B/op 20111 allocs/op
BenchmarkMapGet-8 1496 768210 ns/op 38880 B/op 9900 allocs/op
BenchmarkTreeGet-8 723 1604544 ns/op 38880 B/op 9900 allocs/op
BenchmarkTreePutAndForEach-8 300 4056864 ns/op 1040043 B/op 49903 allocs/op
BenchmarkMapPutAndIterateAfterSort-8 202 5559646 ns/op 2558408 B/op 20173 allocs/op
PASS
ok github.com/krasun/rbytree 12.096s
```## Tests
Run tests with:
```
$ go test -cover .
ok github.com/krasun/rbytree 0.245s coverage: 100.0% of statements
```## Known Usages
1. [krasun/lsmtree](https://github.com/krasun/lsmtree) - my experimental implementation of [log-structured merge-tree](https://en.wikipedia.org/wiki/Log-structured_merge-tree).
## License
**rb**y**tree** is released under [the MIT license](LICENSE).