Immutable in-memory R-tree and R*-tree implementations in Java with reactive api

Overview

rtree

Travis CI
Coverity Scan
Maven Central
codecov

In-memory immutable 2D R-tree implementation in java using RxJava Observables for reactive processing of search results.

Status: released to Maven Central

Note that the next version (without a reactive API and without serialization) is at rtree2.

An R-tree is a commonly used spatial index.

This was fun to make, has an elegant concise algorithm, is thread-safe, fast, and reasonably memory efficient (uses structural sharing).

The algorithm to achieve immutability is cute. For insertion/deletion it involves recursion down to the required leaf node then recursion back up to replace the parent nodes up to the root. The guts of it is in Leaf.java and NonLeaf.java.

Backpressure support required some complexity because effectively a bookmark needed to be kept for a position in the tree and returned to later to continue traversal. An immutable stack containing 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!).

Maven site reports are here including javadoc.

Features

  • immutable R-tree suitable for concurrency
  • Guttman's heuristics (Quadratic splitter) (paper)
  • R*-tree heuristics (paper)
  • Customizable splitter and selector
  • 10x faster index creation with STR bulk loading (paper).
  • search returns Observable
  • search is cancelled by unsubscription
  • search is O(log(n)) on average
  • insert, delete are O(n) worst case
  • all search methods return lazy-evaluated streams offering efficiency and flexibility of functional style including functional composition and concurrency
  • balanced delete
  • uses structural sharing
  • supports backpressure
  • JMH benchmarks
  • visualizer included
  • serialization using FlatBuffers
  • high unit test code coverage
  • R*-tree performs 900,000 searches/second returning 22 entries from a tree of 38,377 Greek earthquake locations on [email protected] (maxChildren=4, minChildren=1). Insert at 240,000 entries per second.
  • requires java 1.6 or later

Number of points = 1000, max children per node 8:

Quadratic split R*-tree split STR bulk loaded

Notice that there is little overlap in the R*-tree split compared to the Quadratic split. This should provide better search performance (and in general benchmarks show this).

STR bulk loaded R-tree has a bit more overlap than R*-tree, which affects the search performance at some extent.

Getting started

Add this maven dependency to your pom.xml:

<dependency>
  <groupId>com.github.davidmoten</groupId>
  <artifactId>rtree</artifactId>
  <version>VERSION_HERE</version>
</dependency>

Instantiate an R-Tree

Use the static builder methods on the RTree class:

// create an R-tree using Quadratic split with max
// children per node 4, min children 2 (the threshold
// at which members are redistributed)
RTree<String, Geometry> tree = RTree.create();

You can specify a few parameters to the builder, including minChildren, maxChildren, splitter, selector:

RTree<String, Geometry> tree = RTree.minChildren(3).maxChildren(6).create();

Geometries

The following geometries are supported for insertion in an RTree:

  • Rectangle
  • Point
  • Circle
  • Line

Generic typing

If for instance you know that the entry geometry is always Point then create an RTree specifying that generic type to gain more type safety:

RTree<String, Point> tree = RTree.create();

R*-tree

If 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):

RTree<String, Geometry> tree = RTree.star().maxChildren(6).create();

See benchmarks below for some of the performance differences.

Add items to the R-tree

When you add an item to the R-tree you need to provide a geometry that represents the 2D physical location or extension of the item. The Geometries builder provides these factory methods:

  • Geometries.rectangle
  • Geometries.circle
  • Geometries.point
  • Geometries.line (requires jts-core dependency)

To add an item to an R-tree:

RTree<T,Geometry> tree = RTree.create();
tree = tree.add(item, Geometries.point(10,20));

or

tree = tree.add(Entries.entry(item, Geometries.point(10,20));

Important note: being an immutable data structure, calling tree.add(item, geometry) does nothing to tree, it returns a new RTree containing the addition. Make sure you use the result of the add!

Remove an item in the R-tree

To remove an item from an R-tree, you need to match the item and its geometry:

tree = tree.delete(item, Geometries.point(10,20));

or

tree = tree.delete(entry);

Important note: being an immutable data structure, calling tree.delete(item, geometry) does nothing to tree, it returns a new RTree without the deleted item. Make sure you use the result of the delete!

Geospatial geometries (lats and longs)

To 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 Points and Rectangles:

Point point = Geometries.pointGeographic(lon, lat);
Rectangle rectangle = Geometries.rectangleGeographic(lon1, lat1, lon2, lat2);

Under 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.

Custom geometries

You can also write your own implementation of Geometry. An implementation of Geometry needs to specify methods to:

  • check intersection with a rectangle (you can reuse the distance method here if you want but it might affect performance)
  • provide a minimum bounding rectangle
  • implement equals and hashCode for consistent equality checking
  • 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.

For the R-tree to be well-behaved, the distance function if implemented needs to satisfy these properties:

  • distance(r) >= 0 for all rectangles r
  • if rectangle r1 contains r2 then distance(r1)<=distance(r2)
  • distance(r) = 0 if and only if the geometry intersects the rectangle r

Searching

The advantage of an R-tree is the ability to search for items in a region reasonably quickly. On average search is O(log(n)) but worst case is O(n).

Search methods return Observable sequences:

Observable<Entry<T, Geometry>> results =
    tree.search(Geometries.rectangle(0,0,2,2));

or search for items within a distance from the given geometry:

Observable<Entry<T, Geometry>> results =
    tree.search(Geometries.rectangle(0,0,2,2),5.0);

To return all entries from an R-tree:

Observable<Entry<T, Geometry>> results = tree.entries();

Search with a custom geometry

Suppose you make a custom geometry like Polygon and you want to search an RTree<String,Point> for points inside the polygon. This is how you do it:

RTree<String, Point> tree = RTree.create();
Func2<Point, Polygon, Boolean> pointInPolygon = ...
Polygon polygon = ...
...
entries = tree.search(polygon, pointInPolygon);

The 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) .

Search with a custom geometry and maxDistance

As 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:

RTree<String, Point> tree = RTree.create();
Func2<Point, Polygon, Boolean> distancePointToPolygon = ...
Polygon polygon = ...
...
entries = tree.search(polygon, 10, distancePointToPolygon);

Example

import com.github.davidmoten.rtree.RTree;
import static com.github.davidmoten.rtree.geometry.Geometries.*;

RTree<String, Point> tree = RTree.maxChildren(5).create();
tree = tree.add("DAVE", point(10, 20))
           .add("FRED", point(12, 25))
           .add("MARY", point(97, 125));
 
Observable<Entry<String, Point>> entries =
    tree.search(Geometries.rectangle(8, 15, 30, 35));

Searching by distance on lat longs

See LatLongExampleTest.java for an example. The example depends on grumpy-core artifact which is also on Maven Central.

Another lat long example searching geo circles

See LatLongExampleTest.testSearchLatLongCircles() for an example of searching circles around geographic points (using great circle distance).

What do I do with the Observable thing?

Very useful, see RxJava.

As an example, suppose you want to filter the search results then apply a function on each and reduce to some best answer:

import rx.Observable;
import rx.functions.*;
import rx.schedulers.Schedulers;

Character result = 
    tree.search(Geometries.rectangle(8, 15, 30, 35))
        // filter for names alphabetically less than M
        .filter(entry -> entry.value() < "M")
        // get the first character of the name
        .map(entry -> entry.value().charAt(0))
        // reduce to the first character alphabetically 
        .reduce((x,y) -> x <= y ? x : y)
        // subscribe to the stream and block for the result
        .toBlocking().single();
System.out.println(list);

output:

D

How to configure the R-tree for best performance

Check out the benchmarks below and refer to another 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:

  • for data sets of <10,000 entries use the default R-tree (quadratic splitter with maxChildren=4)
  • for data sets of >=10,000 entries use the star R-tree (R*-tree heuristics with maxChildren=4 by default)
  • 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

Watch 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.

What about memory use?

To minimize memory use you can use geometries that store single precision decimal values (float) instead of double precision (double). Here are examples:

// create geometry using double precision 
Rectangle r = Geometries.rectangle(1.0, 2.0, 3.0, 4.0);

// create geometry using single precision
Rectangle r = Geometries.rectangle(1.0f, 2.0f, 3.0f, 4.0f);

The same creation methods exist for Circle and Line.

How do I just get an Iterable back from a search?

If 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:

Iterable<T> it = tree.search(Geometries.point(4,5))
                     .toBlocking().toIterable();

Backpressure

The 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.

Visualizer

To visualize the R-tree in a PNG file of size 600 by 600 pixels just call:

tree.visualize(600,600)
    .save("target/mytree.png");

The result is like the images in the Features section above.

Visualize as text

The RTree.asString() method returns output like this:

mbr=Rectangle [x1=10.0, y1=4.0, x2=62.0, y2=85.0]
  mbr=Rectangle [x1=28.0, y1=4.0, x2=34.0, y2=85.0]
    entry=Entry [value=2, geometry=Point [x=29.0, y=4.0]]
    entry=Entry [value=1, geometry=Point [x=28.0, y=19.0]]
    entry=Entry [value=4, geometry=Point [x=34.0, y=85.0]]
  mbr=Rectangle [x1=10.0, y1=45.0, x2=62.0, y2=63.0]
    entry=Entry [value=5, geometry=Point [x=62.0, y=45.0]]
    entry=Entry [value=3, geometry=Point [x=10.0, y=63.0]]

Serialization

Release 0.8 includes flatbuffers support as a serialization format and as a lower performance but lower memory consumption (approximately one third) option for an RTree.

The 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.

As of 5 March 2016, indicative RTree metrics using flatbuffers data structure are:

  • one third the memory use with log(N) object creations per search
  • one third the speed with backpressure (e.g. if flatMap or observeOn is downstream)
  • one tenth the speed without backpressure

Note that serialization uses an optional dependency on flatbuffers. Add the following to your pom dependencies:

<dependency>
    <groupId>com.github.davidmoten</groupId>
    <artifactId>flatbuffers-java</artifactId>
    <version>1.3.0.1</version>
    <optional>true</optional>
</dependency>

Serialization example

Write an RTree to an OutputStream:

RTree<String, Point> tree = ...;
OutputStream os = ...;
Serializer<String, Point> serializer = 
  Serializers.flatBuffers().utf8();
serializer.write(tree, os); 

Read an RTree from an InputStream into a low-memory flatbuffers based structure:

RTree<String, Point> tree = 
  serializer.read(is, lengthBytes, InternalStructure.SINGLE_ARRAY);

Read an RTree from an InputStream into a default structure:

RTree<String, Point> tree = 
  serializer.read(is, lengthBytes, InternalStructure.DEFAULT);

Dependencies

As of 0.7.5 this library does not depend on guava (>2M) 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.

How to build

git clone https://github.com/davidmoten/rtree.git
cd rtree
mvn clean install

How to run benchmarks

Benchmarks are provided by

mvn clean install -Pbenchmark

Coverity scan

This codebase is scanned by Coverity scan whenever the branch coverity_scan is updated.

For the project committers if a coverity scan is desired just do this:

git checkout coverity_scan
git pull origin master
git push origin coverity_scan

Notes

The 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.

Results

These were run on i7-920 @2.67GHz with rtree version 0.8-RC7:

Benchmark                                                               Mode  Cnt        Score       Error  Units

defaultRTreeInsertOneEntryInto1000EntriesMaxChildren004                thrpt   10   262260.993 ±  2767.035  ops/s
defaultRTreeInsertOneEntryInto1000EntriesMaxChildren010                thrpt   10   296264.913 ±  2836.358  ops/s
defaultRTreeInsertOneEntryInto1000EntriesMaxChildren032                thrpt   10   135118.271 ±  1722.039  ops/s
defaultRTreeInsertOneEntryInto1000EntriesMaxChildren128                thrpt   10   315851.452 ±  3097.496  ops/s
defaultRTreeInsertOneEntryIntoGreekDataEntriesMaxChildren004           thrpt   10   278761.674 ±  4182.761  ops/s
defaultRTreeInsertOneEntryIntoGreekDataEntriesMaxChildren010           thrpt   10   315254.478 ±  4104.206  ops/s
defaultRTreeInsertOneEntryIntoGreekDataEntriesMaxChildren032           thrpt   10   214509.476 ±  1555.816  ops/s
defaultRTreeInsertOneEntryIntoGreekDataEntriesMaxChildren128           thrpt   10   118094.486 ±  1118.983  ops/s
defaultRTreeSearchOf1000PointsMaxChildren004                           thrpt   10  1122140.598 ±  8509.106  ops/s
defaultRTreeSearchOf1000PointsMaxChildren010                           thrpt   10   569779.807 ±  4206.544  ops/s
defaultRTreeSearchOf1000PointsMaxChildren032                           thrpt   10   238251.898 ±  3916.281  ops/s
defaultRTreeSearchOf1000PointsMaxChildren128                           thrpt   10   702437.901 ±  5108.786  ops/s
defaultRTreeSearchOfGreekDataPointsMaxChildren004                      thrpt   10   462243.509 ±  7076.045  ops/s
defaultRTreeSearchOfGreekDataPointsMaxChildren010                      thrpt   10   326395.724 ±  1699.043  ops/s
defaultRTreeSearchOfGreekDataPointsMaxChildren032                      thrpt   10   156978.822 ±  1993.372  ops/s
defaultRTreeSearchOfGreekDataPointsMaxChildren128                      thrpt   10    68267.160 ±   929.236  ops/s
rStarTreeDeleteOneEveryOccurrenceFromGreekDataChildren010              thrpt   10   211881.061 ±  3246.693  ops/s
rStarTreeInsertOneEntryInto1000EntriesMaxChildren004                   thrpt   10   187062.089 ±  3005.413  ops/s
rStarTreeInsertOneEntryInto1000EntriesMaxChildren010                   thrpt   10   186767.045 ±  2291.196  ops/s
rStarTreeInsertOneEntryInto1000EntriesMaxChildren032                   thrpt   10    37940.625 ±   743.789  ops/s
rStarTreeInsertOneEntryInto1000EntriesMaxChildren128                   thrpt   10   151897.089 ±   674.941  ops/s
rStarTreeInsertOneEntryIntoGreekDataEntriesMaxChildren004              thrpt   10   237708.825 ±  1644.611  ops/s
rStarTreeInsertOneEntryIntoGreekDataEntriesMaxChildren010              thrpt   10   229577.905 ±  4234.760  ops/s
rStarTreeInsertOneEntryIntoGreekDataEntriesMaxChildren032              thrpt   10    78290.971 ±   393.030  ops/s
rStarTreeInsertOneEntryIntoGreekDataEntriesMaxChildren128              thrpt   10     6521.010 ±    50.798  ops/s
rStarTreeSearchOf1000PointsMaxChildren004                              thrpt   10  1330510.951 ± 18289.410  ops/s
rStarTreeSearchOf1000PointsMaxChildren010                              thrpt   10  1204347.202 ± 17403.105  ops/s
rStarTreeSearchOf1000PointsMaxChildren032                              thrpt   10   576765.468 ±  8909.880  ops/s
rStarTreeSearchOf1000PointsMaxChildren128                              thrpt   10  1028316.856 ± 13747.282  ops/s
rStarTreeSearchOfGreekDataPointsMaxChildren004                         thrpt   10   904494.751 ± 15640.005  ops/s
rStarTreeSearchOfGreekDataPointsMaxChildren010                         thrpt   10   649636.969 ± 16383.786  ops/s
rStarTreeSearchOfGreekDataPointsMaxChildren010FlatBuffers              thrpt   10    84230.053 ±  1869.345  ops/s
rStarTreeSearchOfGreekDataPointsMaxChildren010FlatBuffersBackpressure  thrpt   10    36420.500 ±  1572.298  ops/s
rStarTreeSearchOfGreekDataPointsMaxChildren010WithBackpressure         thrpt   10   116970.445 ±  1955.659  ops/s
rStarTreeSearchOfGreekDataPointsMaxChildren032                         thrpt   10   224874.016 ± 14462.325  ops/s
rStarTreeSearchOfGreekDataPointsMaxChildren128                         thrpt   10   358636.637 ±  4886.459  ops/s
searchNearestGreek                                                     thrpt   10     3715.020 ±    46.570  ops/s

There is a related project rtree-benchmark that presents a more comprehensive benchmark with results and analysis on this rtree implementation.

Comments
  • Provide RTree.search(Geometry) method

    Provide RTree.search(Geometry) method

    A feature request: it seems that search queries must only use rectangle geometries. Most often I would want to be searching by point and it feels wrong to create degenerate rectangles every time.

    RTree<String> rtree = RTree.create();
    rtree.add("foo", Geometries.rectangle(24.0d, 0.0d, 42.0, 1.0));
    ...
    
    rtree.search(Geometries.point(36.0d, 0.5d));  // compile error
    

    Thanks for your consideration!

    opened by heuermh 14
  • Joining the rtree project

    Joining the rtree project

    Hi David, My name is Max. I found your project a few days ago and it sounds very interesting. I was wondering if you're still working on it, and need some help developing, fixing bugs or anything else. I would love to contribute somehow, even if it's with little things. Let me know if you're interested.

    Best Regards, Max.

    P.S. I already cloned the project, imported to eclipse and got it working. I have two tests that are failing for some reason (testBaskpressureIterationForUpTo1000Entries , testVisualizerWithGreekData).

    opened by maxamel 12
  • Does this code support k-nn query?

    Does this code support k-nn query?

    Thanks for your sharing. I have many points which records latitude and longitude. I want to know whether this code support K-nn query for each point? I don't read relevant message except

    As of 0.7.5 this library does not depend on guava (>2M) 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.

    But there is no specific example for k-nn query. Thanks so much.

    question 
    opened by wweichn 11
  • add support for STR bulk packing

    add support for STR bulk packing

    For Issue #45

    add support of Rtree creation through STR packing, according to the paper: STR: a simple and efficient algorithm for R-tree packing

    add a recursive function in RTree.Builder and set the default filling factor as 0.7 (1.0 is better for readonly RTree while 0.7 reserves space for insertion).

    note that this implementation is only for 2D RTree.

    enhancement 
    opened by ambling 10
  • Visualizer does not render points

    Visualizer does not render points

    I am trying to write a program to visualize the data points read from a file. However, rtree.visualize().save() does not render the data points as shown in the README example.

    bug 
    opened by wangchj 10
  • RTree search function not invoking callback function number of expected times

    RTree search function not invoking callback function number of expected times

    I have raised this issue on SO too. https://stackoverflow.com/questions/64258345/rtree-search-function-not-invoking-callback-function-number-of-expected-times

    I observe that callback function I pass to search method is not invoked expected number of times. I observe it when rectangles are not overlapping.

    question 
    opened by mghildiy 9
  • `rtree.nearest` documentation wrong?

    `rtree.nearest` documentation wrong?

    Looking at the implementation of rtree.nearest, it states that it returns objects in no particular order. However, it looks like the comparator that it uses is called ascendingDistance... I haven't actually tested this of course, but was wondering.

    opened by virtuald 9
  • groupBy hangs (0.7.5)

    groupBy hangs (0.7.5)

    Hello, after last update groupBy is not working anymore, here is the test for it

        @Test(timeout = 1000)
        public void testGroupBy() {
            RTree<Integer, Geometry> tree = RTree.star().create();
    
            tree = tree.add(1, Geometries.point(13.0, 52.0));
            tree = tree.add(2, Geometries.point(13.0, 52.0));
            tree = tree.add(3, Geometries.point(13.0, 52.0));
            tree = tree.add(4, Geometries.point(13.0, 52.0));
            tree = tree.add(5, Geometries.point(13.0, 52.0));
            tree = tree.add(6, Geometries.point(13.0, 52.0));
    
            Rectangle rectangle = Geometries.rectangle(12.9, 51.9, 13.1, 52.1);
            assertEquals(Integer.valueOf(6), tree.search(rectangle).count().toBlocking().single());
            assertEquals(Integer.valueOf(2), tree.search(rectangle)
                    .groupBy(new Func1<Entry<Integer, Geometry>, Boolean>() {
                        @Override
                        public Boolean call(Entry<Integer, Geometry> entry) {
                            return entry.value() % 2 == 0;
                        }
                    })
                    .flatMap(new Func1<GroupedObservable<Boolean, Entry<Integer, Geometry>>, Observable<Integer>>() {
                        @Override
                        public Observable<Integer> call(GroupedObservable<Boolean, Entry<Integer, Geometry>> group) {
                            return group.count();
                        }
                    })
                    .count()
                    .toBlocking()
                    .single());
        }
    
    opened by wizzardo 7
  • write unit test for Visualizer.save throwing IOException

    write unit test for Visualizer.save throwing IOException

    Would like to get RTreeTest.testSaveFileException working.

    This is the only code left to get to 100% coverage (thanks to @maxamel for all your efforts). Not sure how to make it work at the moment. How can we provoke an IOException on writing the image to a file?

    @maxamel have a go if you like

    enhancement 
    opened by davidmoten 7
  • Possible Issue on delete

    Possible Issue on delete

    Hello, I believe there is a bug on delete. The following code worked up to the 0.8-RC10 version: val newT=tree.delete(obj, Geometries.pointGeographic((long).toDouble, (lat).toDouble)) Updating to 0.8.5 makes this code stop working, with the new tree returning the same size as the former. Trying things out, I found the problem to be related with the generation of points, which somehow don't get recognized now. I tried searching for my point through the search method and testing different combinations and these are my findings (myValue and myGeometry are the ones I create, while value and geometry are the ones returned from the searched object): tree.delete(myValue, geometry) -> Works tree.delete(value, myGeometry) -> Doesn't Work tree.delete(myValue, myGeometry) -> Doesn't Work tree.delete(value, geometry) -> Works

    bug 
    opened by jscaballero 6
  • Bulk loading (with STR)

    Bulk loading (with STR)

    I have a rather large set of entries (>= 300k) and I would like to somewhat improve the performance of the tree. The data is available beforehand so I think that bulk loading might help, in particular the "Sort-Tile-Recursive" strategy. I think this could be implemented fairly easily.

    enhancement 
    opened by x2b 6
  • Bump flatbuffers-java from 2.0.8 to 22.12.06

    Bump flatbuffers-java from 2.0.8 to 22.12.06

    Bumps flatbuffers-java from 2.0.8 to 22.12.06.

    Release notes

    Sourced from flatbuffers-java's releases.

    v22.12.06

    What's Changed

    New Contributors

    Full Changelog: https://github.com/google/flatbuffers/compare/v22.11.23...v22.12.06

    v22.11.23

    We had transitory CI breakage in the v22.11.22 release that was marking that build as broken. This release is the same as that one with a new version.

    What's Changed

    Full Changelog: https://github.com/google/flatbuffers/compare/v22.11.22...v22.11.23

    v22.11.22

    What's Changed

    ... (truncated)

    Changelog

    Sourced from flatbuffers-java's changelog.

    22.12.06 (Dec 06 2022)

    • Bug fixing release, no major changes.

    22.10.25 (Oct 25 2022)

    • Added Nim language support with generator and runtime libraries (#7534).

    22.9.29 (Sept 29 2022)

    • Rust soundness fixes to avoid the crate from bing labelled unsafe (#7518).

    22.9.24 (Sept 24 2022)

    • 20 Major releases in a row? Nope, we switched to a new versioning scheme that is based on date.

    • Python supports fixed size arrays now (#7529).

    • Behavior change in how C++ object API uses UnPackTo. The original intent of this was to reduce allocations by reusing an existing object to pack data into. At some point, this logic started to merge the states of the two objects instead of clearing the state of the packee. This change goes back to the original intention, the packed object is cleared when getting data packed into it (#7527).

    • Fixed a bug in C++ alignment that was using sizeof() instead of the intended AlignOf() for structs (#7520).

    • C# has an official Nuget package now (#7496).

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 0
  • How to do an incremental knn search?

    How to do an incremental knn search?

    Incremental knn search save the priority queue in each round generated by knn search if best-first strategy is adopted, and use priority queue saved in the previous round to search knn in the current round. I want to do an incremental knn search. Does anyone can teach me, thank you very much!

    help wanted question 
    opened by zyz760543032 5
  • Bump jmh.version from 1.35 to 1.36

    Bump jmh.version from 1.35 to 1.36

    Bumps jmh.version from 1.35 to 1.36. Updates jmh-core from 1.35 to 1.36

    Commits
    • f2f11b3 JMH v1.36.
    • 7708484 7903367: JMH: Add JMHSample_39_MemoryAccess
    • e5caeb1 7903351: JMH: Update pre-integration testing workflows
    • 0c68719 7903355: JMH: Drop support for JDK 7
    • 0cffac9 7903369: JMH: GC profiler options
    • e7b1218 7903368: JMH: GC profiler misreports allocation and churn rates
    • 3103153 7903350: JMH: Update README
    • 7631fce 7903322: JMH: Fix typo in JMHSample_11_Loops
    • fbcc4ac 7903328: Introduce a new method 'clear' in interface 'Multiset'
    • c1b3e75 7903327: Refactor class 'GCProfiler.VMSupport'
    • Additional commits viewable in compare view

    Updates jmh-generator-annprocess from 1.35 to 1.36

    Commits
    • f2f11b3 JMH v1.36.
    • 7708484 7903367: JMH: Add JMHSample_39_MemoryAccess
    • e5caeb1 7903351: JMH: Update pre-integration testing workflows
    • 0c68719 7903355: JMH: Drop support for JDK 7
    • 0cffac9 7903369: JMH: GC profiler options
    • e7b1218 7903368: JMH: GC profiler misreports allocation and churn rates
    • 3103153 7903350: JMH: Update README
    • 7631fce 7903322: JMH: Fix typo in JMHSample_11_Loops
    • fbcc4ac 7903328: Introduce a new method 'clear' in interface 'Multiset'
    • c1b3e75 7903327: Refactor class 'GCProfiler.VMSupport'
    • Additional commits viewable in compare view

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 0
  • How to serialize all geometry?

    How to serialize all geometry?

    如何序列化所有几何? 我添加了自定义的几何图形,希望在spark程序中应用。由于目前不支持自定义几何的序列化,或者说我不知道如何使用FlatBuffers支持序列化我添加的class。导致目前每个spark程序的实例都需要重新构建一次rtree,这样效率很低。我尝试设置Property : spark.serializer=org.apache.spark.serializer.KryoSerializer 修改默认的序列化方式,但是没有作用,甚至很久都没有完成rtree的构建。有没有一种序列化方式,可以不受限制,任意添加自定义几何,且能够完成快速重建rtree?或者我应该怎样使FlatBuffers支持序列化我添加的class? hi: I added a custom geometric figure, hoping to apply it in the spark program. Since the serialization of custom geometries is currently not supported, or I don't know how to use FlatBuffers to support serialization of the classes I added. As a result, each instance of the spark program needs to rebuild the rtree, which is very inefficient. I tried to set Property: spark.serializer=org.apache.spark.serializer.KryoSerializer to modify the default serialization method, but it didn't work, and it didn't even complete the construction of rtree for a long time. Is there a serialization method that can add custom geometry without limitation, and can quickly rebuild the rtree?Or how should I make FlatBuffers support serialization of the class I added?

    thank you! image image image image

    question 
    opened by q127981 1
  • Add Hilbert Packing Support

    Add Hilbert Packing Support

    This PR,

    • Brings Hilbert Packing support on top Bulk Load.
    • Allows user choice between STR and Hilbert packing techniques.

    Ref: http://www.cs.cmu.edu/~christos/PUBLICATIONS.OLDER/cikm93.pdf

    This was done back in 2017, but never got chance to propose here. Addresses #74. Hope this fits the vision, let me know. Thanks.

    opened by panchal 3
  • Propose to store the geographic rectangles in Integer rather than in Float

    Propose to store the geographic rectangles in Integer rather than in Float

    As we know a single precision float (Float type in Java) has only 7 decimal digits precision (include the integral part), so for longitude the absolution value of which is greater than 100, it has only 4 decimal digits for fractional part. I've calculated and analyzed the possible distance deviation caused by different precision, and 0.0001 longitude difference will lead to about 11m deviation on the equator.

    To improve the accuracy meanwhile save the memory/storage usage, a widely applied measure in geospatial industry is to multiply longitude/latitude with a certain multiplier from 1e5 up to 1e7 (1e8 will cause an overflow) and round it to a 32 bit integer (Integer in Java), and the corresponding derivation will be 1.1m to 1.1cm, more accurate than Float.

    Besides, under nowadays computer architecture, an int calculation will be faster than a fp, so this change might lead to a slight performance improvement as well.

    Any suggestions?

    opened by tibetty 0
Releases(0.10)
  • 0.10(May 16, 2022)

    Bug fix

    • use double arithmetic in SplitterRStar lowestMarginSum, initialize with Double.POSITIVE_INFINITY, ensures pairs is non-null at exit of SplitterRStar.split

    Enhancements

    • Bump maven-bundle-plugin from 5.1.4 to 5.1.5
    • Bump mockito-core from 4.5.0 to 4.5.1
    • Bump maven-antrun-plugin from 3.0.0 to 3.1.0
    • Bump maven-site-plugin from 3.11.0 to 3.12.0
    • Bump maven-javadoc-plugin from 3.3.2 to 3.4.0
    • Bump mockito-core from 4.4.0 to 4.5.0
    • automerge passing dependabot PRs (ci.yml)
    • Update flatbuffers-java instructions in README
    • Bump jacoco-maven-plugin from 0.8.7 to 0.8.8
    • Bump jmh.version from 1.34 to 1.35
    • Bump maven-jxr-plugin from 3.1.1 to 3.2.0
    • Bump maven-dependency-plugin from 3.2.0 to 3.3.0
    • Bump maven-compiler-plugin from 3.10.0 to 3.10.1
    • Bump mockito-core from 4.3.1 to 4.4.0
    • Bump maven-site-plugin from 3.9.1 to 3.11.0
    • Bump maven-checkstyle-plugin from 3.1.1 to 3.1.2
    • Bump maven-bundle-plugin from 5.1.1 to 5.1.4
    • Update flatbuffers-java instructions in README by @a10y in https://github.com/davidmoten/rtree/pull/131

    New Contributors

    • @a10y made their first contribution in https://github.com/davidmoten/rtree/pull/131

    Full Changelog: https://github.com/davidmoten/rtree/compare/0.9...0.10

    Source code(tar.gz)
    Source code(zip)
  • 0.9(Feb 23, 2022)

    Breaking changes

    • Language level updated to java 8 by @balazsjonas in https://github.com/davidmoten/rtree/pull/102
    • serialization: bump flatbuffers from 1.3.0.1 to 2.0.3 (refresh generated code in src/main/java)
    • serialization: bump kryo from 3.0.3 to 5.3.0

    Enhancements

    • Update docs for STR bulk loading and benchmark results by @ambling in https://github.com/davidmoten/rtree/pull/68
    • bump maven-dependency-plugin from 3.1.2 to 3.2.0
    • update plugins, remove obsolete plugins
    • bump jacoco-maven-plugin from 0.8.4 to 0.8.7
    • bump maven-bundle-plugin from 4.2.1 to 5.1.1
    • simplify bundle plugin configuration #104
    • add bundle plugin #104 by @balazsjonas
    • use singleton rectangle accumulator
    • Bump taglist-maven-plugin from 2.4 to 3.0.0
    • Bump exec-maven-plugin from 1.4.0 to 3.0.0
    • Bump maven-pmd-plugin from 3.4 to 3.16.0
    • Bump maven-jxr-plugin from 2.5 to 3.1.1
    • fix compiler error, remove unnecessary warning suppression, add warning suppressions, remove unused code
    • bump jmh from 1.11.3 to 1.34
    • bump junit-extras from 0.3 to 0.4
    • bump guava-mini from 0.1.2 to 0.1.4
    • bump grumpy-core from 0.2.2 to 0.4.5
    • Bump jdepend-maven-plugin from 2.0-beta-2 to 2.0
    • Bump maven-antrun-plugin from 1.8 to 3.0.0
    • Bump maven-javadoc-plugin from 2.10.2 to 3.3.2
    • Bump maven-compiler-plugin from 3.1 to 3.10.0
    • Bump junit from 4.13.1 to 4.13.2
    • bump mockito-core from 2.11.0 to 4.3.1
    • migrate CI from travis to github actions
    • Bump junit from 4.12 to 4.13.1
    • Merge pull request #68 from ambling/update_docs_for_exp
    • upgrade to guava-mini 0.1.2 and jacoco to 0.8.4

    New Contributors

    • @dependabot made their first contribution in https://github.com/davidmoten/rtree/pull/106
    • @balazsjonas made their first contribution in https://github.com/davidmoten/rtree/pull/102

    Full Changelog: https://github.com/davidmoten/rtree/compare/0.8.7...0.9

    Source code(tar.gz)
    Source code(zip)
  • 0.8.7(Jun 26, 2019)

  • 0.8.6(Jun 19, 2018)

    • #83 fix deletion of double Point objects from rtree by implementing PointDouble.hashCode and PointDouble.equals. With thanks to reporter @jscaballero
    Source code(tar.gz)
    Source code(zip)
  • 0.8.0.4(Dec 14, 2017)

  • 0.8.0.3(Dec 14, 2017)

  • 0.8.0.2(Dec 14, 2017)

  • 0.8.0.1(Dec 14, 2017)

  • 0.8-RC10(Jul 30, 2016)

  • 0.8-RC9(Jul 6, 2016)

  • 0.8-RC8(Jun 5, 2016)

  • 0.8-RC7(Mar 28, 2016)

    • fix backpressure race condition and release volatile state (null it) before calling onComplete in OnSubscribeSearch
    • avoid cast of float to double in SplitterQuadratic
    Source code(tar.gz)
    Source code(zip)
  • 0.8-RC6(Mar 27, 2016)

    • add final to static comparators in SplitterRStar
    • improve R*-tree insert throughput by up to 100% by optimizing RStarSplitter
    • decrease object allocations and casting to increase performance of insert for R-tree and R*-tree
    Source code(tar.gz)
    Source code(zip)
  • 0.8-RC5(Mar 27, 2016)

    • reduce parsing for flatbuffers searching, use curly brackets more
    • presize ArrayLists to increase performance
    • upgrade to rxjava 1.1.2, remove patch in OnSubscribeSearch to force fast path for request Long.MAX_VALUE - 1 as workaround for RxJava PR #3227
    Source code(tar.gz)
    Source code(zip)
  • 0.8-RC4(Mar 11, 2016)

    • use Float.compare and Double.compare in Comparators class to increase perf (insert/delete)
    • use Float.compare instead of boxing primitives and calling compareTo. Should help performance of SplitterRStar (insert/delete)
    • don't extract point from flatbuffers data structure more than required (improves performance) in FlatBuffersHelper.toGeometry
    • fix infinite loop when rectangleGeographic called with double parameters (introduced in 0.8)
    • switch order of compare parameters instead of negating result because of possbility of problems at Integer.MIN_VALUE being negated
    • handle serialization of empty trees correctly
    Source code(tar.gz)
    Source code(zip)
  • 0.8-RC3(Mar 10, 2016)

  • 0.8-RC1(Mar 8, 2016)

    Flatbuffers for serialization and low-memory RTree

    • major refactor of internal data structures (many classes -> interfaces to support serialization use cases)
    • instantiation of Geometry classes now should happen only through Geometries.rectangle, Geomtries.point, etc.
    • Flatbuffers option for serializing (writing and reading an RTree to disk for instance)
    • RTree built by deserializing using flatbuffers has 1/3 memory usage
    • RTree built by deserializing using flatbuffers has reduced search performance (still O(log N) but 1/10 of throughput)
    • fix redundant check of worst combinations in QuadraticSplitter as reported by Eric Perser (not in github issues), performance improved for using QuadraticSplitter by ~2%
    Source code(tar.gz)
    Source code(zip)
  • 0.7.6(Feb 24, 2016)

    • fix for #40 which was to break from the search backpressure loop on completion
    • use BackpressureUtils in OnSubscribeSearch to avoid request overflow
    • Note that rxjava-extras is now a required dependency (for BackpressureUtils)
    Source code(tar.gz)
    Source code(zip)
  • 0.7.5(Feb 19, 2016)

    Enhancements

    • #39 remove dependency on guava (>2MB) by replacing MinMaxPriorityQueue with BoundedPriorityQueue built on backported java 8 PriorityQueue and using guava-mini (11KB)
    • upgrade to rxjava 1.1.1
    • use simplified min and max that doesn't do NaN checks
    • simplify Rectangle.intersects method

    Performance improvements

    • A combination of rtree changes and rxjava improvements have bumped up many performance benchmarks by 10 to 50 %
    • improvements in performance mean that your data set may now perform better using different RTree parameters. For instance maxChildren=10 now performs better than maxChildren=4 for the Greek Earthquake data set.
    Source code(tar.gz)
    Source code(zip)
  • 0.7.4(Feb 3, 2016)

    • fixed hang bug with RTree.nearest() #38
    • decrease memory usage of ListPair by making a Float field a float field
    • RTree.size should be final field
    Source code(tar.gz)
    Source code(zip)
  • 0.7.2(Dec 12, 2015)

  • 0.7.1(Dec 12, 2015)

    • #34 minimum bounding rectangle not calculated correctly if max x and y values of rectangle were negative. As a consequence the mbr was sometimes bigger than it needed to be. This is an important bug fix for users with lat/long geometries for instance.
    Source code(tar.gz)
    Source code(zip)
  • 0.7(Dec 12, 2015)

  • 0.6.8(Sep 23, 2015)

  • 0.6.4(Jul 14, 2015)

  • 0.6.3(May 27, 2015)

  • 0.6.2(May 26, 2015)

    • upgrade rxjava dependency to 1.0.10
    • add Geometries.rectangleLatLon(...) and Geometries.pointLatLon(...) factory methods that normalize longitude values to enable spatial searches using lat long coordinates
    Source code(tar.gz)
    Source code(zip)
  • 0.6.1(Apr 27, 2015)

    • don't touch volatile stack in requestSome() loop to avoid unnecessary memory synchronizations (~2x search throughput improvement on backpressure path)
    • fix possible race condition where two requests can concurrently initiate fast path (double emissions)
    Source code(tar.gz)
    Source code(zip)
  • 0.5.9(Apr 12, 2015)

  • 0.5.8(Mar 26, 2015)

Owner
Dave Moten
Dave Moten
Reactive Streams Utilities - Future standard utilities library for Reactive Streams.

Reactive Streams Utilities This is an exploration of what a utilities library for Reactive Streams in the JDK might look like. Glossary: A short gloss

Lightbend 61 May 27, 2021
Immutable key/value store with efficient space utilization and fast reads. They are ideal for the use-case of tables built by batch processes and shipped to multiple servers.

Minimal Perfect Hash Tables About Minimal Perfect Hash Tables are an immutable key/value store with efficient space utilization and fast reads. They a

Indeed Engineering 92 Nov 22, 2022
Persistent (immutable) collections for Java and Kotlin

What are Dexx Collections? Dexx Collections are a port of Scala's immutable, persistent collection classes to pure Java. Persistent in the context of

Andrew O'Malley 208 Sep 30, 2022
RxJava – Reactive Extensions for the JVM – a library for composing asynchronous and event-based programs using observable sequences for the Java VM.

RxJava: Reactive Extensions for the JVM RxJava is a Java VM implementation of Reactive Extensions: a library for composing asynchronous and event-base

ReactiveX 46.7k Dec 30, 2022
Hollow is a java library and toolset for disseminating in-memory datasets from a single producer to many consumers for high performance read-only access.

Hollow Hollow is a java library and toolset for disseminating in-memory datasets from a single producer to many consumers for high performance read-on

Netflix, Inc. 1.1k Dec 25, 2022
Java Collections till the last breadcrumb of memory and performance

Koloboke A family of projects around collections in Java (so far). The Koloboke Collections API A carefully designed extension of the Java Collections

Roman Leventov 967 Nov 14, 2022
Reactive Programming for Android

Reactive Programming for Android Agera is a set of classes and interfaces to help write functional, asynchronous, and reactive applications for Androi

Google 7.3k Jan 5, 2023
Zero-dependency Reactive Streams publishers library

⚡️ Mutiny Zero: a zero-dependency Reactive Streams publishers library for Java Mutiny Zero is a minimal API for creating reactive-streams compliant pu

SmallRye 14 Dec 14, 2022
fasttuple - Collections that are laid out adjacently in both on- and off-heap memory.

FastTuple Introduction There are lots of good things about working on the JVM, like a world class JIT, operating system threads, and a world class gar

BMC TrueSight Pulse (formerly Boundary) 137 Sep 30, 2022
A Primitive Collection library that reduces memory usage and improves performance

Primitive-Collections This is a Simple Primitive Collections Library i started as a hobby Project. It is based on Java's Collection Library and FastUt

Speiger 26 Dec 25, 2022
External-Memory Sorting in Java

Externalsortinginjava External-Memory Sorting in Java: useful to sort very large files using multiple cores and an external-memory algorithm. The vers

Daniel Lemire 235 Dec 29, 2022
Lightning Memory Database (LMDB) for Java: a low latency, transactional, sorted, embedded, key-value store

LMDB for Java LMDB offers: Transactions (full ACID semantics) Ordered keys (enabling very fast cursor-based iteration) Memory-mapped files (enabling o

null 680 Dec 23, 2022
jproblemgenerator creates scenarios in which Java programs leak memory or crash the JVM

jproblemgenerator creates scenarios in which Java programs leak memory or crash the JVM. It is intended to train the use of debugging tools

null 1 Jan 6, 2022
Library for creating In-memory circular buffers that use direct ByteBuffers to minimize GC overhead

Overview This project aims at creating a simple efficient building block for "Big Data" libraries, applications and frameworks; thing that can be used

Tatu Saloranta 132 Jul 28, 2022
Eclipse Collections is a collections framework for Java with optimized data structures and a rich, functional and fluent API.

English | 中文 | Deutsch | Español | Ελληνικά | Français | 日本語 | Norsk (bokmål) | Português-Brasil | Русский | हिंदी Eclipse Collections is a comprehens

Eclipse Foundation 2.1k Dec 29, 2022
Zero is a core test automation project that can be used as a basis for any kind of test automation project (API, Browser, Mobile)

Zero Zero is our feature rich, core test automation framework, that can be used as an underlying automation framework for any/and all kind of test aut

Pramod Kumar Yadav 10 Dec 16, 2022
Table-Computing (Simplified as TC) is a distributed light weighted, high performance and low latency stream processing and data analysis framework. Milliseconds latency and 10+ times faster than Flink for complicated use cases.

Table-Computing Welcome to the Table-Computing GitHub. Table-Computing (Simplified as TC) is a distributed light weighted, high performance and low la

Alibaba 34 Oct 14, 2022
A Java library for quickly and efficiently parsing and writing UUIDs

fast-uuid fast-uuid is a Java library for quickly and efficiently parsing and writing UUIDs. It yields the most dramatic performance gains when compar

Jon Chambers 142 Jan 1, 2023