PostGIS  2.4.9dev-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 303 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.

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