PostGIS  2.5.0dev-r@@SVN_REVISION@@
static int PrepGeomCacheBuilder ( const LWGEOM lwgeom,
GeomCache *  cache 
)
static

Given a generic GeomCache, and a geometry to prepare, prepare a PrepGeomCache and stick it into the GeomCache->index slot.

The PrepGeomCache includes the original GEOS geometry, and the GEOS prepared geometry, and a pointer to the MemoryContext where the callback functions are registered.

This function is passed into the generic GetGeomCache function so that it can build an appropriate indexed structure in the case of a cache hit when there is no indexed structure yet available to return.

Definition at line 299 of file lwgeom_geos_prepared.c.

References AddPrepGeomHashEntry(), PrepGeomCache::argnum, PrepGeomHashEntry::context, PrepGeomCache::context_callback, PrepGeomCache::context_statement, CreatePrepGeomHash(), PrepGeomCache::geom, PrepGeomHashEntry::geom, GetPrepGeomHashEntry(), LW_FAILURE, LW_SUCCESS, LWGEOM2GEOS(), lwgeom_get_type(), MULTIPOINTTYPE, POINTTYPE, PrepGeomCache::prepared_geom, PrepGeomHashEntry::prepared_geom, PreparedCacheDelete(), and PrepGeomHash.

300 {
301  PrepGeomCache* prepcache = (PrepGeomCache*)cache;
302  PrepGeomHashEntry* pghe;
303 
304  /*
305  * First time through? allocate the global hash.
306  */
307  if (!PrepGeomHash)
309 
310  /*
311  * No callback entry for this statement context yet? Set it up
312  */
313  if ( ! prepcache->context_callback )
314  {
315  PrepGeomHashEntry pghe;
316 #if POSTGIS_PGSQL_VERSION < 96
317  prepcache->context_callback = MemoryContextCreate(T_AllocSetContext, 8192,
318  &PreparedCacheContextMethods,
319  prepcache->context_statement,
320  "PostGIS Prepared Geometry Context");
321 
322 #else
323  prepcache->context_callback = AllocSetContextCreate(prepcache->context_statement,
324  "PostGIS Prepared Geometry Context",
325  ALLOCSET_SMALL_SIZES);
326 
327  /* PgSQL comments suggest allocating callback in the context */
328  /* being managed, so that the callback object gets cleaned along with */
329  /* the context */
330  MemoryContextCallback *callback = MemoryContextAlloc(prepcache->context_callback, sizeof(MemoryContextCallback));
331  callback->arg = (void*)(prepcache->context_callback);
332  callback->func = PreparedCacheDelete;
333  MemoryContextRegisterResetCallback(prepcache->context_callback, callback);
334 #endif
335 
336  pghe.context = prepcache->context_callback;
337  pghe.geom = 0;
338  pghe.prepared_geom = 0;
339  AddPrepGeomHashEntry( pghe );
340  }
341 
342  /*
343  * Hum, we shouldn't be asked to build a new cache on top of
344  * an existing one. Error.
345  */
346  if ( prepcache->argnum || prepcache->geom || prepcache->prepared_geom )
347  {
348  lwpgerror("PrepGeomCacheBuilder asked to build new prepcache where one already exists.");
349  return LW_FAILURE;
350  }
351 
352  /*
353  * Avoid creating a PreparedPoint around a Point or a MultiPoint.
354  * Consider changing this behavior in the future if supported GEOS
355  * versions correctly handle prepared points and multipoints and
356  * provide a performance benefit.
357  * See https://trac.osgeo.org/postgis/ticket/3437
358  */
359  if (lwgeom_get_type(lwgeom) == POINTTYPE || lwgeom_get_type(lwgeom) == MULTIPOINTTYPE)
360  return LW_FAILURE;
361 
362  prepcache->geom = LWGEOM2GEOS( lwgeom , 0);
363  if ( ! prepcache->geom ) return LW_FAILURE;
364  prepcache->prepared_geom = GEOSPrepare( prepcache->geom );
365  if ( ! prepcache->prepared_geom ) return LW_FAILURE;
366  prepcache->argnum = cache->argnum;
367 
368  /*
369  * In order to find the objects we need to destroy, we keep
370  * extra references in a global hash object.
371  */
372  pghe = GetPrepGeomHashEntry(prepcache->context_callback);
373  if ( ! pghe )
374  {
375  lwpgerror("PrepGeomCacheBuilder failed to find hash entry for context %p", prepcache->context_callback);
376  return LW_FAILURE;
377  }
378 
379  pghe->geom = prepcache->geom;
380  pghe->prepared_geom = prepcache->prepared_geom;
381 
382  return LW_SUCCESS;
383 }
const GEOSPreparedGeometry * prepared_geom
uint32_t lwgeom_get_type(const LWGEOM *geom)
Return LWTYPE number.
Definition: lwgeom.c:916
#define MULTIPOINTTYPE
Definition: liblwgeom.h:87
#define LW_SUCCESS
Definition: liblwgeom.h:79
#define LW_FAILURE
Definition: liblwgeom.h:78
const GEOSPreparedGeometry * prepared_geom
MemoryContext context_statement
const GEOSGeometry * geom
static void AddPrepGeomHashEntry(PrepGeomHashEntry pghe)
const GEOSGeometry * geom
GEOSGeometry * LWGEOM2GEOS(const LWGEOM *lwgeom, int autofix)
static void PreparedCacheDelete(void *ptr)
static void CreatePrepGeomHash(void)
static PrepGeomHashEntry * GetPrepGeomHashEntry(MemoryContext mcxt)
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition: liblwgeom.h:84
MemoryContext context_callback
static HTAB * PrepGeomHash

Here is the call graph for this function: