Re: Large writable variables - Mailing list pgsql-hackers

From Tom Lane
Subject Re: Large writable variables
Date
Msg-id 31562.1539658872@sss.pgh.pa.us
Whole thread Raw
In response to Large writable variables  (Andres Freund <andres@anarazel.de>)
Responses Re: Large writable variables  (Tom Lane <tgl@sss.pgh.pa.us>)
List pgsql-hackers
Andres Freund <andres@anarazel.de> writes:
> top unitialized allocations:
> 0000000008435040 0000000000085280 b DCHCache
> 0000000008391168 0000000000043840 b NUMCache

Here's a patch to improve that situation.

            regards, tom lane

diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c
index b3ff133..43a0307 100644
--- a/src/backend/utils/adt/formatting.c
+++ b/src/backend/utils/adt/formatting.c
@@ -93,6 +93,7 @@
 #include "utils/float.h"
 #include "utils/formatting.h"
 #include "utils/int8.h"
+#include "utils/memutils.h"
 #include "utils/numeric.h"
 #include "utils/pg_locale.h"

@@ -385,12 +386,12 @@ typedef struct
 } NUMCacheEntry;

 /* global cache for date/time format pictures */
-static DCHCacheEntry DCHCache[DCH_CACHE_ENTRIES];
+static DCHCacheEntry *DCHCache[DCH_CACHE_ENTRIES];
 static int    n_DCHCache = 0;        /* current number of entries */
 static int    DCHCounter = 0;        /* aging-event counter */

 /* global cache for number format pictures */
-static NUMCacheEntry NUMCache[NUM_CACHE_ENTRIES];
+static NUMCacheEntry *NUMCache[NUM_CACHE_ENTRIES];
 static int    n_NUMCache = 0;        /* current number of entries */
 static int    NUMCounter = 0;        /* aging-event counter */

@@ -3368,13 +3369,13 @@ DCH_cache_getnew(const char *str)
 {
     DCHCacheEntry *ent;

-    /* counter overflow check - paranoia? */
+    /* handle counter overflow by resetting all ages */
     if (DCHCounter >= (INT_MAX - DCH_CACHE_ENTRIES))
     {
         DCHCounter = 0;

-        for (ent = DCHCache; ent < (DCHCache + DCH_CACHE_ENTRIES); ent++)
-            ent->age = (++DCHCounter);
+        for (int i = 0; i < n_DCHCache; i++)
+            DCHCache[i]->age = (++DCHCounter);
     }

     /*
@@ -3382,15 +3383,16 @@ DCH_cache_getnew(const char *str)
      */
     if (n_DCHCache >= DCH_CACHE_ENTRIES)
     {
-        DCHCacheEntry *old = DCHCache + 0;
+        DCHCacheEntry *old = DCHCache[0];

 #ifdef DEBUG_TO_FROM_CHAR
         elog(DEBUG_elog_output, "cache is full (%d)", n_DCHCache);
 #endif
         if (old->valid)
         {
-            for (ent = DCHCache + 1; ent < (DCHCache + DCH_CACHE_ENTRIES); ent++)
+            for (int i = 1; i < DCH_CACHE_ENTRIES; i++)
             {
+                ent = DCHCache[i];
                 if (!ent->valid)
                 {
                     old = ent;
@@ -3414,7 +3416,9 @@ DCH_cache_getnew(const char *str)
 #ifdef DEBUG_TO_FROM_CHAR
         elog(DEBUG_elog_output, "NEW (%d)", n_DCHCache);
 #endif
-        ent = DCHCache + n_DCHCache;
+        Assert(DCHCache[n_DCHCache] == NULL);
+        DCHCache[n_DCHCache] = ent = (DCHCacheEntry *)
+            MemoryContextAllocZero(TopMemoryContext, sizeof(DCHCacheEntry));
         ent->valid = false;
         StrNCpy(ent->str, str, DCH_CACHE_SIZE + 1);
         ent->age = (++DCHCounter);
@@ -3428,20 +3432,19 @@ DCH_cache_getnew(const char *str)
 static DCHCacheEntry *
 DCH_cache_search(const char *str)
 {
-    int            i;
-    DCHCacheEntry *ent;
-
-    /* counter overflow check - paranoia? */
+    /* handle counter overflow by resetting all ages */
     if (DCHCounter >= (INT_MAX - DCH_CACHE_ENTRIES))
     {
         DCHCounter = 0;

-        for (ent = DCHCache; ent < (DCHCache + DCH_CACHE_ENTRIES); ent++)
-            ent->age = (++DCHCounter);
+        for (int i = 0; i < n_DCHCache; i++)
+            DCHCache[i]->age = (++DCHCounter);
     }

-    for (i = 0, ent = DCHCache; i < n_DCHCache; i++, ent++)
+    for (int i = 0; i < n_DCHCache; i++)
     {
+        DCHCacheEntry *ent = DCHCache[i];
+
         if (ent->valid && strcmp(ent->str, str) == 0)
         {
             ent->age = (++DCHCounter);
@@ -4047,13 +4050,13 @@ NUM_cache_getnew(const char *str)
 {
     NUMCacheEntry *ent;

-    /* counter overflow check - paranoia? */
+    /* handle counter overflow by resetting all ages */
     if (NUMCounter >= (INT_MAX - NUM_CACHE_ENTRIES))
     {
         NUMCounter = 0;

-        for (ent = NUMCache; ent < (NUMCache + NUM_CACHE_ENTRIES); ent++)
-            ent->age = (++NUMCounter);
+        for (int i = 0; i < n_NUMCache; i++)
+            NUMCache[i]->age = (++NUMCounter);
     }

     /*
@@ -4061,15 +4064,16 @@ NUM_cache_getnew(const char *str)
      */
     if (n_NUMCache >= NUM_CACHE_ENTRIES)
     {
-        NUMCacheEntry *old = NUMCache + 0;
+        NUMCacheEntry *old = NUMCache[0];

 #ifdef DEBUG_TO_FROM_CHAR
         elog(DEBUG_elog_output, "Cache is full (%d)", n_NUMCache);
 #endif
         if (old->valid)
         {
-            for (ent = NUMCache + 1; ent < (NUMCache + NUM_CACHE_ENTRIES); ent++)
+            for (int i = 1; i < NUM_CACHE_ENTRIES; i++)
             {
+                ent = NUMCache[i];
                 if (!ent->valid)
                 {
                     old = ent;
@@ -4093,7 +4097,9 @@ NUM_cache_getnew(const char *str)
 #ifdef DEBUG_TO_FROM_CHAR
         elog(DEBUG_elog_output, "NEW (%d)", n_NUMCache);
 #endif
-        ent = NUMCache + n_NUMCache;
+        Assert(NUMCache[n_NUMCache] == NULL);
+        NUMCache[n_NUMCache] = ent = (NUMCacheEntry *)
+            MemoryContextAllocZero(TopMemoryContext, sizeof(NUMCacheEntry));
         ent->valid = false;
         StrNCpy(ent->str, str, NUM_CACHE_SIZE + 1);
         ent->age = (++NUMCounter);
@@ -4107,20 +4113,19 @@ NUM_cache_getnew(const char *str)
 static NUMCacheEntry *
 NUM_cache_search(const char *str)
 {
-    int            i;
-    NUMCacheEntry *ent;
-
-    /* counter overflow check - paranoia? */
+    /* handle counter overflow by resetting all ages */
     if (NUMCounter >= (INT_MAX - NUM_CACHE_ENTRIES))
     {
         NUMCounter = 0;

-        for (ent = NUMCache; ent < (NUMCache + NUM_CACHE_ENTRIES); ent++)
-            ent->age = (++NUMCounter);
+        for (int i = 0; i < n_NUMCache; i++)
+            NUMCache[i]->age = (++NUMCounter);
     }

-    for (i = 0, ent = NUMCache; i < n_NUMCache; i++, ent++)
+    for (int i = 0; i < n_NUMCache; i++)
     {
+        NUMCacheEntry *ent = NUMCache[i];
+
         if (ent->valid && strcmp(ent->str, str) == 0)
         {
             ent->age = (++NUMCounter);

pgsql-hackers by date:

Previous
From: Haribabu Kommi
Date:
Subject: Re: Pluggable Storage - Andres's take
Next
From: Amit Kapila
Date:
Subject: Re: WIP: Avoid creation of the free space map for small tables