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

Commit 3788c66

Browse files
committed
Improve various places that double the size of a buffer
Several places were performing a tight loop to determine the first power of 2 number that's > or >= the required memory. Instead of using a loop for that, we can use pg_nextpower2_32 or pg_nextpower2_64. When we need a power of 2 number equal to or greater than a given amount, we just pass the amount to the nextpower2 function. When we need a power of 2 greater than the amount, we just pass the amount + 1. Additionally, in tsearch there were a couple of locations that were performing a while loop when a simple "if" would have done. In both of these locations only 1 item is being added, so the loop could only have ever iterated once. Changing the loop into an if statement makes the code very slightly more optimal as the condition is checked once rather than twice. There are quite a few remaining locations that increase the size of the buffer in the following form: while (reqsize >= buflen) { buflen *= 2; buf = repalloc(buf, buflen); } These are not touched in this commit. repalloc will error out for sizes larger than MaxAllocSize. Changing these to use pg_nextpower2_32 would remove the chance of that error being raised. It's unclear from the code if the sizes could ever become that large, so err on the side of caution. Discussion: https://postgr.es/m/CAApHDvp=tns7RL4PH0ZR0M+M-YFLquK7218x=0B_zO+DbOma+w@mail.gmail.com Reviewed-by: Zhihong Yu
1 parent e45b0df commit 3788c66

File tree

7 files changed

+21
-24
lines changed

7 files changed

+21
-24
lines changed

src/backend/parser/scan.l

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include "parser/gramparse.h"
4040
#include "parser/parser.h" /* only needed for GUC variables */
4141
#include "parser/scansup.h"
42+
#include "port/pg_bitutils.h"
4243
#include "mb/pg_wchar.h"
4344
}
4445

@@ -1253,10 +1254,7 @@ addlit(char *ytext, int yleng, core_yyscan_t yyscanner)
12531254
/* enlarge buffer if needed */
12541255
if ((yyextra->literallen + yleng) >= yyextra->literalalloc)
12551256
{
1256-
do
1257-
{
1258-
yyextra->literalalloc *= 2;
1259-
} while ((yyextra->literallen + yleng) >= yyextra->literalalloc);
1257+
yyextra->literalalloc = pg_nextpower2_32(yyextra->literallen + yleng + 1);
12601258
yyextra->literalbuf = (char *) repalloc(yyextra->literalbuf,
12611259
yyextra->literalalloc);
12621260
}

src/backend/storage/ipc/shm_mq.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
#include "miscadmin.h"
2222
#include "pgstat.h"
23+
#include "port/pg_bitutils.h"
2324
#include "postmaster/bgworker.h"
2425
#include "storage/procsignal.h"
2526
#include "storage/shm_mq.h"
@@ -720,14 +721,17 @@ shm_mq_receive(shm_mq_handle *mqh, Size *nbytesp, void **datap, bool nowait)
720721
*/
721722
if (mqh->mqh_buflen < nbytes)
722723
{
723-
Size newbuflen = Max(mqh->mqh_buflen, MQH_INITIAL_BUFSIZE);
724+
Size newbuflen;
724725

725726
/*
726-
* Double the buffer size until the payload fits, but limit to
727-
* MaxAllocSize.
727+
* Increase size to the next power of 2 that's >= nbytes, but
728+
* limit to MaxAllocSize.
728729
*/
729-
while (newbuflen < nbytes)
730-
newbuflen *= 2;
730+
#if SIZEOF_SIZE_T == 4
731+
newbuflen = pg_nextpower2_32(nbytes);
732+
#else
733+
newbuflen = pg_nextpower2_64(nbytes);
734+
#endif
731735
newbuflen = Min(newbuflen, MaxAllocSize);
732736

733737
if (mqh->mqh_buffer != NULL)

src/backend/storage/lmgr/lwlock.c

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979
#include "miscadmin.h"
8080
#include "pg_trace.h"
8181
#include "pgstat.h"
82+
#include "port/pg_bitutils.h"
8283
#include "postmaster/postmaster.h"
8384
#include "replication/slot.h"
8485
#include "storage/ipc.h"
@@ -659,9 +660,7 @@ LWLockRegisterTranche(int tranche_id, const char *tranche_name)
659660
{
660661
int newalloc;
661662

662-
newalloc = Max(LWLockTrancheNamesAllocated, 8);
663-
while (newalloc <= tranche_id)
664-
newalloc *= 2;
663+
newalloc = pg_nextpower2_32(Max(8, tranche_id + 1));
665664

666665
if (LWLockTrancheNames == NULL)
667666
LWLockTrancheNames = (const char **)
@@ -715,10 +714,7 @@ RequestNamedLWLockTranche(const char *tranche_name, int num_lwlocks)
715714

716715
if (NamedLWLockTrancheRequests >= NamedLWLockTrancheRequestsAllocated)
717716
{
718-
int i = NamedLWLockTrancheRequestsAllocated;
719-
720-
while (i <= NamedLWLockTrancheRequests)
721-
i *= 2;
717+
int i = pg_nextpower2_32(NamedLWLockTrancheRequests + 1);
722718

723719
NamedLWLockTrancheRequestArray = (NamedLWLockTrancheRequest *)
724720
repalloc(NamedLWLockTrancheRequestArray,

src/backend/tsearch/spell.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1600,7 +1600,8 @@ MergeAffix(IspellDict *Conf, int a1, int a2)
16001600
else if (*Conf->AffixData[a2] == '\0')
16011601
return a1;
16021602

1603-
while (Conf->nAffixData + 1 >= Conf->lenAffixData)
1603+
/* Double the size of AffixData if there's not enough space */
1604+
if (Conf->nAffixData + 1 >= Conf->lenAffixData)
16041605
{
16051606
Conf->lenAffixData *= 2;
16061607
Conf->AffixData = (char **) repalloc(Conf->AffixData,

src/backend/tsearch/ts_parse.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,7 @@ parsetext(Oid cfgId, ParsedText *prs, char *buf, int buflen)
436436
static void
437437
hladdword(HeadlineParsedText *prs, char *buf, int buflen, int type)
438438
{
439-
while (prs->curwords >= prs->lenwords)
439+
if (prs->curwords >= prs->lenwords)
440440
{
441441
prs->lenwords *= 2;
442442
prs->words = (HeadlineWordEntry *) repalloc((void *) prs->words, prs->lenwords * sizeof(HeadlineWordEntry));

src/backend/utils/cache/inval.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@
106106
#include "catalog/catalog.h"
107107
#include "catalog/pg_constraint.h"
108108
#include "miscadmin.h"
109+
#include "port/pg_bitutils.h"
109110
#include "storage/sinval.h"
110111
#include "storage/smgr.h"
111112
#include "utils/catcache.h"
@@ -799,8 +800,7 @@ MakeSharedInvalidMessagesArray(const SharedInvalidationMessage *msgs, int n)
799800

800801
if ((numSharedInvalidMessagesArray + n) > maxSharedInvalidMessagesArray)
801802
{
802-
while ((numSharedInvalidMessagesArray + n) > maxSharedInvalidMessagesArray)
803-
maxSharedInvalidMessagesArray *= 2;
803+
maxSharedInvalidMessagesArray = pg_nextpower2_32(numSharedInvalidMessagesArray + n);
804804

805805
SharedInvalidMessagesArray = repalloc(SharedInvalidMessagesArray,
806806
maxSharedInvalidMessagesArray

src/backend/utils/cache/typcache.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
#include "executor/executor.h"
6161
#include "lib/dshash.h"
6262
#include "optimizer/optimizer.h"
63+
#include "port/pg_bitutils.h"
6364
#include "storage/lwlock.h"
6465
#include "utils/builtins.h"
6566
#include "utils/catcache.h"
@@ -1708,10 +1709,7 @@ ensure_record_cache_typmod_slot_exists(int32 typmod)
17081709

17091710
if (typmod >= RecordCacheArrayLen)
17101711
{
1711-
int32 newlen = RecordCacheArrayLen * 2;
1712-
1713-
while (typmod >= newlen)
1714-
newlen *= 2;
1712+
int32 newlen = pg_nextpower2_32(typmod + 1);
17151713

17161714
RecordCacheArray = (TupleDesc *) repalloc(RecordCacheArray,
17171715
newlen * sizeof(TupleDesc));

0 commit comments

Comments
 (0)