Changeset: 003387d18d46 for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=003387d18d46 Modified Files: geom/monetdb5/geom.c geom/monetdb5/geom.h geom/monetdb5/geom.mal Branch: sfcgal Log Message:
Brut force NN filter join. Fix a crash and better error message diffs (truncated from 414 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 @@ -3804,7 +3804,8 @@ wkbMakePolygon(wkb **out, wkb **external //create a linearRing using the copy of the coordinates linearRingGeometry = GEOSGeom_createLinearRing(coordSeq_copy); if (linearRingGeometry == NULL) { - GEOSCoordSeq_destroy(coordSeq_copy); + //TODO: Make sure there is not a leak + //GEOSCoordSeq_destroy(coordSeq_copy); throw(MAL, "geom.Polygon", "GEOSGeom_createLinearRing failed"); } @@ -3832,7 +3833,7 @@ wkbMakeLine(wkb **out, wkb **geom1WKB, w GEOSCoordSeq outCoordSeq; const GEOSCoordSequence *geom1CoordSeq = NULL, *geom2CoordSeq = NULL; unsigned int i = 0, geom1Size = 0, geom2Size = 0; - unsigned geom1Dimension = 0, geom2Dimension = 0; + unsigned int geom1Dimension = 0, geom2Dimension = 0; double x, y, z; int srid; str err = MAL_SUCCEED; @@ -3879,7 +3880,7 @@ wkbMakeLine(wkb **out, wkb **geom1WKB, w err = createException(MAL, "geom.MakeLine", "GEOSGeom_getDimensions failed"); } else if (geom1Dimension != geom2Dimension) { - err = createException(MAL, "geom.MakeLine", "Geometries should be of the same dimension"); + err = createException(MAL, "geom.MakeLine", "Geometries should be of the same dimension: dim1 %u and dim2 %u", geom1Dimension, geom2Dimension); } //get the number of coordinates in the two geometries else if (!GEOSCoordSeq_getSize(geom1CoordSeq, &geom1Size) || @@ -10667,6 +10668,357 @@ DWithinXYZsubjoin(bat *lres, bat *rres, } static str +DNNXYZsubjoin_intern(bat *lres, bat *rres, bat *lid, bat *xid, bat*yid, bat *zid, int *srid, const char *name) +{ + str msg = MAL_SUCCEED; + BAT *xl, *xr, *bl, *bx, *by, *bz; + oid lo, ro; + BATiter lBAT_iter, xBAT_iter, yBAT_iter, zBAT_iter; + uint32_t j = 0; + BUN px = 0, py = 0, pz =0, pl = 0, qx = 0, qy = 0, qz = 0, ql = 0; + GEOSGeom *rGeometries = NULL; + mbr **rMBRs = NULL; + int outs = 0; + int numThreads = 1, i = 0; + GEOSGeom *lGeometries = NULL; + double dist = -1.0; +#ifdef GEOMBULK_DEBUG + static struct timeval start, stop; + unsigned long long t; +#endif + + if( (bl= BATdescriptor(*lid)) == NULL ) + throw(MAL, name, RUNTIME_OBJECT_MISSING); + + if( (bx= BATdescriptor(*xid)) == NULL ){ + BBPunfix(*lid); + throw(MAL, name, RUNTIME_OBJECT_MISSING); + } + + if( (by= BATdescriptor(*yid)) == NULL ){ + BBPunfix(*lid); + BBPunfix(*xid); + throw(MAL, name, RUNTIME_OBJECT_MISSING); + } + + if( (bz= BATdescriptor(*zid)) == NULL ){ + BBPunfix(*lid); + BBPunfix(*xid); + BBPunfix(*yid); + throw(MAL, name, RUNTIME_OBJECT_MISSING); + } + + xl = COLnew(0, TYPE_oid, 0, TRANSIENT); + if ( xl == NULL){ + BBPunfix(*lid); + BBPunfix(*xid); + BBPunfix(*yid); + BBPunfix(*zid); + throw(MAL, name, MAL_MALLOC_FAIL); + } + + xr = COLnew(0, TYPE_oid, 0, TRANSIENT); + if ( xr == NULL){ + BBPunfix(*lid); + BBPunfix(*xid); + BBPunfix(*yid); + BBPunfix(*zid); + BBPunfix(xl->batCacheid); + throw(MAL, name, MAL_MALLOC_FAIL); + } + + if ( !BATcount(bx) || !BATcount(bl)) { + BBPunfix(*lid); + BBPunfix(*xid); + BBPunfix(*yid); + BBPunfix(*zid); + BBPkeepref(*lres = xl->batCacheid); + BBPkeepref(*rres = xr->batCacheid); + return MAL_SUCCEED; + } + + /*iterator over the BATs*/ + lBAT_iter = bat_iterator(bl); + xBAT_iter = bat_iterator(bx); + yBAT_iter = bat_iterator(by); + zBAT_iter = bat_iterator(bz); + + /*Get the Geometry for the inner BAT*/ + if ( (BATcount(bx)) && (rGeometries = (GEOSGeom*) GDKzalloc(sizeof(GEOSGeom) * BATcount(bx))) == NULL) { + BBPunfix(*lid); + BBPunfix(*xid); + BBPunfix(*yid); + BBPunfix(*zid); + BBPunfix(xl->batCacheid); + BBPunfix(xr->batCacheid); + throw(MAL, name, MAL_MALLOC_FAIL); + } + if ( (BATcount(bx)) && (rMBRs = (mbr**) GDKzalloc(sizeof(mbr*) * BATcount(bx))) == NULL) { + GDKfree(rGeometries); + BBPunfix(*lid); + BBPunfix(*xid); + BBPunfix(*yid); + BBPunfix(*zid); + BBPunfix(xl->batCacheid); + BBPunfix(xr->batCacheid); + throw(MAL, name, MAL_MALLOC_FAIL); + } +#ifdef GEOMBULK_DEBUG + gettimeofday(&start, NULL); +#endif + BATloop(bx, px, qx) { + GEOSGeom rGeos = NULL; + double *x, *y, *z; + GEOSCoordSeq seq; + x = (double*) BUNtail(xBAT_iter, px); + y = (double*) BUNtail(yBAT_iter, px); + z = (double*) BUNtail(zBAT_iter, px); + + /*Create Geometry*/ + if (*x == dbl_nil || *y == dbl_nil || *z == dbl_nil) { + rGeos = GEOSGeom_createEmptyPoint(); + } else { + //create the point from the coordinates + seq = GEOSCoordSeq_create(1, 3); + + if (seq == NULL) { + GEOSCoordSeq_destroy(seq); + for (j = 0; j < px-1;j++) { + GEOSGeom_destroy(rGeometries[j]); + if (rMBRs[j]) + GDKfree(rMBRs[j]); + } + msg = createException(MAL, name, "GEOSCoordSeq_create failed"); + break; + } + + if (!GEOSCoordSeq_setOrdinate(seq, 0, 0, *x) || + !GEOSCoordSeq_setOrdinate(seq, 0, 1, *y) || + !GEOSCoordSeq_setOrdinate(seq, 0, 2, *z)) { + GEOSCoordSeq_destroy(seq); + for (j = 0; j < px-1;j++) { + GEOSGeom_destroy(rGeometries[j]); + if (rMBRs[j]) + GDKfree(rMBRs[j]); + } + msg = createException(MAL, name, "GEOSCoordSeq_setOrdinate failed"); + break; + } + + if ((rGeos = GEOSGeom_createPoint(seq)) == NULL) { + GEOSCoordSeq_destroy(seq); + for (j = 0; j < px-1;j++) { + GEOSGeom_destroy(rGeometries[j]); + if (rMBRs[j]) + GDKfree(rMBRs[j]); + } + msg = createException(MAL, name, "Failed to create GEOSGeometry from the coordinates"); + break; + } + + if (*srid != int_nil) + GEOSSetSRID(rGeos, *srid); + } + rGeometries[px] = rGeos; + rMBRs[px] = mbrFromGeos(rGeometries[px]); + if (mbr_isnil(rMBRs[px])) { + for (j = 0; j < px;j++) { + GEOSGeom_destroy(rGeometries[j]); + if (rMBRs[j]) + GDKfree(rMBRs[j]); + } + msg = createException(MAL, name, "Failed to create mbrFromGeos"); + break; + } + } +#ifdef GEOMBULK_DEBUG + gettimeofday(&stop, NULL); + t = 1000 * (stop.tv_sec - start.tv_sec) + (stop.tv_usec - start.tv_usec) / 1000; + fprintf(stdout, "%s first BATloop qx %d %llu ms\n", name, qx, t); +#endif + + if (msg != MAL_SUCCEED) { + GDKfree(rGeometries); + GDKfree(rMBRs); + BBPunfix(*lid); + BBPunfix(*xid); + BBPunfix(*yid); + BBPunfix(*zid); + BBPunfix(xl->batCacheid); + BBPunfix(xr->batCacheid); + return msg; + } +#ifdef OPENMP + numThreads = OPENCL_THREADS; +#endif + if ( (lGeometries = GDKmalloc(sizeof(GEOSGeom) * numThreads)) == NULL) { + GDKfree(rGeometries); + GDKfree(rMBRs); + BBPunfix(*lid); + BBPunfix(*xid); + BBPunfix(*yid); + BBPunfix(*zid); + BBPunfix(xl->batCacheid); + BBPunfix(xr->batCacheid); + } + + lo = bl->hseqbase; +#ifdef GEOMBULK_DEBUG + gettimeofday(&start, NULL); +#endif + BATloop(bl, pl, ql) { + str err = NULL; + wkb *lWKB = NULL; + mbr *lMBR = NULL; + ro = bx->hseqbase; + int lSRID = 0; + dist = -1; + + lWKB = (wkb *) BUNtail(lBAT_iter, pl); + lGeometries[0] = wkb2geos(lWKB); + if ( !lGeometries[0] ) { + msg = createException(MAL, name, "wkb2geos failed"); + break; + } + + lSRID = GEOSGetSRID(lGeometries[0]); + if (lSRID != *srid) { + for (j = 0; j < numThreads; j++) { + GEOSGeom_destroy(lGeometries[j]); + } + msg = createException(MAL, name, "Geometries of different SRID"); + break; + } + + lMBR = mbrFromGeos(lGeometries[0]); + if (lMBR == NULL || mbr_isnil(lMBR)) { + GEOSGeom_destroy(lGeometries[0]); + msg = createException(MAL, name, "mbrFromGeos failed"); + break; + } + + for (j = 1; j < numThreads; j++) { + lGeometries[j] = GEOSGeom_clone(lGeometries[0]); + } + + //for (j = 0; j < BATcount(bx); j++, ro++) { +#ifdef OPENMP + //omp_set_dynamic(OPENCL_DYNAMIC); // Explicitly disable dynamic teams + omp_set_dynamic(0); // Explicitly disable dynamic teams + //omp_set_num_threads(OPENCL_THREADS); + omp_set_num_threads(1); + #pragma omp parallel for +#endif + for (j = 0; j < BATcount(bx); j++) { + mbr *rMBR = NULL; + double distance = 0.0; + int res = 0; + int tNum = 0; +#ifdef OPENMP + tNum = omp_get_thread_num(); +#endif + GEOSGeom rGeometry = rGeometries[j]; + + if (msg != MAL_SUCCEED) + continue; + + if(dist == -1) { + if ( (res = GEOSDistance(lGeometries[tNum], rGeometry, &distance)) == 0) { + msg = createException(MAL, name, "GEOSDistance failed"); +#ifdef OPENMP + #pragma omp cancelregion +#else + break; +#endif + } + dist = distance; + outs = j; _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list