tidwall cfc65a13f6 Refactor repository and build scripts
This commit includes updates that affects the build, testing, and
deployment of Tile38.

- The root level build.sh has been broken up into multiple scripts
  and placed in the "scripts" directory.

- The vendor directory has been updated to follow the Go modules
  rules, thus `make` should work on isolated environments. Also
  some vendored packages may have been updated to a later
  version, if needed.

- The Makefile has been updated to allow for making single
  binaries such as `make tile38-server`. There is some scaffolding
  during the build process, so from now on all binaries should be
  made using make. For example, to run a development version of
  the tile38-cli binary, do this:
     make tile38-cli && ./tile38-cli
  not this:
     go run cmd/tile38-cli/main.go

- Travis.CI docker push script has been updated to address a
  change to Docker's JSON repo meta output, which in turn fixes
  a bug where new Tile38 versions were not being properly pushed
  to Docker
2019-11-18 10:33:15 -07:00

89 lines
3.2 KiB
Markdown

# `R!tree`
[![GoDoc](https://godoc.org/github.com/tidwall/rbang?status.svg)](https://godoc.org/github.com/tidwall/rbang)
This package provides an in-memory R-Tree implementation for Go. It's designed
for [Tile38](https://github.com/tidwall/tile38) and is optimized for fast rect
inserts and replacements.
<img src="cities.png" width="512" height="256" border="0" alt="Cities">
## Usage
### Installing
To start using R!Tree, install Go and run `go get`:
```sh
$ go get -u github.com/tidwall/rbang
```
### Basic operations
```go
// create a 2D RTree
var tr rbang.RTree
// insert a point
tr.Insert([2]float64{-112.0078, 33.4373}, [2]float64{-112.0078, 33.4373}, "PHX")
// insert a box
tr.Insert([2]float64{10, 10}, [2]float64{20, 20}, "rect")
// search
tr.Search([2]float64{-112.1, 33.4}, [2]float64{-112.0, 33.5},
func(min, max [2]float64, value interface{}) bool {
println(value.(string)) // prints "PHX"
},
)
// delete
tr.Delete([2]float64{-112.0078, 33.4373}, [2]float64{-112.0078, 33.4373}, "PHX")
```
## Algorithms
This implementation is a variant of the original paper:
[R-TREES. A DYNAMIC INDEX STRUCTURE FOR SPATIAL SEARCHING](http://www-db.deis.unibo.it/courses/SI-LS/papers/Gut84.pdf)
### Inserting
Same as the original algorithm. From the root to the leaf, the boxes which will incur the least enlargment are chosen. Ties go to boxes with the smallest area.
### Deleting
Same as the original algorithm. A target box is deleted directly. When the number of children in a box falls below it's minumum entries, it is removed from the tree and it's items are re-inserted.
### Splitting
This is a custom algorithm.
It attempts to minimize intensive operations such as pre-sorting the children and comparing overlaps & area sizes.
The desire is to do simple single axis distance calculations each child only once, with a target 50/50 chance that the child might be moved in-memory.
When a box has reached it's max number of entries it's largest axis is calculated and the box is split into two smaller boxes, named `left` and `right`.
Each child boxes is then evaluated to determine which smaller box it should be placed into.
Two values, `min-dist` and `max-dist`, are calcuated for each child.
- `min-dist` is the distance from the parent's minumum value of it's largest axis to the child's minumum value of the parent largest axis.
- `max-dist` is the distance from the parent's maximum value of it's largest axis to the child's maximum value of the parent largest axis.
When the `min-dist` is less than `max-dist` then the child is placed into the `left` box.
When the `max-dist` is less than `min-dist` then the child is placed into the `right` box.
When the `min-dist` is equal to `max-dist` then the child is placed into an `equal` bucket until all of the children are evaluated.
Each `equal` box is then one-by-one placed in either `left` or `right`, whichever has less children.
## Performance
In my testing:
- Insert show similar performance as the quadratic R-tree and ~1.2x - 1.5x faster than R*tree.
- Search and Delete is ~1.5x - 2x faster than quadratic and about the same as R*tree.
I hope to provide more details in the future.
## License
`rbang` source code is available under the MIT License.