[postgis-commits] svn - r3074 - trunk/lwgeom

postgis-commits at postgis.refractions.net postgis-commits at postgis.refractions.net
Tue Oct 7 16:51:14 PDT 2008


Author: pramsey
Date: 2008-10-07 16:51:14 -0700 (Tue, 07 Oct 2008)
New Revision: 3074

Modified:
   trunk/lwgeom/lwgeom_geos_c.c
Log:
Re-work prepared geom cache to use memcmp instead of keys, step 1.


Modified: trunk/lwgeom/lwgeom_geos_c.c
===================================================================
--- trunk/lwgeom/lwgeom_geos_c.c	2008-10-07 20:38:23 UTC (rev 3073)
+++ trunk/lwgeom/lwgeom_geos_c.c	2008-10-07 23:51:14 UTC (rev 3074)
@@ -3564,6 +3564,10 @@
 {
 	int32                         key1;
 	int32                         key2;
+	uchar*                         serialized1;
+	uchar*                         serialized2;
+	size_t                        serialized1_size;
+	size_t                        serialized2_size;
 	int32                         argnum;
 	const GEOSPreparedGeometry*   prepared_geom;
 	const GEOSGeometry*           geom;
@@ -3591,11 +3595,11 @@
 } PrepGeomHashEntry;
 
 /* Utility function to pull or prepare the current cache */
-PrepGeomCache *GetPrepGeomCache(FunctionCallInfoData *fcinfo, PG_LWGEOM *serialized_geom1, PG_LWGEOM *serialized_geom2, int32 key1, int32 key2);
+PrepGeomCache *GetPrepGeomCache(FunctionCallInfoData *fcinfo, uchar *serialized_geom1, uchar *serialized_geom2);
 
 /* Memory context hash table function prototypes */
 uint32 mcxt_ptr_hasha(const void *key, Size keysize);
-static HTAB* CreatePrepGeomHash(void);
+static void CreatePrepGeomHash(void);
 static void AddPrepGeomHashEntry(PrepGeomHashEntry pghe);
 static PrepGeomHashEntry *GetPrepGeomHashEntry(MemoryContext mcxt);
 static void DeletePrepGeomHashEntry(MemoryContext mcxt);
@@ -3714,7 +3718,7 @@
 	return hashval;
 }
 
-static HTAB*
+static void
 CreatePrepGeomHash(void)
 {
 	HASHCTL ctl;
@@ -3723,7 +3727,7 @@
 	ctl.entrysize = sizeof(PrepGeomHashEntry);
 	ctl.hash = mcxt_ptr_hasha;
 
-	return hash_create("PostGIS Prepared Geometry Backend MemoryContext Hash", PREPARED_BACKEND_HASH_SIZE, &ctl, (HASH_ELEM | HASH_FUNCTION));
+	PrepGeomHash = hash_create("PostGIS Prepared Geometry Backend MemoryContext Hash", PREPARED_BACKEND_HASH_SIZE, &ctl, (HASH_ELEM | HASH_FUNCTION));
 }
 
 static void 
@@ -3795,15 +3799,27 @@
 **
 */
 PrepGeomCache* 
-GetPrepGeomCache(FunctionCallInfoData *fcinfo, PG_LWGEOM *serialized_geom1, PG_LWGEOM *serialized_geom2, int32 key1, int32 key2)
+GetPrepGeomCache(FunctionCallInfoData *fcinfo, uchar *serialized_geom1, uchar *serialized_geom2)
 {
 	PrepGeomCache* cache = fcinfo->flinfo->fn_extra;
+	size_t geom1_size = 0;
+	size_t geom2_size = 0;
 
 	if (!PrepGeomHash)
-		PrepGeomHash = CreatePrepGeomHash();
+		CreatePrepGeomHash();
 
+	if(serialized_geom1)
+		geom1_size = lwgeom_size(serialized_geom1);
+		
+	if(serialized_geom2)
+		geom2_size = lwgeom_size(serialized_geom2);
+
 	if ( cache == NULL)
 	{
+		/*
+		** Cache hit, but the cache isn't set up yet.
+		** Set it up, but don't prepare the geometry yet.
+		*/
 		PrepGeomHashEntry pghe;
 		MemoryContext old_context;
 	
@@ -3814,8 +3830,10 @@
 		cache->prepared_geom = 0;
 		cache->geom = 0;
 		cache->argnum = 0;
-		cache->key1 = 0;
-		cache->key2 = 0;
+		cache->serialized1 = 0;
+		cache->serialized2 = 0;
+		cache->serialized1_size = 0;
+		cache->serialized2_size = 0;
 		cache->context = MemoryContextCreate(T_AllocSetContext, 8192,
 		                 &PreparedCacheContextMethods,
 		                 fcinfo->flinfo->fn_mcxt,
@@ -3832,12 +3850,17 @@
 
 		POSTGIS_DEBUGF(3, "GetPrepGeomCache: adding context to hash: %x", cache);
 	}
-	else if ( cache->key1 == key1 )
+	else if ( cache->serialized1_size == geom1_size && 
+	          memcmp(cache->serialized1, serialized_geom1, geom1_size) )
 	{
 		if ( !cache->prepared_geom )
 		{
+			/*
+			** Cache hit, but we haven't prepared our geometry yet.
+			** Prepare it.
+			*/
 			PrepGeomHashEntry* pghe;
-			
+		
 			GEOSGeom g = POSTGIS2GEOS( serialized_geom1 );
 			cache->geom = g;
 			cache->prepared_geom = GEOSPrepare( g );
@@ -3848,38 +3871,50 @@
 			pghe->geom = cache->geom;
 			pghe->prepared_geom = cache->prepared_geom;
 			POSTGIS_DEBUG(3, "GetPrepGeomCache: storing references to prepared obj in argument 1");
-
 		}
 		else
-		{
+		{	
+			/*
+			** Cache hit, and we're good to go. Do nothing.
+			*/
 			POSTGIS_DEBUG(3, "GetPrepGeomCache: prepared obj 1 in cache");
 		}
 	}
-	else if ( key2 && cache->key2 == key2 )
+	else if ( cache->serialized2_size == geom2_size && 
+	          memcmp(cache->serialized2, serialized_geom2, geom2_size) )
 	{
-		if ( !cache->prepared_geom )
-		{
-			PrepGeomHashEntry* pghe;
-
-			GEOSGeom g = POSTGIS2GEOS( serialized_geom2 );
-			cache->geom = g;
-			cache->prepared_geom = GEOSPrepare( g );
-			cache->argnum = 2;
-			POSTGIS_DEBUG(3, "GetPrepGeomCache: preparing obj in argument 2");
+		 	if ( !cache->prepared_geom )
+			{
+				/*
+				** Cache hit on arg2, but we haven't prepared our geometry yet.
+				** Prepare it.
+				*/
+				PrepGeomHashEntry* pghe;
+				GEOSGeom g = POSTGIS2GEOS( serialized_geom2 );
+				cache->geom = g;
+				cache->prepared_geom = GEOSPrepare( g );
+				cache->argnum = 2;
+				POSTGIS_DEBUG(3, "GetPrepGeomCache: preparing obj in argument 2");
 			
-			pghe = GetPrepGeomHashEntry(cache->context);
-			pghe->geom = cache->geom;
-			pghe->prepared_geom = cache->prepared_geom;
-			POSTGIS_DEBUG(3, "GetPrepGeomCache: storing references to prepared obj in argument 2");
-
-		}
-		else
-		{
-			POSTGIS_DEBUG(3, "GetPrepGeomCache: prepared obj 2 in cache");
-		}
+				pghe = GetPrepGeomHashEntry(cache->context);
+				pghe->geom = cache->geom;
+				pghe->prepared_geom = cache->prepared_geom;
+				POSTGIS_DEBUG(3, "GetPrepGeomCache: storing references to prepared obj in argument 2");
+			}
+			else 
+			{
+				/*
+				** Cache hit, and we're good to go. Do nothing.
+				*/
+				POSTGIS_DEBUG(3, "GetPrepGeomCache: prepared obj for arg 2 in cache");
+			}
 	}
 	else if ( cache->prepared_geom )
 	{
+		/*
+		** No cache hits, so this must be a miss.
+		** Destroy the GEOS objects, empty the cache.
+		*/
 		PrepGeomHashEntry* pghe;
 
 		pghe = GetPrepGeomHashEntry(cache->context);
@@ -3895,10 +3930,18 @@
 		cache->argnum = 0;
 
 	}
+	
+	if( serialized_geom1 ) 
+	{
+		cache->serialized1 = serialized_geom1;
+		cache->serialized1_size = geom1_size;
+	}
+	if( serialized_geom2 )
+	{ 
+		cache->serialized2 = serialized_geom2;
+		cache->serialized2_size = geom2_size;
+	}
 
-	cache->key1 = key1;
-	cache->key2 = key2;
-
 	return cache;
 }
 #endif /* PREPARED_GEOM */
@@ -3942,7 +3985,7 @@
 
 	POSTGIS_DEBUGF(4, "containsPrepared: calling for prep_cache with key1 = %d", key1);
 
-	prep_cache = GetPrepGeomCache( fcinfo, geom1, 0, key1, 0 );
+	prep_cache = GetPrepGeomCache( fcinfo, SERIALIZED_FORM(geom1), 0 );
 
 	initGEOS(lwnotice, lwnotice);
 
@@ -4010,7 +4053,7 @@
 			PG_RETURN_BOOL(FALSE);
 	}
 
-	prep_cache = GetPrepGeomCache( fcinfo, geom1, 0, key1, 0 );
+	prep_cache = GetPrepGeomCache( fcinfo, SERIALIZED_FORM(geom1), 0 );
 
 	initGEOS(lwnotice, lwnotice);
 
@@ -4076,7 +4119,7 @@
 			PG_RETURN_BOOL(FALSE);
 	}
 
-	prep_cache = GetPrepGeomCache( fcinfo, geom1, 0, key1, 0 );
+	prep_cache = GetPrepGeomCache( fcinfo, SERIALIZED_FORM(geom1), 0 );
 
 	initGEOS(lwnotice, lwnotice);
 
@@ -4144,7 +4187,7 @@
 			PG_RETURN_BOOL(FALSE);
 	}
 
-	prep_cache = GetPrepGeomCache( fcinfo, geom1, geom2, key1, key2 );
+	prep_cache = GetPrepGeomCache( fcinfo, SERIALIZED_FORM(geom1), SERIALIZED_FORM(geom2) );
 
 	initGEOS(lwnotice, lwnotice);
 



More information about the postgis-commits mailing list