PostGIS  3.4.0dev-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 224 of file lwgeom_geos_prepared.c.

225 {
226  PrepGeomCache* prepcache = (PrepGeomCache*)cache;
227  PrepGeomHashEntry* pghe;
228 
229  /*
230  * First time through? allocate the global hash.
231  */
232  if (!PrepGeomHash)
234 
235  /*
236  * No callback entry for this statement context yet? Set it up
237  */
238  if ( ! prepcache->context_callback )
239  {
240  PrepGeomHashEntry pghe;
241  MemoryContextCallback *callback;
242  prepcache->context_callback = AllocSetContextCreate(prepcache->context_statement,
243  "PostGIS Prepared Geometry Context",
244  ALLOCSET_SMALL_SIZES);
245 
246  /* PgSQL comments suggest allocating callback in the context */
247  /* being managed, so that the callback object gets cleaned along with */
248  /* the context */
249  callback = MemoryContextAlloc(prepcache->context_callback, sizeof(MemoryContextCallback));
250  callback->arg = (void*)(prepcache->context_callback);
251  callback->func = PreparedCacheDelete;
252  MemoryContextRegisterResetCallback(prepcache->context_callback, callback);
253 
254  pghe.context = prepcache->context_callback;
255  pghe.geom = 0;
256  pghe.prepared_geom = 0;
257  AddPrepGeomHashEntry( pghe );
258  }
259 
260  /*
261  * Hum, we shouldn't be asked to build a new cache on top of
262  * an existing one. Error.
263  */
264  if ( prepcache->gcache.argnum || prepcache->geom || prepcache->prepared_geom )
265  {
266  lwpgerror("PrepGeomCacheBuilder asked to build new prepcache where one already exists.");
267  return LW_FAILURE;
268  }
269 
270  prepcache->geom = LWGEOM2GEOS( lwgeom , 0);
271  if ( ! prepcache->geom ) return LW_FAILURE;
272  prepcache->prepared_geom = GEOSPrepare( prepcache->geom );
273  if ( ! prepcache->prepared_geom ) return LW_FAILURE;
274  prepcache->gcache.argnum = cache->argnum;
275 
276  /*
277  * In order to find the objects we need to destroy, we keep
278  * extra references in a global hash object.
279  */
280  pghe = GetPrepGeomHashEntry(prepcache->context_callback);
281  if ( ! pghe )
282  {
283  lwpgerror("PrepGeomCacheBuilder failed to find hash entry for context %p", prepcache->context_callback);
284  return LW_FAILURE;
285  }
286 
287  pghe->geom = prepcache->geom;
288  pghe->prepared_geom = prepcache->prepared_geom;
289 
290  return LW_SUCCESS;
291 }
GEOSGeometry * LWGEOM2GEOS(const LWGEOM *lwgeom, uint8_t autofix)
#define LW_FAILURE
Definition: liblwgeom.h:96
#define LW_SUCCESS
Definition: liblwgeom.h:97
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(), PrepGeomHashEntry::prepared_geom, PrepGeomCache::prepared_geom, PreparedCacheDelete(), and PrepGeomHash.

Here is the call graph for this function: