GithubHelp home page GithubHelp logo

krasun / rbytree Goto Github PK

View Code? Open in Web Editor NEW
2.0 3.0 2.0 51 KB

Red-black tree implementation for Go with byte-slice keys and values

License: MIT License

Go 100.00%
redblacktree tree bst bst-tree redblack-tree redblacktrees bstree searchtrees map

rbytree's Introduction

rbytree

Build codecov Go Report Card GoDoc

A red-black 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:

package main

import (
	"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:

package main

import (
	"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:

// if it worked 
b := []byte{1}
m := make(map[[]byte]int)
m[b] = 1

b[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 - my experimental implementation of log-structured merge-tree.

License

rbytree is released under the MIT license.

rbytree's People

Stargazers

 avatar  avatar

Watchers

 avatar  avatar  avatar

rbytree's Issues

Document iterator

Document iterator and that it is not safe to modify the tree while iterating.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.