Skip to content

Commit 13b935c

Browse files
committed
Change dynahash.c and hsearch.h to use int64 instead of long
This code was relying on "long", which is signed 8 bytes everywhere except on Windows where it is 4 bytes, that could potentially expose it to overflows, even if the current uses in the code are fine as far as I know. This code is now able to rely on the same sizeof() variable everywhere, with int64. long was used for sizes, partition counts and entry counts. Some callers of the dynahash.c routines used long declarations, that can be cleaned up to use int64 instead. There was one shortcut based on SIZEOF_LONG, that can be removed. long is entirely removed from dynahash.c and hsearch.h. Similar work was done in b1e5c9f. Reviewed-by: Peter Eisentraut <peter@eisentraut.org> Reviewed-by: Chao Li <li.evan.chao@gmail.com> Discussion: https://postgr.es/m/aKQYp-bKTRtRauZ6@paquier.xyz
1 parent ef03ea0 commit 13b935c

File tree

9 files changed

+61
-65
lines changed

9 files changed

+61
-65
lines changed

contrib/pg_stat_statements/pg_stat_statements.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2713,8 +2713,8 @@ entry_reset(Oid userid, Oid dbid, int64 queryid, bool minmax_only)
27132713
HASH_SEQ_STATUS hash_seq;
27142714
pgssEntry *entry;
27152715
FILE *qfile;
2716-
long num_entries;
2717-
long num_remove = 0;
2716+
int64 num_entries;
2717+
int64 num_remove = 0;
27182718
pgssHashKey key;
27192719
TimestampTz stats_reset;
27202720

src/backend/catalog/storage.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -586,7 +586,7 @@ RelFileLocatorSkippingWAL(RelFileLocator rlocator)
586586
Size
587587
EstimatePendingSyncsSpace(void)
588588
{
589-
long entries;
589+
int64 entries;
590590

591591
entries = pendingSyncHash ? hash_get_num_entries(pendingSyncHash) : 0;
592592
return mul_size(1 + entries, sizeof(RelFileLocator));

src/backend/storage/ipc/shmem.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -330,8 +330,8 @@ InitShmemIndex(void)
330330
*/
331331
HTAB *
332332
ShmemInitHash(const char *name, /* table string name for shmem index */
333-
long init_size, /* initial table size */
334-
long max_size, /* max size of the table */
333+
int64 init_size, /* initial table size */
334+
int64 max_size, /* max size of the table */
335335
HASHCTL *infoP, /* info about key and bucket size */
336336
int hash_flags) /* info about infoP */
337337
{

src/backend/storage/lmgr/lock.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,7 @@ void
443443
LockManagerShmemInit(void)
444444
{
445445
HASHCTL info;
446-
long init_table_size,
446+
int64 init_table_size,
447447
max_table_size;
448448
bool found;
449449

src/backend/storage/lmgr/predicate.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1145,7 +1145,7 @@ void
11451145
PredicateLockShmemInit(void)
11461146
{
11471147
HASHCTL info;
1148-
long max_table_size;
1148+
int64 max_table_size;
11491149
Size requestSize;
11501150
bool found;
11511151

src/backend/utils/hash/dynahash.c

Lines changed: 44 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ typedef HASHBUCKET *HASHSEGMENT;
154154
typedef struct
155155
{
156156
slock_t mutex; /* spinlock for this freelist */
157-
long nentries; /* number of entries in associated buckets */
157+
int64 nentries; /* number of entries in associated buckets */
158158
HASHELEMENT *freeList; /* chain of free elements */
159159
} FreeListData;
160160

@@ -182,18 +182,18 @@ struct HASHHDR
182182

183183
/* These fields can change, but not in a partitioned table */
184184
/* Also, dsize can't change in a shared table, even if unpartitioned */
185-
long dsize; /* directory size */
186-
long nsegs; /* number of allocated segments (<= dsize) */
185+
int64 dsize; /* directory size */
186+
int64 nsegs; /* number of allocated segments (<= dsize) */
187187
uint32 max_bucket; /* ID of maximum bucket in use */
188188
uint32 high_mask; /* mask to modulo into entire table */
189189
uint32 low_mask; /* mask to modulo into lower half of table */
190190

191191
/* These fields are fixed at hashtable creation */
192192
Size keysize; /* hash key length in bytes */
193193
Size entrysize; /* total user element size in bytes */
194-
long num_partitions; /* # partitions (must be power of 2), or 0 */
195-
long max_dsize; /* 'dsize' limit if directory is fixed size */
196-
long ssize; /* segment size --- must be power of 2 */
194+
int64 num_partitions; /* # partitions (must be power of 2), or 0 */
195+
int64 max_dsize; /* 'dsize' limit if directory is fixed size */
196+
int64 ssize; /* segment size --- must be power of 2 */
197197
int sshift; /* segment shift = log2(ssize) */
198198
int nelem_alloc; /* number of entries to allocate at once */
199199
bool isfixed; /* if true, don't enlarge */
@@ -236,7 +236,7 @@ struct HTAB
236236

237237
/* We keep local copies of these fixed values to reduce contention */
238238
Size keysize; /* hash key length in bytes */
239-
long ssize; /* segment size --- must be power of 2 */
239+
int64 ssize; /* segment size --- must be power of 2 */
240240
int sshift; /* segment shift = log2(ssize) */
241241

242242
/*
@@ -277,12 +277,12 @@ static bool expand_table(HTAB *hashp);
277277
static HASHBUCKET get_hash_entry(HTAB *hashp, int freelist_idx);
278278
static void hdefault(HTAB *hashp);
279279
static int choose_nelem_alloc(Size entrysize);
280-
static bool init_htab(HTAB *hashp, long nelem);
280+
static bool init_htab(HTAB *hashp, int64 nelem);
281281
pg_noreturn static void hash_corrupted(HTAB *hashp);
282282
static uint32 hash_initial_lookup(HTAB *hashp, uint32 hashvalue,
283283
HASHBUCKET **bucketptr);
284-
static long next_pow2_long(long num);
285-
static int next_pow2_int(long num);
284+
static int64 next_pow2_int64(int64 num);
285+
static int next_pow2_int(int64 num);
286286
static void register_seq_scan(HTAB *hashp);
287287
static void deregister_seq_scan(HTAB *hashp);
288288
static bool has_seq_scans(HTAB *hashp);
@@ -355,7 +355,7 @@ string_compare(const char *key1, const char *key2, Size keysize)
355355
* large nelem will penalize hash_seq_search speed without buying much.
356356
*/
357357
HTAB *
358-
hash_create(const char *tabname, long nelem, const HASHCTL *info, int flags)
358+
hash_create(const char *tabname, int64 nelem, const HASHCTL *info, int flags)
359359
{
360360
HTAB *hashp;
361361
HASHHDR *hctl;
@@ -697,7 +697,7 @@ choose_nelem_alloc(Size entrysize)
697697
* arrays
698698
*/
699699
static bool
700-
init_htab(HTAB *hashp, long nelem)
700+
init_htab(HTAB *hashp, int64 nelem)
701701
{
702702
HASHHDR *hctl = hashp->hctl;
703703
HASHSEGMENT *segp;
@@ -780,20 +780,20 @@ init_htab(HTAB *hashp, long nelem)
780780
* NB: assumes that all hash structure parameters have default values!
781781
*/
782782
Size
783-
hash_estimate_size(long num_entries, Size entrysize)
783+
hash_estimate_size(int64 num_entries, Size entrysize)
784784
{
785785
Size size;
786-
long nBuckets,
786+
int64 nBuckets,
787787
nSegments,
788788
nDirEntries,
789789
nElementAllocs,
790790
elementSize,
791791
elementAllocCnt;
792792

793793
/* estimate number of buckets wanted */
794-
nBuckets = next_pow2_long(num_entries);
794+
nBuckets = next_pow2_int64(num_entries);
795795
/* # of segments needed for nBuckets */
796-
nSegments = next_pow2_long((nBuckets - 1) / DEF_SEGSIZE + 1);
796+
nSegments = next_pow2_int64((nBuckets - 1) / DEF_SEGSIZE + 1);
797797
/* directory entries */
798798
nDirEntries = DEF_DIRSIZE;
799799
while (nDirEntries < nSegments)
@@ -826,17 +826,17 @@ hash_estimate_size(long num_entries, Size entrysize)
826826
*
827827
* XXX this had better agree with the behavior of init_htab()...
828828
*/
829-
long
830-
hash_select_dirsize(long num_entries)
829+
int64
830+
hash_select_dirsize(int64 num_entries)
831831
{
832-
long nBuckets,
832+
int64 nBuckets,
833833
nSegments,
834834
nDirEntries;
835835

836836
/* estimate number of buckets wanted */
837-
nBuckets = next_pow2_long(num_entries);
837+
nBuckets = next_pow2_int64(num_entries);
838838
/* # of segments needed for nBuckets */
839-
nSegments = next_pow2_long((nBuckets - 1) / DEF_SEGSIZE + 1);
839+
nSegments = next_pow2_int64((nBuckets - 1) / DEF_SEGSIZE + 1);
840840
/* directory entries */
841841
nDirEntries = DEF_DIRSIZE;
842842
while (nDirEntries < nSegments)
@@ -887,7 +887,7 @@ hash_stats(const char *caller, HTAB *hashp)
887887
HASHHDR *hctl = hashp->hctl;
888888

889889
elog(DEBUG4,
890-
"hash_stats: Caller: %s Table Name: \"%s\" Accesses: " UINT64_FORMAT " Collisions: " UINT64_FORMAT " Expansions: " UINT64_FORMAT " Entries: %ld Key Size: %zu Max Bucket: %u Segment Count: %ld",
890+
"hash_stats: Caller: %s Table Name: \"%s\" Accesses: " UINT64_FORMAT " Collisions: " UINT64_FORMAT " Expansions: " UINT64_FORMAT " Entries: " INT64_FORMAT " Key Size: %zu Max Bucket: %u Segment Count: " INT64_FORMAT,
891891
caller != NULL ? caller : "(unknown)", hashp->tabname, hctl->accesses,
892892
hctl->collisions, hctl->expansions, hash_get_num_entries(hashp),
893893
hctl->keysize, hctl->max_bucket, hctl->nsegs);
@@ -993,7 +993,7 @@ hash_search_with_hash_value(HTAB *hashp,
993993
* Can't split if running in partitioned mode, nor if frozen, nor if
994994
* table is the subject of any active hash_seq_search scans.
995995
*/
996-
if (hctl->freeList[0].nentries > (long) hctl->max_bucket &&
996+
if (hctl->freeList[0].nentries > (int64) hctl->max_bucket &&
997997
!IS_PARTITIONED(hctl) && !hashp->frozen &&
998998
!has_seq_scans(hashp))
999999
(void) expand_table(hashp);
@@ -1332,11 +1332,11 @@ get_hash_entry(HTAB *hashp, int freelist_idx)
13321332
/*
13331333
* hash_get_num_entries -- get the number of entries in a hashtable
13341334
*/
1335-
long
1335+
int64
13361336
hash_get_num_entries(HTAB *hashp)
13371337
{
13381338
int i;
1339-
long sum = hashp->hctl->freeList[0].nentries;
1339+
int64 sum = hashp->hctl->freeList[0].nentries;
13401340

13411341
/*
13421342
* We currently don't bother with acquiring the mutexes; it's only
@@ -1417,9 +1417,9 @@ hash_seq_search(HASH_SEQ_STATUS *status)
14171417
HTAB *hashp;
14181418
HASHHDR *hctl;
14191419
uint32 max_bucket;
1420-
long ssize;
1421-
long segment_num;
1422-
long segment_ndx;
1420+
int64 ssize;
1421+
int64 segment_num;
1422+
int64 segment_ndx;
14231423
HASHSEGMENT segp;
14241424
uint32 curBucket;
14251425
HASHELEMENT *curElem;
@@ -1548,11 +1548,11 @@ expand_table(HTAB *hashp)
15481548
HASHHDR *hctl = hashp->hctl;
15491549
HASHSEGMENT old_seg,
15501550
new_seg;
1551-
long old_bucket,
1551+
int64 old_bucket,
15521552
new_bucket;
1553-
long new_segnum,
1553+
int64 new_segnum,
15541554
new_segndx;
1555-
long old_segnum,
1555+
int64 old_segnum,
15561556
old_segndx;
15571557
HASHBUCKET *oldlink,
15581558
*newlink;
@@ -1620,7 +1620,7 @@ expand_table(HTAB *hashp)
16201620
currElement = nextElement)
16211621
{
16221622
nextElement = currElement->link;
1623-
if ((long) calc_bucket(hctl, currElement->hashvalue) == old_bucket)
1623+
if ((int64) calc_bucket(hctl, currElement->hashvalue) == old_bucket)
16241624
{
16251625
*oldlink = currElement;
16261626
oldlink = &currElement->link;
@@ -1644,9 +1644,9 @@ dir_realloc(HTAB *hashp)
16441644
{
16451645
HASHSEGMENT *p;
16461646
HASHSEGMENT *old_p;
1647-
long new_dsize;
1648-
long old_dirsize;
1649-
long new_dirsize;
1647+
int64 new_dsize;
1648+
int64 old_dirsize;
1649+
int64 new_dirsize;
16501650

16511651
if (hashp->hctl->max_dsize != NO_MAX_DSIZE)
16521652
return false;
@@ -1780,8 +1780,8 @@ hash_initial_lookup(HTAB *hashp, uint32 hashvalue, HASHBUCKET **bucketptr)
17801780
{
17811781
HASHHDR *hctl = hashp->hctl;
17821782
HASHSEGMENT segp;
1783-
long segment_num;
1784-
long segment_ndx;
1783+
int64 segment_num;
1784+
int64 segment_ndx;
17851785
uint32 bucket;
17861786

17871787
bucket = calc_bucket(hctl, hashvalue);
@@ -1814,33 +1814,29 @@ hash_corrupted(HTAB *hashp)
18141814

18151815
/* calculate ceil(log base 2) of num */
18161816
int
1817-
my_log2(long num)
1817+
my_log2(int64 num)
18181818
{
18191819
/*
18201820
* guard against too-large input, which would be invalid for
18211821
* pg_ceil_log2_*()
18221822
*/
1823-
if (num > LONG_MAX / 2)
1824-
num = LONG_MAX / 2;
1823+
if (num > PG_INT64_MAX / 2)
1824+
num = PG_INT64_MAX / 2;
18251825

1826-
#if SIZEOF_LONG < 8
1827-
return pg_ceil_log2_32(num);
1828-
#else
18291826
return pg_ceil_log2_64(num);
1830-
#endif
18311827
}
18321828

1833-
/* calculate first power of 2 >= num, bounded to what will fit in a long */
1834-
static long
1835-
next_pow2_long(long num)
1829+
/* calculate first power of 2 >= num, bounded to what will fit in a int64 */
1830+
static int64
1831+
next_pow2_int64(int64 num)
18361832
{
18371833
/* my_log2's internal range check is sufficient */
18381834
return 1L << my_log2(num);
18391835
}
18401836

18411837
/* calculate first power of 2 >= num, bounded to what will fit in an int */
18421838
static int
1843-
next_pow2_int(long num)
1839+
next_pow2_int(int64 num)
18441840
{
18451841
if (num > INT_MAX / 2)
18461842
num = INT_MAX / 2;

src/include/storage/shmem.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ extern void *ShmemAllocNoError(Size size);
3535
extern void *ShmemAllocUnlocked(Size size);
3636
extern bool ShmemAddrIsValid(const void *addr);
3737
extern void InitShmemIndex(void);
38-
extern HTAB *ShmemInitHash(const char *name, long init_size, long max_size,
38+
extern HTAB *ShmemInitHash(const char *name, int64 init_size, int64 max_size,
3939
HASHCTL *infoP, int hash_flags);
4040
extern void *ShmemInitStruct(const char *name, Size size, bool *foundPtr);
4141
extern Size add_size(Size s1, Size s2);

src/include/utils/dynahash.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,6 @@
1515
#ifndef DYNAHASH_H
1616
#define DYNAHASH_H
1717

18-
extern int my_log2(long num);
18+
extern int my_log2(int64 num);
1919

2020
#endif /* DYNAHASH_H */

src/include/utils/hsearch.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,12 @@ typedef struct HTAB HTAB;
6565
typedef struct HASHCTL
6666
{
6767
/* Used if HASH_PARTITION flag is set: */
68-
long num_partitions; /* # partitions (must be power of 2) */
68+
int64 num_partitions; /* # partitions (must be power of 2) */
6969
/* Used if HASH_SEGMENT flag is set: */
70-
long ssize; /* segment size */
70+
int64 ssize; /* segment size */
7171
/* Used if HASH_DIRSIZE flag is set: */
72-
long dsize; /* (initial) directory size */
73-
long max_dsize; /* limit to dsize if dir size is limited */
72+
int64 dsize; /* (initial) directory size */
73+
int64 max_dsize; /* limit to dsize if dir size is limited */
7474
/* Used if HASH_ELEM flag is set (which is now required): */
7575
Size keysize; /* hash key length in bytes */
7676
Size entrysize; /* total user element size in bytes */
@@ -129,7 +129,7 @@ typedef struct
129129
/*
130130
* prototypes for functions in dynahash.c
131131
*/
132-
extern HTAB *hash_create(const char *tabname, long nelem,
132+
extern HTAB *hash_create(const char *tabname, int64 nelem,
133133
const HASHCTL *info, int flags);
134134
extern void hash_destroy(HTAB *hashp);
135135
extern void hash_stats(const char *caller, HTAB *hashp);
@@ -141,16 +141,16 @@ extern void *hash_search_with_hash_value(HTAB *hashp, const void *keyPtr,
141141
bool *foundPtr);
142142
extern bool hash_update_hash_key(HTAB *hashp, void *existingEntry,
143143
const void *newKeyPtr);
144-
extern long hash_get_num_entries(HTAB *hashp);
144+
extern int64 hash_get_num_entries(HTAB *hashp);
145145
extern void hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp);
146146
extern void hash_seq_init_with_hash_value(HASH_SEQ_STATUS *status,
147147
HTAB *hashp,
148148
uint32 hashvalue);
149149
extern void *hash_seq_search(HASH_SEQ_STATUS *status);
150150
extern void hash_seq_term(HASH_SEQ_STATUS *status);
151151
extern void hash_freeze(HTAB *hashp);
152-
extern Size hash_estimate_size(long num_entries, Size entrysize);
153-
extern long hash_select_dirsize(long num_entries);
152+
extern Size hash_estimate_size(int64 num_entries, Size entrysize);
153+
extern int64 hash_select_dirsize(int64 num_entries);
154154
extern Size hash_get_shared_size(HASHCTL *info, int flags);
155155
extern void AtEOXact_HashTables(bool isCommit);
156156
extern void AtEOSubXact_HashTables(bool isCommit, int nestDepth);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy