[postgis-tickets] r17547 - PROJ: Remove the extra MemoryContext for PG9.6+
Raul
raul at rmr.ninja
Wed Jun 19 08:23:33 PDT 2019
Author: algunenano
Date: 2019-06-19 08:23:33 -0700 (Wed, 19 Jun 2019)
New Revision: 17547
Modified:
trunk/libpgcommon/lwgeom_cache.c
trunk/libpgcommon/lwgeom_cache.h
trunk/libpgcommon/lwgeom_transform.c
Log:
PROJ: Remove the extra MemoryContext for PG9.6+
In PG9.6+ we can allocate callbacks in the parent node
and associate them directly without creating new contextes
References #4372
Modified: trunk/libpgcommon/lwgeom_cache.c
===================================================================
--- trunk/libpgcommon/lwgeom_cache.c 2019-06-19 15:21:29 UTC (rev 17546)
+++ trunk/libpgcommon/lwgeom_cache.c 2019-06-19 15:23:33 UTC (rev 17547)
@@ -93,19 +93,11 @@
if (cache)
{
- int i;
-
POSTGIS_DEBUGF(3,
"Allocating PROJCache for portal with transform() MemoryContext %p",
FIContext(fcinfo));
/* Put in any required defaults */
- for (i = 0; i < PROJ_CACHE_ITEMS; i++)
- {
- cache->PROJSRSCache[i].srid_from = SRID_UNKNOWN;
- cache->PROJSRSCache[i].srid_to = SRID_UNKNOWN;
- cache->PROJSRSCache[i].projection = NULL;
- cache->PROJSRSCache[i].projection_mcxt = NULL;
- }
+ memset(cache->PROJSRSCache, 0, sizeof(PROJSRSCacheItem) * PROJ_CACHE_ITEMS);
cache->type = PROJ_CACHE_ENTRY;
cache->PROJSRSCacheCount = 0;
cache->PROJSRSCacheContext = FIContext(fcinfo);
Modified: trunk/libpgcommon/lwgeom_cache.h
===================================================================
--- trunk/libpgcommon/lwgeom_cache.h 2019-06-19 15:21:29 UTC (rev 17546)
+++ trunk/libpgcommon/lwgeom_cache.h 2019-06-19 15:23:33 UTC (rev 17547)
@@ -68,7 +68,9 @@
int32_t srid_from;
int32_t srid_to;
LWPROJ *projection;
+#if POSTGIS_PGSQL_VERSION < 96
MemoryContext projection_mcxt;
+#endif
}
PROJSRSCacheItem;
Modified: trunk/libpgcommon/lwgeom_transform.c
===================================================================
--- trunk/libpgcommon/lwgeom_transform.c 2019-06-19 15:21:29 UTC (rev 17546)
+++ trunk/libpgcommon/lwgeom_transform.c 2019-06-19 15:23:33 UTC (rev 17547)
@@ -48,18 +48,6 @@
*/
#define PROJ_BACKEND_HASH_SIZE 256
-/**
- * Backend PROJ hash table
- *
- * This hash table stores a key/value pair of MemoryContext/PJ objects.
- * Whenever we create a PJ object using pj_init(), we create a separate
- * MemoryContext as a child context of the current executor context.
- * The MemoryContext/PJ object is stored in this hash table so
- * that when PROJSRSCacheDelete() is called during query cleanup, we can
- * lookup the PJ object based upon the MemoryContext parameter and hence
- * pj_free() it.
- */
-static HTAB *PJHash = NULL;
/**
* Utility structure to get many potential string representations
@@ -71,23 +59,6 @@
char* proj4text;
} PjStrs;
-
-typedef struct struct_PJHashEntry
-{
- MemoryContext ProjectionContext;
- LWPROJ *projection;
-}
-PJHashEntry;
-
-
-/* PJ Hash API */
-uint32 mcxt_ptr_hash(const void *key, Size keysize);
-
-static HTAB *CreatePJHash(void);
-static void DeletePJHashEntry(MemoryContext mcxt);
-static LWPROJ *GetPJHashEntry(MemoryContext mcxt);
-static void AddPJHashEntry(MemoryContext mcxt, LWPROJ *projection);
-
/* Internal Cache API */
static LWPROJ *AddToPROJSRSCache(PROJPortalCache *PROJCache, int32_t srid_from, int32_t srid_to);
static void DeleteFromPROJSRSCache(PROJPortalCache *PROJCache, int32_t srid_from, int32_t srid_to);
@@ -118,42 +89,61 @@
}
static void
-PROJSRSDestroyPJ(LWPROJ *pj)
+PROJSRSDestroyPJ(void *projection)
{
+ LWPROJ *pj = (LWPROJ *)projection;
#if POSTGIS_PROJ_VERSION < 60
/* Ape the Proj 6+ API for versions < 6 */
if (pj->pj_from)
+ {
pj_free(pj->pj_from);
+ pj->pj_from = NULL;
+ }
if (pj->pj_to)
+ {
pj_free(pj->pj_to);
- pfree(pj);
+ pj->pj_to = NULL;
+ }
#else
- proj_destroy(pj->pj);
- pfree(pj);
+ if (pj->pj)
+ {
+ proj_destroy(pj->pj);
+ pj->pj = NULL;
+ }
#endif
}
-#if 0
-static const char *
-PJErrStr()
+#if POSTGIS_PGSQL_VERSION < 96
+/**
+ * Backend PROJ hash table
+ *
+ * This hash table stores a key/value pair of MemoryContext/PJ objects.
+ * Whenever we create a PJ object using pj_init(), we create a separate
+ * MemoryContext as a child context of the current executor context.
+ * The MemoryContext/PJ object is stored in this hash table so
+ * that when PROJSRSCacheDelete() is called during query cleanup, we can
+ * lookup the PJ object based upon the MemoryContext parameter and hence
+ * pj_free() it.
+ */
+static HTAB *PJHash = NULL;
+
+typedef struct struct_PJHashEntry
{
- const char *pj_errstr = pj_strerrno(*pj_get_errno_ref());
- if (!pj_errstr)
- return "";
- return pj_errstr;
-}
-#endif
+ MemoryContext ProjectionContext;
+ LWPROJ *projection;
+} PJHashEntry;
+/* PJ Hash API */
+uint32 mcxt_ptr_hash(const void *key, Size keysize);
+
+static HTAB *CreatePJHash(void);
+static void DeletePJHashEntry(MemoryContext mcxt);
+static LWPROJ *GetPJHashEntry(MemoryContext mcxt);
+static void AddPJHashEntry(MemoryContext mcxt, LWPROJ *projection);
+
static void
-#if POSTGIS_PGSQL_VERSION < 96
PROJSRSCacheDelete(MemoryContext context)
{
-#else
-PROJSRSCacheDelete(void *ptr)
-{
- MemoryContext context = (MemoryContext)ptr;
-#endif
-
/* Lookup the PJ pointer in the global hash table so we can free it */
LWPROJ *projection = GetPJHashEntry(context);
@@ -168,8 +158,6 @@
DeletePJHashEntry(context);
}
-#if POSTGIS_PGSQL_VERSION < 96
-
static void
PROJSRSCacheInit(MemoryContext context)
{
@@ -237,7 +225,6 @@
#endif
};
-#endif /* POSTGIS_PGSQL_VERSION < 96 */
/*
* PROJ PJ Hash Table functions
@@ -327,6 +314,7 @@
he->projection = NULL;
}
+#endif /* POSTGIS_PGSQL_VERSION < 96 */
/*****************************************************************************
* Per-cache management functions
@@ -600,7 +588,10 @@
static LWPROJ *
AddToPROJSRSCache(PROJPortalCache *PROJCache, int32_t srid_from, int32_t srid_to)
{
- MemoryContext PJMemoryContext, oldContext;
+#if POSTGIS_PGSQL_VERSION < 96
+ MemoryContext PJMemoryContext;
+#endif
+ MemoryContext oldContext;
PjStrs from_strs, to_strs;
char *pj_from_str, *pj_to_str;
@@ -710,38 +701,28 @@
&PROJSRSCacheContextMethods,
PROJCache->PROJSRSCacheContext,
"PostGIS PROJ PJ Memory Context");
-#else
- PJMemoryContext = AllocSetContextCreate(PROJCache->PROJSRSCacheContext,
- "PostGIS PROJ PJ Memory Context",
- ALLOCSET_SMALL_SIZES);
- /* PgSQL comments suggest allocating callback in the context */
- /* being managed, so that the callback object gets cleaned along with */
- /* the context */
- {
- MemoryContextCallback *callback = MemoryContextAlloc(PJMemoryContext, sizeof(MemoryContextCallback));
- callback->arg = (void*)PJMemoryContext;
- callback->func = PROJSRSCacheDelete;
- MemoryContextRegisterResetCallback(PJMemoryContext, callback);
- }
-#endif
-
- /* Create the backend hash if it doesn't already exist */
+ /* We register a new memory context to use it to delete the projection on exit */
if (!PJHash)
PJHash = CreatePJHash();
- /*
- * Add the MemoryContext to the backend hash so we can
- * clean up upon portal shutdown
- */
- POSTGIS_DEBUGF(3, "adding projection object (%p) to hash table with MemoryContext key (%p)", projection, PJMemoryContext);
-
AddPJHashEntry(PJMemoryContext, projection);
+#else
+ /* We register a new callback to delete the projection on exit */
+ MemoryContextCallback *callback =
+ MemoryContextAlloc(PROJCache->PROJSRSCacheContext, sizeof(MemoryContextCallback));
+ callback->func = PROJSRSDestroyPJ;
+ callback->arg = (void *)projection;
+ MemoryContextRegisterResetCallback(PROJCache->PROJSRSCacheContext, callback);
+#endif
+
PROJCache->PROJSRSCache[PROJCache->PROJSRSCacheCount].srid_from = srid_from;
PROJCache->PROJSRSCache[PROJCache->PROJSRSCacheCount].srid_to = srid_to;
PROJCache->PROJSRSCache[PROJCache->PROJSRSCacheCount].projection = projection;
+#if POSTGIS_PGSQL_VERSION < 96
PROJCache->PROJSRSCache[PROJCache->PROJSRSCacheCount].projection_mcxt = PJMemoryContext;
+#endif
PROJCache->PROJSRSCacheCount++;
MemoryContextSwitchTo(oldContext);
@@ -766,9 +747,16 @@
* Zero out the entries and free the PROJ handle
* by deleting the memory context
*/
+#if POSTGIS_PGSQL_VERSION < 96
+ /* Deleting the memory context will free the PROJ objects */
MemoryContextDelete(PROJCache->PROJSRSCache[i].projection_mcxt);
+ PROJCache->PROJSRSCache[i].projection_mcxt = NULL;
+#else
+ /* Call PROJSRSDestroyPJ to free the PROJ objects memory now instead of
+ * waiting for the parent memory context to exit */
+ PROJSRSDestroyPJ(PROJCache->PROJSRSCache[i].projection);
+#endif
PROJCache->PROJSRSCache[i].projection = NULL;
- PROJCache->PROJSRSCache[i].projection_mcxt = NULL;
PROJCache->PROJSRSCache[i].srid_from = SRID_UNKNOWN;
PROJCache->PROJSRSCache[i].srid_to = SRID_UNKNOWN;
}
@@ -796,7 +784,7 @@
*pj = AddToPROJSRSCache(proj_cache, srid_from, srid_to);
}
- return LW_SUCCESS;
+ return pj != NULL;
}
static int
More information about the postgis-tickets
mailing list