Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 2c300c6

Browse files
committed
Be smarter about age-counter overflow in formatting.c caches.
The previous code here simply threw away whatever it knew about cache entry ages whenever a counter overflow occurred. Since the counter is int width and will be bumped once per format function execution, overflows are not really so rare as to not be worth thinking about. Instead, let's deal with the situation by halving all the age values, essentially rescaling the age metric. In that way, we retain a pretty accurate (if not quite perfect) idea of which entries are oldest.
1 parent f7a953c commit 2c300c6

File tree

1 file changed

+38
-32
lines changed

1 file changed

+38
-32
lines changed

src/backend/utils/adt/formatting.c

Lines changed: 38 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3376,20 +3376,32 @@ DCH_from_char(FormatNode *node, char *in, TmFromChar *out)
33763376
}
33773377
}
33783378

3379+
/*
3380+
* The invariant for DCH cache entry management is that DCHCounter is equal
3381+
* to the maximum age value among the existing entries, and we increment it
3382+
* whenever an access occurs. If we approach overflow, deal with that by
3383+
* halving all the age values, so that we retain a fairly accurate idea of
3384+
* which entries are oldest.
3385+
*/
3386+
static inline void
3387+
DCH_prevent_counter_overflow(void)
3388+
{
3389+
if (DCHCounter >= (INT_MAX - 1))
3390+
{
3391+
for (int i = 0; i < n_DCHCache; i++)
3392+
DCHCache[i]->age >>= 1;
3393+
DCHCounter >>= 1;
3394+
}
3395+
}
3396+
33793397
/* select a DCHCacheEntry to hold the given format picture */
33803398
static DCHCacheEntry *
33813399
DCH_cache_getnew(const char *str)
33823400
{
33833401
DCHCacheEntry *ent;
33843402

3385-
/* handle counter overflow by resetting all ages */
3386-
if (DCHCounter >= (INT_MAX - DCH_CACHE_ENTRIES))
3387-
{
3388-
DCHCounter = 0;
3389-
3390-
for (int i = 0; i < n_DCHCache; i++)
3391-
DCHCache[i]->age = (++DCHCounter);
3392-
}
3403+
/* Ensure we can advance DCHCounter below */
3404+
DCH_prevent_counter_overflow();
33933405

33943406
/*
33953407
* If cache is full, remove oldest entry (or recycle first not-valid one)
@@ -3445,14 +3457,8 @@ DCH_cache_getnew(const char *str)
34453457
static DCHCacheEntry *
34463458
DCH_cache_search(const char *str)
34473459
{
3448-
/* handle counter overflow by resetting all ages */
3449-
if (DCHCounter >= (INT_MAX - DCH_CACHE_ENTRIES))
3450-
{
3451-
DCHCounter = 0;
3452-
3453-
for (int i = 0; i < n_DCHCache; i++)
3454-
DCHCache[i]->age = (++DCHCounter);
3455-
}
3460+
/* Ensure we can advance DCHCounter below */
3461+
DCH_prevent_counter_overflow();
34563462

34573463
for (int i = 0; i < n_DCHCache; i++)
34583464
{
@@ -4057,20 +4063,26 @@ do { \
40574063
(_n)->zero_end = 0; \
40584064
} while(0)
40594065

4066+
/* This works the same as DCH_prevent_counter_overflow */
4067+
static inline void
4068+
NUM_prevent_counter_overflow(void)
4069+
{
4070+
if (NUMCounter >= (INT_MAX - 1))
4071+
{
4072+
for (int i = 0; i < n_NUMCache; i++)
4073+
NUMCache[i]->age >>= 1;
4074+
NUMCounter >>= 1;
4075+
}
4076+
}
4077+
40604078
/* select a NUMCacheEntry to hold the given format picture */
40614079
static NUMCacheEntry *
40624080
NUM_cache_getnew(const char *str)
40634081
{
40644082
NUMCacheEntry *ent;
40654083

4066-
/* handle counter overflow by resetting all ages */
4067-
if (NUMCounter >= (INT_MAX - NUM_CACHE_ENTRIES))
4068-
{
4069-
NUMCounter = 0;
4070-
4071-
for (int i = 0; i < n_NUMCache; i++)
4072-
NUMCache[i]->age = (++NUMCounter);
4073-
}
4084+
/* Ensure we can advance NUMCounter below */
4085+
NUM_prevent_counter_overflow();
40744086

40754087
/*
40764088
* If cache is full, remove oldest entry (or recycle first not-valid one)
@@ -4126,14 +4138,8 @@ NUM_cache_getnew(const char *str)
41264138
static NUMCacheEntry *
41274139
NUM_cache_search(const char *str)
41284140
{
4129-
/* handle counter overflow by resetting all ages */
4130-
if (NUMCounter >= (INT_MAX - NUM_CACHE_ENTRIES))
4131-
{
4132-
NUMCounter = 0;
4133-
4134-
for (int i = 0; i < n_NUMCache; i++)
4135-
NUMCache[i]->age = (++NUMCounter);
4136-
}
4141+
/* Ensure we can advance NUMCounter below */
4142+
NUM_prevent_counter_overflow();
41374143

41384144
for (int i = 0; i < n_NUMCache; i++)
41394145
{

0 commit comments

Comments
 (0)