Changeset: 2d3073d9a61c for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/2d3073d9a61c
Modified Files:
geom/monetdb5/geom.c
geom/monetdb5/geom.h
geom/monetdb5/geomBulk.c
geom/sql/40_geom.sql
Branch: geo-update-dev
Log Message:
Improved ST_Intersects with RTree index search. Differentiate between rtree
version and no index version. Changed function names.
diffs (truncated from 338 to 300 lines):
diff --git a/geom/monetdb5/geom.c b/geom/monetdb5/geom.c
--- a/geom/monetdb5/geom.c
+++ b/geom/monetdb5/geom.c
@@ -5515,11 +5515,12 @@ static mel_func geom_init_funcs[] = {
command("geom", "IntersectsGeographicjoin", wkbIntersectsGeographicJoin,
false, "TODO", args(2, 9, batarg("lr",oid),batarg("rr",oid), batarg("a", wkb),
batarg("b", wkb),
batarg("sl",oid),batarg("sr",oid),arg("nil_matches",bit),arg("estimate",lng),arg("anti",bit))),
command("geom", "Intersects", wkbIntersects, false, "Returns true if these
Geometries 'spatially intersect in 2D'", args(1,3,
arg("",bit),arg("a",wkb),arg("b",wkb))),
- command("geom", "Intersectsselect", wkbIntersectsSelect, false, "TODO",
args(1, 5, batarg("", oid), batarg("b", wkb), batarg("s", oid), arg("c", wkb),
arg("anti",bit))),
- command("geom", "Intersectsjoin", wkbIntersectsJoin, false, "TODO", args(2,
8, batarg("lr",oid),batarg("rr",oid), batarg("a", wkb), batarg("b", wkb),
batarg("sl",oid),batarg("sr",oid),arg("nil_matches",bit),arg("estimate",lng))),
+ command("geom", "Intersectsselect", wkbIntersectsSelectRTree, false, "TODO",
args(1, 5, batarg("", oid), batarg("b", wkb), batarg("s", oid), arg("c", wkb),
arg("anti",bit))),
+ command("geom", "Intersectsjoin", wkbIntersectsJoinRTree, false, "TODO",
args(2, 8, batarg("lr",oid),batarg("rr",oid), batarg("a", wkb), batarg("b",
wkb),
batarg("sl",oid),batarg("sr",oid),arg("nil_matches",bit),arg("estimate",lng))),
+
command("geom", "IntersectsMBR", mbrIntersects, false, "TODO", args(1,3,
arg("",bit),arg("a",mbr),arg("b",mbr))),
-
+
command("aggr", "Collect", wkbCollectAggr, false, "TODO", args(1, 2, arg("",
wkb), batarg("val", wkb))),
command("aggr", "subCollect", wkbCollectAggrSubGrouped, false, "TODO",
args(1, 5, batarg("", wkb), batarg("val", wkb), batarg("g", oid), batarg("e",
oid), arg("skip_nils", bit))),
command("aggr", "subCollect", wkbCollectAggrSubGroupedCand, false, "TODO",
args(1, 6, batarg("", wkb), batarg("val", wkb), batarg("g", oid),
batargany("e", 1), batarg("g", oid), arg("skip_nils", bit))),
diff --git a/geom/monetdb5/geom.h b/geom/monetdb5/geom.h
--- a/geom/monetdb5/geom.h
+++ b/geom/monetdb5/geom.h
@@ -217,6 +217,6 @@ geom_export str wkbCoordinateFromMBR_bat
geom_export str geom_sql_upgrade(int);
-geom_export str wkbIntersectsJoin(bat *lres_id, bat *rres_id, const bat *l_id,
const bat *r_id, const bat *ls_id, const bat *rs_id, bit *nil_matches, lng
*estimate);
-geom_export str wkbIntersectsSelect(bat* outid, const bat *bid , const bat
*sid, wkb **wkb_const, bit *anti);
+geom_export str wkbIntersectsJoinRTree(bat *lres_id, bat *rres_id, const bat
*l_id, const bat *r_id, const bat *ls_id, const bat *rs_id, bit *nil_matches,
lng *estimate);
+geom_export str wkbIntersectsSelectRTree(bat* outid, const bat *bid , const
bat *sid, wkb **wkb_const, bit *anti);
geom_export str mbrIntersects(bit* out, mbr** mbr1, mbr** mbr2);
diff --git a/geom/monetdb5/geomBulk.c b/geom/monetdb5/geomBulk.c
--- a/geom/monetdb5/geomBulk.c
+++ b/geom/monetdb5/geomBulk.c
@@ -16,15 +16,129 @@
#include "gdk_rtree.h"
/********** Geo Update **********/
+//TODO SRID check could come earlier?
+//TODO The BUN_NONE is not correctly retrieved in search function
static str
-filterSelectGeomGeomToBitIndex(bat* outid, const bat *bid , const bat *sid,
wkb *wkb_const, bit anti, char (*func) (const GEOSGeometry *, const
GEOSGeometry *), const char *name)
+filterSelectRTree(bat* outid, const bat *bid , const bat *sid, wkb *wkb_const,
bit anti, char (*func) (const GEOSGeometry *, const GEOSGeometry *), const char
*name)
{
BAT *out = NULL, *b = NULL, *s = NULL;
BATiter b_iter;
struct canditer ci;
GEOSGeom col_geom, const_geom;
- //Check if the geometry is null and convert to GEOS
+ if ((const_geom = wkb2geos(wkb_const)) == NULL) {
+ if ((out = BATdense(0, 0, 0)) == NULL)
+ throw(MAL, name, GDK_EXCEPTION);
+ *outid = out->batCacheid;
+ BBPkeepref(out);
+ return MAL_SUCCEED;
+ }
+ if ((b = BATdescriptor(*bid)) == NULL)
+ throw(MAL, name, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
+ if (sid && !is_bat_nil(*sid) && !(s = BATdescriptor(*sid))) {
+ BBPunfix(b->batCacheid);
+ throw(MAL, name, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
+ }
+
+ canditer_init(&ci, b, s);
+ b_iter = bat_iterator(b);
+
+ if ((out = COLnew(0, ATOMindex("oid"), ci.ncand, TRANSIENT)) == NULL) {
+ BBPunfix(b->batCacheid);
+ if (s)
+ BBPunfix(s->batCacheid);
+ throw(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
+ }
+
+ /*if (!RTREEexists(b)) {
+ if (RTREEcreate(b) != GDK_SUCCEED) {
+ //TODO What to do?
+ throw(MAL, name, "Failed to initialize RTree");
+ }
+ for (BUN j = 0; j < BATcount(b); j++) {
+ wkb *inWKB = (wkb *) BUNtvar(b_iter, j - b->hseqbase);
+ mbr *inMBR = NULL;
+ wkbMBR(&inMBR, &inWKB);
+
+ if (RTREEaddmbr(b,(mbr_t*)inMBR,j) != GDK_SUCCEED) {
+ //TODO Cleanup
+ }
+ GDKfree(inMBR);
+ inMBR = NULL;
+ }
+ }*/
+
+ //Calculate the MBR for the constant geometry
+ mbr *const_mbr = NULL;
+ wkbMBR(&const_mbr,&wkb_const);
+
+ //Get a candidate list from searching on the rtree with the constant mbr
+ BUN* results_rtree = NULL;
+ if (RTREEexists(b))
+ results_rtree = RTREEsearch(b,(mbr_t*)const_mbr, b->batCount);
+
+ //Cycle through rtree candidates
+ //If there is a original candidate list, make sure the rtree cand is in
there
+ //Then do the actual calculation for the geo predicate using the GEOS
func
+ for (int i = 0; results_rtree[i] != BUN_NONE; i++) {
+ BUN cand = results_rtree[i];
+ //If we have a candidate list that is not dense, we need to
check if the rtree candidate is also on the original candidate list
+ //TODO Check w Stefanos
+ if (ci.tpe != cand_dense) {
+ //If the original candidate list does not contain the
rtree cand, move on to next one
+ if (!canditer_contains(&ci,cand))
+ continue;
+ }
+ const wkb *col_wkb = BUNtvar(b_iter, cand - b->hseqbase);
+ if ((col_geom = wkb2geos(col_wkb)) == NULL)
+ throw(MAL, name, SQLSTATE(38000) "WKB2Geos operation
failed");
+ if (GEOSGetSRID(col_geom) != GEOSGetSRID(const_geom)) {
+ GEOSGeom_destroy(col_geom);
+ GEOSGeom_destroy(const_geom);
+ bat_iterator_end(&b_iter);
+ BBPunfix(b->batCacheid);
+ if (s)
+ BBPunfix(s->batCacheid);
+ BBPreclaim(out);
+ throw(MAL, name, SQLSTATE(38000) "Geometries of
different SRID");
+ }
+ //GEOS function returns 1 on true, 0 on false and 2 on exception
+ //TODO Deal with exception of GEOS func?
+ bit cond = ((*func)(col_geom, const_geom) == 1);
+ if (cond != anti) {
+ if (BUNappend(out, (oid*) &cand, false) != GDK_SUCCEED)
{
+ if (col_geom)
+ GEOSGeom_destroy(col_geom);
+ if (const_geom)
+ GEOSGeom_destroy(const_geom);
+ bat_iterator_end(&b_iter);
+ BBPunfix(b->batCacheid);
+ if (s)
+ BBPunfix(s->batCacheid);
+ BBPreclaim(out);
+ throw(MAL, name, SQLSTATE(HY013)
MAL_MALLOC_FAIL);
+ }
+ }
+ GEOSGeom_destroy(col_geom);
+ }
+ GEOSGeom_destroy(const_geom);
+ bat_iterator_end(&b_iter);
+ BBPunfix(b->batCacheid);
+ if (s)
+ BBPunfix(s->batCacheid);
+ *outid = out->batCacheid;
+ BBPkeepref(out);
+ return MAL_SUCCEED;
+}
+
+static str
+filterSelectNoIndex(bat* outid, const bat *bid , const bat *sid, wkb
*wkb_const, bit anti, char (*func) (const GEOSGeometry *, const GEOSGeometry
*), const char *name)
+{
+ BAT *out = NULL, *b = NULL, *s = NULL;
+ BATiter b_iter;
+ struct canditer ci;
+ GEOSGeom col_geom, const_geom;
+
if ((const_geom = wkb2geos(wkb_const)) == NULL) {
if ((out = BATdense(0, 0, 0)) == NULL)
throw(MAL, name, GDK_EXCEPTION);
@@ -39,6 +153,10 @@ filterSelectGeomGeomToBitIndex(bat* outi
BBPunfix(b->batCacheid);
throw(MAL, name, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
}
+
+ canditer_init(&ci, b, s);
+ b_iter = bat_iterator(b);
+
if ((out = COLnew(0, ATOMindex("oid"), ci.ncand, TRANSIENT)) == NULL) {
BBPunfix(b->batCacheid);
if (s)
@@ -46,34 +164,11 @@ filterSelectGeomGeomToBitIndex(bat* outi
throw(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
}
- //Calculate the MBR for the constant geometry
- mbr *const_mbr = NULL;
- wkbMBR(&const_mbr,&wkb_const);
-
- //Get a candidate list from searching on the rtree with the constant mbr
- BUN* results_rtree = RTREEsearch(b,(mbr_t*)const_mbr, b->batCount);
-
- canditer_init(&ci, b, s);
- b_iter = bat_iterator(b);
-
- //Intersect prev_cands with rtree_cands
- //Cycle through rtree_cands
- // if there is prev_cands -> bin search
- // if there is not -> just cycle through rtree_cands
-
for (BUN i = 0; i < ci.ncand; i++) {
- oid c_oid = canditer_next(&ci);
-
- int i = 0;
- while (results_rtree[i] != BUN_NONE && results_rtree[i] !=
c_oid) {
- i++;
- }
- if (results_rtree[i] == BUN_NONE)
- continue;
-
- const wkb *col_wkb = BUNtvar(b_iter, c_oid - b->hseqbase);
+ oid cand = canditer_next(&ci) - b->hseqbase;
+ const wkb *col_wkb = BUNtvar(b_iter, cand);
if ((col_geom = wkb2geos(col_wkb)) == NULL)
- continue;
+ throw(MAL, name, SQLSTATE(38000) "WKB2Geos operation
failed");
if (GEOSGetSRID(col_geom) != GEOSGetSRID(const_geom)) {
GEOSGeom_destroy(col_geom);
GEOSGeom_destroy(const_geom);
@@ -84,12 +179,11 @@ filterSelectGeomGeomToBitIndex(bat* outi
BBPreclaim(out);
throw(MAL, name, SQLSTATE(38000) "Geometries of
different SRID");
}
-
- //GEOS functino returns 1 on true, 0 on false and 2 on exception
- char ret = ((*func)(col_geom, const_geom));
- bit cond = (ret == 1);
+ //GEOS function returns 1 on true, 0 on false and 2 on exception
+ //TODO Deal with exception of GEOS func?
+ bit cond = ((*func)(col_geom, const_geom) == 1);
if (cond != anti) {
- if (BUNappend(out, &c_oid, false) != GDK_SUCCEED) {
+ if (BUNappend(out, (oid*) &cand, false) != GDK_SUCCEED)
{
if (col_geom)
GEOSGeom_destroy(col_geom);
if (const_geom)
@@ -102,7 +196,6 @@ filterSelectGeomGeomToBitIndex(bat* outi
throw(MAL, name, SQLSTATE(HY013)
MAL_MALLOC_FAIL);
}
}
- //TODO Deal with exception?
GEOSGeom_destroy(col_geom);
}
GEOSGeom_destroy(const_geom);
@@ -116,13 +209,15 @@ filterSelectGeomGeomToBitIndex(bat* outi
}
str
-wkbIntersectsSelect(bat* outid, const bat *bid , const bat *sid, wkb
**wkb_const, bit *anti) {
- return
filterSelectGeomGeomToBitIndex(outid,bid,sid,*wkb_const,*anti,GEOSIntersects,"geom.wkbIntersectsSelect");
+wkbIntersectsSelectRTree(bat* outid, const bat *bid , const bat *sid, wkb
**wkb_const, bit *anti) {
+ return
filterSelectRTree(outid,bid,sid,*wkb_const,*anti,GEOSIntersects,"geom.wkbIntersectsSelectRTree");
+}
+
}
static str
-filterJoinGeomGeomDoubleToBit(bat *lres_id, bat *rres_id, const bat *l_id,
const bat *r_id, double double_flag, const bat *ls_id, const bat *rs_id, bit
nil_matches, lng *estimate, char (*func) (const GEOSGeometry *, const
GEOSGeometry *, double), const char *name)
{
+ (void) double_flag;
BAT *lres = NULL, *rres = NULL, *l = NULL, *r = NULL, *ls = NULL, *rs =
NULL;
BATiter l_iter, r_iter;
str msg = MAL_SUCCEED;
@@ -207,7 +302,7 @@ filterJoinGeomGeomDoubleToBit(bat *lres_
goto free;
}
//Apply the (Geom, Geom) -> bit function
- bit cond = ((*func)(l_geom, r_geom, double_flag) ==
'1');
+ bit cond = ((*func)(l_geom, r_geom) == '1');
if (cond != anti) {
if (BUNappend(lres, &l_oid, false) !=
GDK_SUCCEED || BUNappend(rres, &r_oid, false) != GDK_SUCCEED) {
msg = createException(MAL, name,
SQLSTATE(HY013) MAL_MALLOC_FAIL);
@@ -269,9 +364,25 @@ free:
return msg;
}
+static str
+filterJoinRTree(bat *lres_id, bat *rres_id, const bat *l_id, const bat *r_id,
double double_flag, const bat *ls_id, const bat *rs_id, bit nil_matches, lng
*estimate, char (*func) (const GEOSGeometry *, const GEOSGeometry *), const
char *name) {
+ (void) lres_id;
+ (void) rres_id;
+ (void) l_id;
+ (void) r_id;
+ (void) double_flag;
+ (void) ls_id;
+ (void) rs_id;
+ (void) nil_matches;
+ (void) estimate;
+ (void) func;
+ (void) name;
+ return MAL_SUCCEED;
+}
+
str
-wkbIntersectsJoin(bat *lres_id, bat *rres_id, const bat *l_id, const bat
*r_id, const bat *ls_id, const bat *rs_id, bit *nil_matches, lng *estimate) {
- return
filterJoinGeomGeomDoubleToBit(lres_id,rres_id,l_id,r_id,0,ls_id,rs_id,*nil_matches,estimate,GEOSDistanceWithin,"geom.wkbIntersectsJoin");
+wkbIntersectsJoinRTree(bat *lres_id, bat *rres_id, const bat *l_id, const bat
*r_id, const bat *ls_id, const bat *rs_id, bit *nil_matches, lng *estimate) {
+ return
filterJoinRTree(lres_id,rres_id,l_id,r_id,0,ls_id,rs_id,*nil_matches,estimate,GEOSIntersects,"geom.wkbIntersectsJoinRTree");
}
@@ -297,9 +408,8 @@ wkbMBR_bat(bat *outBAT_id, bat *inBAT_id
throw(MAL, "batgeom.mbr", SQLSTATE(HY013) MAL_MALLOC_FAIL);
}
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]