{"id":13593431,"url":"https://github.com/davidmoten/rtree","last_synced_at":"2025-05-14T00:10:06.096Z","repository":{"id":20081751,"uuid":"23350791","full_name":"davidmoten/rtree","owner":"davidmoten","description":"Immutable in-memory R-tree and R*-tree implementations in Java with reactive api","archived":false,"fork":false,"pushed_at":"2025-04-03T11:55:18.000Z","size":1880,"stargazers_count":1116,"open_issues_count":33,"forks_count":213,"subscribers_count":57,"default_branch":"master","last_synced_at":"2025-04-10T19:08:01.710Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"bruhautomation/BRUH2-Home-Assistant-Configuration","license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/davidmoten.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2014-08-26T12:29:14.000Z","updated_at":"2025-04-10T15:48:17.000Z","dependencies_parsed_at":"2024-05-06T03:25:35.013Z","dependency_job_id":"c43ad17d-52d4-4742-8619-6539fcab8c59","html_url":"https://github.com/davidmoten/rtree","commit_stats":{"total_commits":1241,"total_committers":12,"mean_commits":"103.41666666666667","dds":"0.11361804995970992","last_synced_commit":"77b62a819b02b5e000f67f15ad839878cbbbe30f"},"previous_names":[],"tags_count":56,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davidmoten%2Frtree","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davidmoten%2Frtree/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davidmoten%2Frtree/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davidmoten%2Frtree/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/davidmoten","download_url":"https://codeload.github.com/davidmoten/rtree/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254044258,"owners_count":22005116,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T16:01:20.228Z","updated_at":"2025-05-14T00:10:01.087Z","avatar_url":"https://github.com/davidmoten.png","language":"Java","funding_links":[],"categories":["Java","Memory and concurrency"],"sub_categories":[],"readme":"rtree\n=========\n\u003ca href=\"https://github.com/davidmoten/rtree/actions/workflows/ci.yml\"\u003e\u003cimg src=\"https://github.com/davidmoten/rtree/actions/workflows/ci.yml/badge.svg\"/\u003e\u003c/a\u003e\u003cbr/\u003e\n[![Coverity Scan](https://scan.coverity.com/projects/4762/badge.svg?flat=1)](https://scan.coverity.com/projects/4762?tab=overview)\u003cbr/\u003e\n[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.davidmoten/rtree/badge.svg?style=flat)](https://maven-badges.herokuapp.com/maven-central/com.github.davidmoten/rtree)\u003cbr/\u003e\n[![codecov](https://codecov.io/gh/davidmoten/rtree/branch/master/graph/badge.svg)](https://codecov.io/gh/davidmoten/rtree)\n\n\nIn-memory immutable 2D [R-tree](http://en.wikipedia.org/wiki/R-tree) implementation in java using [RxJava Observables](https://github.com/ReactiveX/RxJava) for reactive processing of search results. \n\nStatus: *released to Maven Central*\n\nNote that the **next version** (without a reactive API and without serialization) is at [rtree2](https://github.com/davidmoten/rtree2).\n\nAn [R-tree](http://en.wikipedia.org/wiki/R-tree) is a commonly used spatial index.\n\nThis was fun to make, has an elegant concise algorithm, is thread-safe, fast, and reasonably memory efficient (uses structural sharing).\n\nThe algorithm to achieve immutability is cute. For insertion/deletion it involves recursion down to the \nrequired leaf node then recursion back up to replace the parent nodes up to the root. The guts of \nit is in [Leaf.java](src/main/java/com/github/davidmoten/rtree/internal/LeafDefault.java) and [NonLeaf.java](src/main/java/com/github/davidmoten/rtree/internal/NonLeafDefault.java).\n\n[Backpressure](https://github.com/ReactiveX/RxJava/wiki/Backpressure) support required some complexity because effectively a\nbookmark needed to be kept for a position in the tree and returned to later to continue traversal. An immutable stack containing\n the node and child index of the path nodes came to the rescue here and recursion was abandoned in favour of looping to prevent stack overflow (unfortunately java doesn't support tail recursion!).\n\nMaven site reports are [here](http://davidmoten.github.io/rtree/index.html) including [javadoc](http://davidmoten.github.io/rtree/apidocs/index.html).\n\nFeatures\n------------\n* immutable R-tree suitable for concurrency\n* Guttman's heuristics (Quadratic splitter) ([paper](https://www.google.com.au/url?sa=t\u0026rct=j\u0026q=\u0026esrc=s\u0026source=web\u0026cd=1\u0026cad=rja\u0026uact=8\u0026ved=0CB8QFjAA\u0026url=http%3A%2F%2Fpostgis.org%2Fsupport%2Frtree.pdf\u0026ei=ieEQVJuKGdK8uATpgoKQCg\u0026usg=AFQjCNED9w2KjgiAa9UI-UO_0eWjcADTng\u0026sig2=rZ_dzKHBHY62BlkBuw3oCw\u0026bvm=bv.74894050,d.c2E))\n* R*-tree heuristics ([paper](http://dbs.mathematik.uni-marburg.de/publications/myPapers/1990/BKSS90.pdf))\n* Customizable [splitter](src/main/java/com/github/davidmoten/rtree/Splitter.java) and [selector](src/main/java/com/github/davidmoten/rtree/Selector.java)\n* 10x faster index creation with STR bulk loading ([paper](https://www.researchgate.net/profile/Scott_Leutenegger/publication/3686660_STR_A_Simple_and_Efficient_Algorithm_for_R-Tree_Packing/links/5563368008ae86c06b676a02.pdf)).\n* search returns [```Observable```](http://reactivex.io/RxJava/javadoc/rx/Observable.html) \n* search is cancelled by unsubscription\n* search is ```O(log(n))``` on average\n* insert, delete are ```O(n)``` worst case\n* all search methods return lazy-evaluated streams offering efficiency and flexibility of functional style including functional composition and concurrency\n* balanced delete\n* uses structural sharing\n* supports [backpressure](https://github.com/ReactiveX/RxJava/wiki/Backpressure)\n* JMH benchmarks\n* visualizer included\n* serialization using [FlatBuffers](http://github.com/google/flatbuffers)\n* high unit test [code coverage](http://davidmoten.github.io/rtree/cobertura/index.html) \n* R*-tree performs 900,000 searches/second returning 22 entries from a tree of 38,377 Greek earthquake locations on i7-920@2.67Ghz (maxChildren=4, minChildren=1). Insert at 240,000 entries per second.\n* requires java 1.6 or later\n\nNumber of points = 1000, max children per node 8: \n\n| Quadratic split | R*-tree split | STR bulk loaded |\n| :-------------: | :-----------: | :-----------: |\n| \u003cimg src=\"src/docs/quad-1000-8.png?raw=true\" /\u003e | \u003cimg src=\"src/docs/star-1000-8.png?raw=true\" /\u003e | \u003cimg src=\"src/docs/str-1000-8.png?raw=true\" /\u003e |\n\n\nNotice that there is little overlap in the R*-tree split compared to the \nQuadratic split. This should provide better search performance (and in general benchmarks show this).\n\nSTR bulk loaded R-tree has a bit more overlap than R*-tree, which affects the search performance at some extent.\n\nGetting started\n----------------\nAdd this maven dependency to your pom.xml:\n\n```xml\n\u003cdependency\u003e\n  \u003cgroupId\u003ecom.github.davidmoten\u003c/groupId\u003e\n  \u003cartifactId\u003ertree\u003c/artifactId\u003e\n  \u003cversion\u003eVERSION_HERE\u003c/version\u003e\n\u003c/dependency\u003e\n```\n### Instantiate an R-Tree\nUse the static builder methods on the ```RTree``` class:\n\n```java\n// create an R-tree using Quadratic split with max\n// children per node 4, min children 2 (the threshold\n// at which members are redistributed)\nRTree\u003cString, Geometry\u003e tree = RTree.create();\n```\nYou can specify a few parameters to the builder, including *minChildren*, *maxChildren*, *splitter*, *selector*:\n\n```java\nRTree\u003cString, Geometry\u003e tree = RTree.minChildren(3).maxChildren(6).create();\n```\n### Geometries\nThe following geometries are supported for insertion in an RTree:\n\n* `Rectangle`\n* `Point`\n* `Circle`\n* `Line`\n\n### Generic typing\nIf for instance you know that the entry geometry is always ```Point``` then create an ```RTree``` specifying that generic type to gain more type safety:\n\n```java\nRTree\u003cString, Point\u003e tree = RTree.create();\n```\n\n### R*-tree\nIf you'd like an R*-tree (which uses a topological splitter on minimal margin, overlap area and area and a selector combination of minimal area increase, minimal overlap, and area):\n\n```\nRTree\u003cString, Geometry\u003e tree = RTree.star().maxChildren(6).create();\n```\n\nSee benchmarks below for some of the performance differences.\n\n### Add items to the R-tree\nWhen you add an item to the R-tree you need to provide a geometry that represents the 2D physical location or \nextension of the item. The ``Geometries`` builder provides these factory methods:\n\n* ```Geometries.rectangle```\n* ```Geometries.circle```\n* ```Geometries.point```\n* ```Geometries.line``` (requires *jts-core* dependency)\n\nTo add an item to an R-tree:\n\n```java\nRTree\u003cT,Geometry\u003e tree = RTree.create();\ntree = tree.add(item, Geometries.point(10,20));\n```\nor \n```java\ntree = tree.add(Entries.entry(item, Geometries.point(10,20));\n```\n\n*Important note:* being an immutable data structure, calling ```tree.add(item, geometry)``` does nothing to ```tree```, \nit returns a new ```RTree``` containing the addition. Make sure you use the result of the ```add```!\n\n### Remove an item in the R-tree\nTo remove an item from an R-tree, you need to match the item and its geometry:\n\n```java\ntree = tree.delete(item, Geometries.point(10,20));\n```\nor \n```java\ntree = tree.delete(entry);\n```\n\n*Important note:* being an immutable data structure, calling ```tree.delete(item, geometry)``` does nothing to ```tree```, \nit returns a new ```RTree``` without the deleted item. Make sure you use the result of the ```delete```!\n\n### Geospatial geometries (lats and longs)\nTo handle wraparounds of longitude values on the earth (180/-180 boundary trickiness) there are special factory methods in the `Geometries` class. If you want to do geospatial searches then you should use these methods to build `Point`s and `Rectangle`s:\n\n```java\nPoint point = Geometries.pointGeographic(lon, lat);\nRectangle rectangle = Geometries.rectangleGeographic(lon1, lat1, lon2, lat2);\n```\n\nUnder the covers these methods normalize the longitude value to be in the interval [-180, 180) and for rectangles the rightmost longitude has 360 added to it if it is less than the leftmost longitude.\n\n### Custom geometries\nYou can also write your own implementation of [```Geometry```](src/main/java/com/github/davidmoten/rtree/geometry/Geometry.java). An implementation of ```Geometry``` needs to specify methods to:\n\n* check intersection with a rectangle (you can reuse the distance method here if you want but it might affect performance)\n* provide a minimum bounding rectangle\n* implement ```equals``` and ```hashCode``` for consistent equality checking\n* measure distance to a rectangle (0 means they intersect). Note that this method is only used for search within a distance so implementing this method is *optional*. If you don't want to implement this method just throw a ```RuntimeException```.\n\nFor the R-tree to be well-behaved, the distance function if implemented needs to satisfy these properties:\n\n* ```distance(r) \u003e= 0 for all rectangles r```\n* ```if rectangle r1 contains r2 then distance(r1)\u003c=distance(r2)```\n* ```distance(r) = 0 if and only if the geometry intersects the rectangle r``` \n\n### Searching\nThe advantage of an R-tree is the ability to search for items in a region reasonably quickly. \nOn average search is ```O(log(n))``` but worst case is ```O(n)```.\n\nSearch methods return ```Observable``` sequences:\n```java\nObservable\u003cEntry\u003cT, Geometry\u003e\u003e results =\n    tree.search(Geometries.rectangle(0,0,2,2));\n```\nor search for items within a distance from the given geometry:\n```java\nObservable\u003cEntry\u003cT, Geometry\u003e\u003e results =\n    tree.search(Geometries.rectangle(0,0,2,2),5.0);\n```\nTo return all entries from an R-tree:\n```java\nObservable\u003cEntry\u003cT, Geometry\u003e\u003e results = tree.entries();\n```\n\nSearch with a custom geometry\n-----------------------------------\nSuppose you make a custom geometry like ```Polygon``` and you want to search an ```RTree\u003cString,Point\u003e``` for points inside the polygon. This is how you do it:\n\n```java\nRTree\u003cString, Point\u003e tree = RTree.create();\nFunc2\u003cPoint, Polygon, Boolean\u003e pointInPolygon = ...\nPolygon polygon = ...\n...\nentries = tree.search(polygon, pointInPolygon);\n```\nThe key is that you need to supply the ```intersects``` function (```pointInPolygon```) to the search. It is on you to implement that for all types of geometry present in the ```RTree```. This is one reason that the generic ```Geometry``` type was added in *rtree* 0.5 (so the type system could tell you what geometry types you needed to calculate intersection for) .\n\nSearch with a custom geometry and maxDistance\n--------------------------------------------------\nAs per the example above to do a proximity search you need to specify how to calculate distance between the geometry you are searching and the entry geometries:\n\n```java\nRTree\u003cString, Point\u003e tree = RTree.create();\nFunc2\u003cPoint, Polygon, Boolean\u003e distancePointToPolygon = ...\nPolygon polygon = ...\n...\nentries = tree.search(polygon, 10, distancePointToPolygon);\n```\nExample\n--------------\n```java\nimport com.github.davidmoten.rtree.RTree;\nimport static com.github.davidmoten.rtree.geometry.Geometries.*;\n\nRTree\u003cString, Point\u003e tree = RTree.maxChildren(5).create();\ntree = tree.add(\"DAVE\", point(10, 20))\n           .add(\"FRED\", point(12, 25))\n           .add(\"MARY\", point(97, 125));\n \nObservable\u003cEntry\u003cString, Point\u003e\u003e entries =\n    tree.search(Geometries.rectangle(8, 15, 30, 35));\n```\n\nSearching by distance on lat longs\n------------------------------------\nSee [LatLongExampleTest.java](src/test/java/com/github/davidmoten/rtree/LatLongExampleTest.java) for an example. The example depends on [*grumpy-core*](https://github.com/davidmoten/grumpy) artifact which is also on Maven Central.\n\nAnother lat long example searching geo circles \n------------------------------------------------\nSee [LatLongExampleTest.testSearchLatLongCircles()](src/test/java/com/github/davidmoten/rtree/LatLongExampleTest.java) for an example of searching circles around geographic points (using great circle distance).\n\n\nWhat do I do with the Observable thing?\n-------------------------------------------\nVery useful, see [RxJava](http://github.com/ReactiveX/RxJava).\n\nAs an example, suppose you want to filter the search results then apply a function on each and reduce to some best answer:\n\n```java\nimport rx.Observable;\nimport rx.functions.*;\nimport rx.schedulers.Schedulers;\n\nCharacter result = \n    tree.search(Geometries.rectangle(8, 15, 30, 35))\n        // filter for names alphabetically less than M\n        .filter(entry -\u003e entry.value() \u003c \"M\")\n        // get the first character of the name\n        .map(entry -\u003e entry.value().charAt(0))\n        // reduce to the first character alphabetically \n        .reduce((x,y) -\u003e x \u003c= y ? x : y)\n        // subscribe to the stream and block for the result\n        .toBlocking().single();\nSystem.out.println(list);\n```\noutput:\n```\nD\n```\n\nHow to configure the R-tree for best performance\n--------------------------------------------------\nCheck out the benchmarks below and refer to [another benchmark results](https://github.com/ambling/rtree-benchmark#results), but I recommend you do your own benchmarks because every data set will behave differently. If you don't want to benchmark then use the defaults. General rules based on the benchmarks:\n\n* for data sets of \u003c10,000 entries use the default R-tree (quadratic splitter with maxChildren=4)\n* for data sets of \u003e=10,000 entries use the star R-tree (R*-tree heuristics with maxChildren=4 by default)\n* use STR bulk loaded R-tree (quadratic splitter or R*-tree heuristics) for large (where index creation time is important) or static (where insertion and deletion are not frequent) data sets\n\nWatch out though, the benchmark data sets had quite specific characteristics. The 1000 entry dataset was randomly generated (so is more or less uniformly distributed) and the *Greek* dataset was earthquake data with its own clustering characteristics. \n\nWhat about memory use?\n------------------------\nTo minimize memory use you can use geometries that store single precision decimal values (`float`) instead of double precision (`double`). Here are examples:\n\n```java\n// create geometry using double precision \nRectangle r = Geometries.rectangle(1.0, 2.0, 3.0, 4.0);\n\n// create geometry using single precision\nRectangle r = Geometries.rectangle(1.0f, 2.0f, 3.0f, 4.0f);\n```\n\nThe same creation methods exist for `Circle` and `Line`.\n\nHow do I just get an Iterable back from a search?\n---------------------------------------------------------\nIf you are not familiar with the Observable API and want to skip the reactive stuff then here's how to get an ```Iterable``` from a search:\n\n```java\nIterable\u003cT\u003e it = tree.search(Geometries.point(4,5))\n                     .toBlocking().toIterable();\n```\n\nBackpressure\n-----------------\nThe backpressure slow path may be enabled by some RxJava operators. This may slow search performance by a factor of 3 but avoids possible out of memory errors and thread starvation due to asynchronous buffering. Backpressure is benchmarked below.\n\nVisualizer\n--------------\nTo visualize the R-tree in a PNG file of size 600 by 600 pixels just call:\n```java\ntree.visualize(600,600)\n    .save(\"target/mytree.png\");\n```\nThe result is like the images in the Features section above.\n\nVisualize as text\n--------------------\nThe ```RTree.asString()``` method returns output like this:\n\n```\nmbr=Rectangle [x1=10.0, y1=4.0, x2=62.0, y2=85.0]\n  mbr=Rectangle [x1=28.0, y1=4.0, x2=34.0, y2=85.0]\n    entry=Entry [value=2, geometry=Point [x=29.0, y=4.0]]\n    entry=Entry [value=1, geometry=Point [x=28.0, y=19.0]]\n    entry=Entry [value=4, geometry=Point [x=34.0, y=85.0]]\n  mbr=Rectangle [x1=10.0, y1=45.0, x2=62.0, y2=63.0]\n    entry=Entry [value=5, geometry=Point [x=62.0, y=45.0]]\n    entry=Entry [value=3, geometry=Point [x=10.0, y=63.0]]\n```\n\nSerialization\n------------------\nRelease 0.8 includes [flatbuffers](https://github.com/google/flatbuffers) support as a serialization format and as a lower performance but lower memory consumption (approximately one third) option for an RTree. \n\nThe greek earthquake data (38,377 entries) when placed in a default RTree with `maxChildren=10` takes up 4,548,133 bytes in memory. If that data is serialized then reloaded into memory using the `InternalStructure.FLATBUFFERS_SINGLE_ARRAY` option then the RTree takes up 1,431,772 bytes in memory (approximately one third the memory usage). Bear in mind though that searches are much more expensive (at the moment) with this data structure because of object creation and gc pressures (see benchmarks). Further work would be to enable direct searching of the underlying array without object creation expenses required to match the current search routines. \n\nAs of 5 March 2016, indicative RTree metrics using flatbuffers data structure are:\n\n* one third the memory use with log(N) object creations per search\n* one third the speed with backpressure (e.g. if `flatMap` or `observeOn` is downstream)\n* one tenth the speed without backpressure \n\nNote that serialization uses an optional dependency on `flatbuffers`. Add the following to your pom dependencies:\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.google.flatbuffers\u003c/groupId\u003e\n    \u003cartifactId\u003eflatbuffers-java\u003c/artifactId\u003e\n    \u003cversion\u003e2.0.3\u003c/version\u003e\n    \u003coptional\u003etrue\u003c/optional\u003e\n\u003c/dependency\u003e\n```\n\n## Serialization example\n\nWrite an `RTree` to an `OutputStream`:\n```java\nRTree\u003cString, Point\u003e tree = ...;\nOutputStream os = ...;\nSerializer\u003cString, Point\u003e serializer = \n  Serializers.flatBuffers().utf8();\nserializer.write(tree, os); \n```\n\nRead an `RTree` from an `InputStream` into a low-memory flatbuffers based structure:\n```java\nRTree\u003cString, Point\u003e tree = \n  serializer.read(is, lengthBytes, InternalStructure.SINGLE_ARRAY);\n```\n\nRead an `RTree` from an `InputStream` into a default structure:\n```java\nRTree\u003cString, Point\u003e tree = \n  serializer.read(is, lengthBytes, InternalStructure.DEFAULT);\n```\n\nDependencies\n---------------------\nAs of 0.7.5 this library does not depend on *guava* (\u003e2M) but rather depends on *guava-mini* (11K). The `nearest` search used to depend on `MinMaxPriorityQueue` from guava but now uses a backport of Java 8 `PriorityQueue` inside a custom `BoundedPriorityQueue` class that gives about 1.7x the throughput as the guava class.\n\nHow to build\n----------------\n```\ngit clone https://github.com/davidmoten/rtree.git\ncd rtree\nmvn clean install\n```\n\nHow to run benchmarks\n--------------------------\nBenchmarks are provided by \n```\nmvn clean install -Pbenchmark\n```\nCoverity scan\n----------------\nThis codebase is scanned by Coverity scan whenever the branch `coverity_scan` is updated. \n\nFor the project committers if a coverity scan is desired just do this:\n\n```bash\ngit checkout coverity_scan\ngit pull origin master\ngit push origin coverity_scan\n```\n\n### Notes\nThe *Greek* data referred to in the benchmarks is a collection of some 38,377 entries corresponding to the epicentres of earthquakes in Greece between 1964 and 2000. This data set is used by multiple studies on R-trees as a test case.\n\n### Results\n\nThese were run on i7-920 @2.67GHz with *rtree* version 0.8-RC7:\n\n```\nBenchmark                                                               Mode  Cnt        Score       Error  Units\n\ndefaultRTreeInsertOneEntryInto1000EntriesMaxChildren004                thrpt   10   262260.993 ±  2767.035  ops/s\ndefaultRTreeInsertOneEntryInto1000EntriesMaxChildren010                thrpt   10   296264.913 ±  2836.358  ops/s\ndefaultRTreeInsertOneEntryInto1000EntriesMaxChildren032                thrpt   10   135118.271 ±  1722.039  ops/s\ndefaultRTreeInsertOneEntryInto1000EntriesMaxChildren128                thrpt   10   315851.452 ±  3097.496  ops/s\ndefaultRTreeInsertOneEntryIntoGreekDataEntriesMaxChildren004           thrpt   10   278761.674 ±  4182.761  ops/s\ndefaultRTreeInsertOneEntryIntoGreekDataEntriesMaxChildren010           thrpt   10   315254.478 ±  4104.206  ops/s\ndefaultRTreeInsertOneEntryIntoGreekDataEntriesMaxChildren032           thrpt   10   214509.476 ±  1555.816  ops/s\ndefaultRTreeInsertOneEntryIntoGreekDataEntriesMaxChildren128           thrpt   10   118094.486 ±  1118.983  ops/s\ndefaultRTreeSearchOf1000PointsMaxChildren004                           thrpt   10  1122140.598 ±  8509.106  ops/s\ndefaultRTreeSearchOf1000PointsMaxChildren010                           thrpt   10   569779.807 ±  4206.544  ops/s\ndefaultRTreeSearchOf1000PointsMaxChildren032                           thrpt   10   238251.898 ±  3916.281  ops/s\ndefaultRTreeSearchOf1000PointsMaxChildren128                           thrpt   10   702437.901 ±  5108.786  ops/s\ndefaultRTreeSearchOfGreekDataPointsMaxChildren004                      thrpt   10   462243.509 ±  7076.045  ops/s\ndefaultRTreeSearchOfGreekDataPointsMaxChildren010                      thrpt   10   326395.724 ±  1699.043  ops/s\ndefaultRTreeSearchOfGreekDataPointsMaxChildren032                      thrpt   10   156978.822 ±  1993.372  ops/s\ndefaultRTreeSearchOfGreekDataPointsMaxChildren128                      thrpt   10    68267.160 ±   929.236  ops/s\nrStarTreeDeleteOneEveryOccurrenceFromGreekDataChildren010              thrpt   10   211881.061 ±  3246.693  ops/s\nrStarTreeInsertOneEntryInto1000EntriesMaxChildren004                   thrpt   10   187062.089 ±  3005.413  ops/s\nrStarTreeInsertOneEntryInto1000EntriesMaxChildren010                   thrpt   10   186767.045 ±  2291.196  ops/s\nrStarTreeInsertOneEntryInto1000EntriesMaxChildren032                   thrpt   10    37940.625 ±   743.789  ops/s\nrStarTreeInsertOneEntryInto1000EntriesMaxChildren128                   thrpt   10   151897.089 ±   674.941  ops/s\nrStarTreeInsertOneEntryIntoGreekDataEntriesMaxChildren004              thrpt   10   237708.825 ±  1644.611  ops/s\nrStarTreeInsertOneEntryIntoGreekDataEntriesMaxChildren010              thrpt   10   229577.905 ±  4234.760  ops/s\nrStarTreeInsertOneEntryIntoGreekDataEntriesMaxChildren032              thrpt   10    78290.971 ±   393.030  ops/s\nrStarTreeInsertOneEntryIntoGreekDataEntriesMaxChildren128              thrpt   10     6521.010 ±    50.798  ops/s\nrStarTreeSearchOf1000PointsMaxChildren004                              thrpt   10  1330510.951 ± 18289.410  ops/s\nrStarTreeSearchOf1000PointsMaxChildren010                              thrpt   10  1204347.202 ± 17403.105  ops/s\nrStarTreeSearchOf1000PointsMaxChildren032                              thrpt   10   576765.468 ±  8909.880  ops/s\nrStarTreeSearchOf1000PointsMaxChildren128                              thrpt   10  1028316.856 ± 13747.282  ops/s\nrStarTreeSearchOfGreekDataPointsMaxChildren004                         thrpt   10   904494.751 ± 15640.005  ops/s\nrStarTreeSearchOfGreekDataPointsMaxChildren010                         thrpt   10   649636.969 ± 16383.786  ops/s\nrStarTreeSearchOfGreekDataPointsMaxChildren010FlatBuffers              thrpt   10    84230.053 ±  1869.345  ops/s\nrStarTreeSearchOfGreekDataPointsMaxChildren010FlatBuffersBackpressure  thrpt   10    36420.500 ±  1572.298  ops/s\nrStarTreeSearchOfGreekDataPointsMaxChildren010WithBackpressure         thrpt   10   116970.445 ±  1955.659  ops/s\nrStarTreeSearchOfGreekDataPointsMaxChildren032                         thrpt   10   224874.016 ± 14462.325  ops/s\nrStarTreeSearchOfGreekDataPointsMaxChildren128                         thrpt   10   358636.637 ±  4886.459  ops/s\nsearchNearestGreek                                                     thrpt   10     3715.020 ±    46.570  ops/s\n\n```\n\nThere is a related project [rtree-benchmark](https://github.com/ambling/rtree-benchmark) that presents a more comprehensive benchmark with results and analysis on this rtree implementation.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdavidmoten%2Frtree","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdavidmoten%2Frtree","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdavidmoten%2Frtree/lists"}