Avoid statically allocating statement cache in ecpglib/prepare.c.
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 17 Oct 2018 04:04:48 +0000 (00:04 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 17 Oct 2018 04:04:48 +0000 (00:04 -0400)
This removes a megabyte of storage that isn't used at all in ecpglib's
default operating mode --- you have to enable auto-prepare to get any
use out of it.  Seems well worth the trouble to allocate on demand.

Discussion: https://postgr.es/m/20181015200754.7y7zfuzsoux2c4ya@alap3.anarazel.de

src/interfaces/ecpg/ecpglib/prepare.c

index bc0ac4afadbda3444a5febb3e94fce765cbe5e1c..f904d326e48c293f4bd4968a619c459e1e82c888 100644 (file)
@@ -13,6 +13,8 @@
 
 #define STMTID_SIZE 32
 
+#define N_STMTCACHE_ENTRIES 16384
+
 typedef struct
 {
    int         lineno;
@@ -25,7 +27,7 @@ typedef struct
 static int nextStmtID = 1;
 static const int stmtCacheNBuckets = 2039; /* # buckets - a prime # */
 static const int stmtCacheEntPerBucket = 8; /* # entries/bucket */
-static stmtCacheEntry stmtCacheEntries[16384] = {{0, {0}, 0, 0, 0}};
+static stmtCacheEntry *stmtCacheEntries = NULL;
 
 static bool deallocate_one(int lineno, enum COMPAT_MODE c, struct connection *con,
               struct prepared_statement *prev, struct prepared_statement *this);
@@ -362,6 +364,10 @@ SearchStmtCache(const char *ecpgQuery)
    int         entNo,
                entIx;
 
+   /* quick failure if cache not set up */
+   if (stmtCacheEntries == NULL)
+       return 0;
+
    /* hash the statement */
    entNo = HashStmt(ecpgQuery);
 
@@ -397,6 +403,10 @@ ecpg_freeStmtCacheEntry(int lineno, int compat,
    struct prepared_statement *this,
               *prev;
 
+   /* fail if cache isn't set up */
+   if (stmtCacheEntries == NULL)
+       return -1;
+
    entry = &stmtCacheEntries[entNo];
    if (!entry->stmtID[0])      /* return if the entry isn't in use */
        return 0;
@@ -437,6 +447,15 @@ AddStmtToCache(int lineno,     /* line # of statement */
                entNo;
    stmtCacheEntry *entry;
 
+   /* allocate and zero cache array if we haven't already */
+   if (stmtCacheEntries == NULL)
+   {
+       stmtCacheEntries = (stmtCacheEntry *)
+           ecpg_alloc(sizeof(stmtCacheEntry) * N_STMTCACHE_ENTRIES, lineno);
+       if (stmtCacheEntries == NULL)
+           return -1;
+   }
+
    /* hash the statement */
    initEntNo = HashStmt(ecpgQuery);