Skip to content

Commit

Permalink
Accelerate build-side geometries in spatial join
Browse files Browse the repository at this point in the history
Build gemetries are often used repeated for spatial relation checks in a
spatial join.  Accelerating a geometry is a one-time cost which reduces
the complexity of these checks from `O(n)` to `O(lg n)` or even `O(1)`,
where n is the number of vertices.  When a geometry is accessed for the
join, accelerate it (an idempotent operation).

Upgraded ESRI library to 2.2.2 (from 2.2.1) to pick up a fix in
acceleration logic.
  • Loading branch information
jagill authored and mbasmanova committed Dec 5, 2018
1 parent ad05dcb commit 65edf49
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 1 deletion.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1013,7 +1013,7 @@
<dependency>
<groupId>com.esri.geometry</groupId>
<artifactId>esri-geometry-api</artifactId>
<version>2.2.1</version>
<version>2.2.2</version>
<exclusions>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
*/
package com.facebook.presto.operator;

import com.esri.core.geometry.Geometry;
import com.esri.core.geometry.GeometryCursor;
import com.esri.core.geometry.Operator;
import com.esri.core.geometry.OperatorFactoryLocal;
import com.esri.core.geometry.ogc.OGCGeometry;
import com.facebook.presto.Session;
import com.facebook.presto.geospatial.Rectangle;
Expand Down Expand Up @@ -96,6 +100,7 @@ public PagesSpatialIndexSupplier(
private static STRtree buildRTree(LongArrayList addresses, List<List<Block>> channels, int geometryChannel, Optional<Integer> radiusChannel, Optional<Integer> partitionChannel)
{
STRtree rtree = new STRtree();
Operator relateOperator = OperatorFactoryLocal.getInstance().getOperator(Operator.Type.Relate);

for (int position = 0; position < addresses.size(); position++) {
long pageAddress = addresses.getLong(position);
Expand All @@ -120,6 +125,11 @@ private static STRtree buildRTree(LongArrayList addresses, List<List<Block>> cha
continue;
}

if (!radiusChannel.isPresent()) {
// If radiusChannel is supplied, this is a distance query, for which our acceleration won't help.
accelerateGeometry(ogcGeometry, relateOperator);
}

int partition = -1;
if (partitionChannel.isPresent()) {
Block partitionBlock = channels.get(partitionChannel.get()).get(blockIndex);
Expand Down Expand Up @@ -154,6 +164,19 @@ private long computeMemorySizeInBytes(ItemBoundable item)
return ENVELOPE_INSTANCE_SIZE + ((GeometryWithPosition) item.getItem()).getEstimatedMemorySizeInBytes();
}

private static void accelerateGeometry(OGCGeometry ogcGeometry, Operator relateOperator)
{
// Recurse into GeometryCollections
GeometryCursor cursor = ogcGeometry.getEsriGeometryCursor();
while (true) {
com.esri.core.geometry.Geometry esriGeometry = cursor.next();
if (esriGeometry == null) {
break;
}
relateOperator.accelerateGeometry(esriGeometry, null, Geometry.GeometryAccelerationDegree.enumMild);
}
}

// doesn't include memory used by channels and addresses which are shared with PagesIndex
public DataSize getEstimatedSize()
{
Expand Down

0 comments on commit 65edf49

Please sign in to comment.