PostGIS  2.5.7dev-r@@SVN_REVISION@@

◆ PrepGeomCacheBuilder()

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.

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  MemoryContextCallback *callback;
324  prepcache->context_callback = AllocSetContextCreate(prepcache->context_statement,
325  "PostGIS Prepared Geometry Context",
326  ALLOCSET_SMALL_SIZES);
327 
328  /* PgSQL comments suggest allocating callback in the context */
329  /* being managed, so that the callback object gets cleaned along with */
330  /* the context */
331  callback = MemoryContextAlloc(prepcache->context_callback, sizeof(MemoryContextCallback));
332  callback->arg = (void*)(prepcache->context_callback);
333  callback->func = PreparedCacheDelete;
334  MemoryContextRegisterResetCallback(prepcache->context_callback, callback);
335 #endif
336 
337  pghe.context = prepcache->context_callback;
338  pghe.geom = 0;
339  pghe.prepared_geom = 0;
340  AddPrepGeomHashEntry( pghe );
341  }
342 
343  /*
344  * Hum, we shouldn't be asked to build a new cache on top of
345  * an existing one. Error.
346  */
347  if ( prepcache->gcache.argnum || prepcache->geom || prepcache->prepared_geom )
348  {
349  lwpgerror("PrepGeomCacheBuilder asked to build new prepcache where one already exists.");
350  return LW_FAILURE;
351  }
352 
353  /*
354  * Avoid creating a PreparedPoint around a Point or a MultiPoint.
355  * Consider changing this behavior in the future if supported GEOS
356  * versions correctly handle prepared points and multipoints and
357  * provide a performance benefit.
358  * See https://trac.osgeo.org/postgis/ticket/3437
359  */
360  if (lwgeom_get_type(lwgeom) == POINTTYPE || lwgeom_get_type(lwgeom) == MULTIPOINTTYPE)
361  return LW_FAILURE;
362 
363  prepcache->geom = LWGEOM2GEOS( lwgeom , 0);
364  if ( ! prepcache->geom ) return LW_FAILURE;
365  prepcache->prepared_geom = GEOSPrepare( prepcache->geom );
366  if ( ! prepcache->prepared_geom ) return LW_FAILURE;
367  prepcache->gcache.argnum = cache->argnum;
368 
369  /*
370  * In order to find the objects we need to destroy, we keep
371  * extra references in a global hash object.
372  */
373  pghe = GetPrepGeomHashEntry(prepcache->context_callback);
374  if ( ! pghe )
375  {
376  lwpgerror("PrepGeomCacheBuilder failed to find hash entry for context %p", prepcache->context_callback);
377  return LW_FAILURE;
378  }
379 
380  pghe->geom = prepcache->geom;
381  pghe->prepared_geom = prepcache->prepared_geom;
382 
383  return LW_SUCCESS;
384 }
GEOSGeometry * LWGEOM2GEOS(const LWGEOM *lwgeom, uint8_t autofix)
#define LW_FAILURE
Definition: liblwgeom.h:79
#define LW_SUCCESS
Definition: liblwgeom.h:80
#define MULTIPOINTTYPE
Definition: liblwgeom.h:88
uint32_t lwgeom_get_type(const LWGEOM *geom)
Return LWTYPE number.
Definition: lwgeom.c:923
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition: liblwgeom.h:85
static void CreatePrepGeomHash(void)
static HTAB * PrepGeomHash
static void AddPrepGeomHashEntry(PrepGeomHashEntry pghe)
static void PreparedCacheDelete(void *ptr)
static PrepGeomHashEntry * GetPrepGeomHashEntry(MemoryContext mcxt)
const GEOSPreparedGeometry * prepared_geom
MemoryContext context_statement
const GEOSGeometry * geom
MemoryContext context_callback
const GEOSGeometry * geom
const GEOSPreparedGeometry * prepared_geom

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

Here is the call graph for this function: