On Wed, Feb 26, 2020 at 09:12:24AM +0100, David Fetter wrote: > On Fri, Jan 31, 2020 at 04:59:18PM +0100, David Fetter wrote: > > On Wed, Jan 15, 2020 at 03:45:12PM -0800, Jesse Zhang wrote: > > > On Tue, Jan 14, 2020 at 2:09 PM David Fetter <da...@fetter.org> wrote: > > > > > The changes in hash AM and SIMPLEHASH do look like a net positive > > > > > improvement. My biggest cringe might be in pg_bitutils: > > > > > > > > > > 1. Is ceil_log2_64 dead code? > > > > > > > > Let's call it nascent code. I suspect there are places it could go, if > > > > I look for them. Also, it seemed silly to have one without the other. > > > > > > > > > > While not absolutely required, I'd like us to find at least one > > > place and start using it. (Clang also nags at me when we have > > > unused functions). > > > > Done in the expanded patches attached. > > These bit-rotted a little, so I've updated them.
05d8449e73694585b59f8b03aaa087f04cc4679a broke this patch set, so fix. Best, David. -- David Fetter <david(at)fetter(dot)org> http://fetter.org/ Phone: +1 415 235 3778 Remember to vote! Consider donating to Postgres: http://www.postgresql.org/about/donate
>From 2f8778f6133be23f6b7c375a39e9940ecc9fb063 Mon Sep 17 00:00:00 2001 From: David Fetter <da...@fetter.org> Date: Wed, 29 Jan 2020 02:09:59 -0800 Subject: [PATCH v6 1/3] de-long-ify To: hackers MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="------------2.24.1" This is a multi-part message in MIME format. --------------2.24.1 Content-Type: text/plain; charset=UTF-8; format=fixed Content-Transfer-Encoding: 8bit diff --git a/src/backend/access/gist/gistbuildbuffers.c b/src/backend/access/gist/gistbuildbuffers.c index 4b562d8d3f..482a569814 100644 --- a/src/backend/access/gist/gistbuildbuffers.c +++ b/src/backend/access/gist/gistbuildbuffers.c @@ -34,11 +34,11 @@ static void gistPlaceItupToPage(GISTNodeBufferPage *pageBuffer, IndexTuple item); static void gistGetItupFromPage(GISTNodeBufferPage *pageBuffer, IndexTuple *item); -static long gistBuffersGetFreeBlock(GISTBuildBuffers *gfbb); -static void gistBuffersReleaseBlock(GISTBuildBuffers *gfbb, long blocknum); +static uint64 gistBuffersGetFreeBlock(GISTBuildBuffers *gfbb); +static void gistBuffersReleaseBlock(GISTBuildBuffers *gfbb, uint64 blocknum); -static void ReadTempFileBlock(BufFile *file, long blknum, void *ptr); -static void WriteTempFileBlock(BufFile *file, long blknum, void *ptr); +static void ReadTempFileBlock(BufFile *file, uint64 blknum, void *ptr); +static void WriteTempFileBlock(BufFile *file, uint64 blknum, void *ptr); /* @@ -64,7 +64,7 @@ gistInitBuildBuffers(int pagesPerBuffer, int levelStep, int maxLevel) /* Initialize free page management. */ gfbb->nFreeBlocks = 0; gfbb->freeBlocksLen = 32; - gfbb->freeBlocks = (long *) palloc(gfbb->freeBlocksLen * sizeof(long)); + gfbb->freeBlocks = (int64 *) palloc(gfbb->freeBlocksLen * sizeof(int64)); /* * Current memory context will be used for all in-memory data structures @@ -469,7 +469,7 @@ gistPopItupFromNodeBuffer(GISTBuildBuffers *gfbb, GISTNodeBuffer *nodeBuffer, /* * Select a currently unused block for writing to. */ -static long +static uint64 gistBuffersGetFreeBlock(GISTBuildBuffers *gfbb) { /* @@ -487,7 +487,7 @@ gistBuffersGetFreeBlock(GISTBuildBuffers *gfbb) * Return a block# to the freelist. */ static void -gistBuffersReleaseBlock(GISTBuildBuffers *gfbb, long blocknum) +gistBuffersReleaseBlock(GISTBuildBuffers *gfbb, uint64 blocknum) { int ndx; @@ -495,9 +495,9 @@ gistBuffersReleaseBlock(GISTBuildBuffers *gfbb, long blocknum) if (gfbb->nFreeBlocks >= gfbb->freeBlocksLen) { gfbb->freeBlocksLen *= 2; - gfbb->freeBlocks = (long *) repalloc(gfbb->freeBlocks, + gfbb->freeBlocks = (int64 *) repalloc(gfbb->freeBlocks, gfbb->freeBlocksLen * - sizeof(long)); + sizeof(uint64)); } /* Add blocknum to array */ @@ -755,7 +755,7 @@ gistRelocateBuildBuffersOnSplit(GISTBuildBuffers *gfbb, GISTSTATE *giststate, */ static void -ReadTempFileBlock(BufFile *file, long blknum, void *ptr) +ReadTempFileBlock(BufFile *file, uint64 blknum, void *ptr) { if (BufFileSeekBlock(file, blknum) != 0) elog(ERROR, "could not seek temporary file: %m"); @@ -764,7 +764,7 @@ ReadTempFileBlock(BufFile *file, long blknum, void *ptr) } static void -WriteTempFileBlock(BufFile *file, long blknum, void *ptr) +WriteTempFileBlock(BufFile *file, uint64 blknum, void *ptr) { if (BufFileSeekBlock(file, blknum) != 0) elog(ERROR, "could not seek temporary file: %m"); diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c index c46764bf42..4fc478640a 100644 --- a/src/backend/executor/spi.c +++ b/src/backend/executor/spi.c @@ -70,7 +70,7 @@ static int _SPI_pquery(QueryDesc *queryDesc, bool fire_triggers, uint64 tcount); static void _SPI_error_callback(void *arg); static void _SPI_cursor_operation(Portal portal, - FetchDirection direction, long count, + FetchDirection direction, uint64 count, DestReceiver *dest); static SPIPlanPtr _SPI_make_plan_non_temp(SPIPlanPtr plan); @@ -493,7 +493,7 @@ SPI_inside_nonatomic_context(void) /* Parse, plan, and execute a query string */ int -SPI_execute(const char *src, bool read_only, long tcount) +SPI_execute(const char *src, bool read_only, int64 tcount) { _SPI_plan plan; int res; @@ -521,7 +521,7 @@ SPI_execute(const char *src, bool read_only, long tcount) /* Obsolete version of SPI_execute */ int -SPI_exec(const char *src, long tcount) +SPI_exec(const char *src, int64 tcount) { return SPI_execute(src, false, tcount); } @@ -529,7 +529,7 @@ SPI_exec(const char *src, long tcount) /* Execute a previously prepared plan */ int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, - bool read_only, long tcount) + bool read_only, int64 tcount) { int res; @@ -555,7 +555,7 @@ SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, /* Obsolete version of SPI_execute_plan */ int -SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, long tcount) +SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, int64 tcount) { return SPI_execute_plan(plan, Values, Nulls, false, tcount); } @@ -563,7 +563,7 @@ SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, long tcount) /* Execute a previously prepared plan */ int SPI_execute_plan_with_paramlist(SPIPlanPtr plan, ParamListInfo params, - bool read_only, long tcount) + bool read_only, int64 tcount) { int res; @@ -599,7 +599,7 @@ int SPI_execute_snapshot(SPIPlanPtr plan, Datum *Values, const char *Nulls, Snapshot snapshot, Snapshot crosscheck_snapshot, - bool read_only, bool fire_triggers, long tcount) + bool read_only, bool fire_triggers, int64 tcount) { int res; @@ -633,7 +633,7 @@ int SPI_execute_with_args(const char *src, int nargs, Oid *argtypes, Datum *Values, const char *Nulls, - bool read_only, long tcount) + bool read_only, int64 tcount) { int res; _SPI_plan plan; @@ -1530,7 +1530,7 @@ SPI_cursor_find(const char *name) * Fetch rows in a cursor */ void -SPI_cursor_fetch(Portal portal, bool forward, long count) +SPI_cursor_fetch(Portal portal, bool forward, int64 count) { _SPI_cursor_operation(portal, forward ? FETCH_FORWARD : FETCH_BACKWARD, count, @@ -1545,7 +1545,7 @@ SPI_cursor_fetch(Portal portal, bool forward, long count) * Move in a cursor */ void -SPI_cursor_move(Portal portal, bool forward, long count) +SPI_cursor_move(Portal portal, bool forward, int64 count) { _SPI_cursor_operation(portal, forward ? FETCH_FORWARD : FETCH_BACKWARD, count, @@ -1559,7 +1559,7 @@ SPI_cursor_move(Portal portal, bool forward, long count) * Fetch rows in a scrollable cursor */ void -SPI_scroll_cursor_fetch(Portal portal, FetchDirection direction, long count) +SPI_scroll_cursor_fetch(Portal portal, FetchDirection direction, int64 count) { _SPI_cursor_operation(portal, direction, count, @@ -1574,7 +1574,7 @@ SPI_scroll_cursor_fetch(Portal portal, FetchDirection direction, long count) * Move in a scrollable cursor */ void -SPI_scroll_cursor_move(Portal portal, FetchDirection direction, long count) +SPI_scroll_cursor_move(Portal portal, FetchDirection direction, int64 count) { _SPI_cursor_operation(portal, direction, count, None_Receiver); } @@ -2567,7 +2567,7 @@ _SPI_error_callback(void *arg) * Do a FETCH or MOVE in a cursor */ static void -_SPI_cursor_operation(Portal portal, FetchDirection direction, long count, +_SPI_cursor_operation(Portal portal, FetchDirection direction, uint64 count, DestReceiver *dest) { uint64 nfetched; diff --git a/src/backend/storage/file/buffile.c b/src/backend/storage/file/buffile.c index 35e8f12e62..db73a9f159 100644 --- a/src/backend/storage/file/buffile.c +++ b/src/backend/storage/file/buffile.c @@ -749,7 +749,7 @@ BufFileTell(BufFile *file, int *fileno, off_t *offset) * impossible seek is attempted. */ int -BufFileSeekBlock(BufFile *file, long blknum) +BufFileSeekBlock(BufFile *file, uint64 blknum) { return BufFileSeek(file, (int) (blknum / BUFFILE_SEG_SIZE), @@ -760,13 +760,11 @@ BufFileSeekBlock(BufFile *file, long blknum) #ifdef NOT_USED /* * BufFileTellBlock --- block-oriented tell - * - * Any fractional part of a block in the current seek position is ignored. */ -long +uint64 BufFileTellBlock(BufFile *file) { - long blknum; + uint64 blknum; blknum = (file->curOffset + file->pos) / BLCKSZ; blknum += file->curFile * BUFFILE_SEG_SIZE; @@ -820,10 +818,10 @@ BufFileSize(BufFile *file) * begins. Caller should apply this as an offset when working off block * positions that are in terms of the original BufFile space. */ -long +uint64 BufFileAppend(BufFile *target, BufFile *source) { - long startBlock = target->numFiles * BUFFILE_SEG_SIZE; + uint64 startBlock = target->numFiles * BUFFILE_SEG_SIZE; int newNumFiles = target->numFiles + source->numFiles; int i; diff --git a/src/backend/storage/ipc/latch.c b/src/backend/storage/ipc/latch.c index 046ca5c6c7..cb00c67303 100644 --- a/src/backend/storage/ipc/latch.c +++ b/src/backend/storage/ipc/latch.c @@ -349,7 +349,7 @@ DisownLatch(Latch *latch) * function returns immediately. * * The "timeout" is given in milliseconds. It must be >= 0 if WL_TIMEOUT flag - * is given. Although it is declared as "long", we don't actually support + * is given. Although it is declared as "int64", we don't actually support * timeouts longer than INT_MAX milliseconds. Note that some extra overhead * is incurred when WL_TIMEOUT is given, so avoid using a timeout if possible. * @@ -362,7 +362,7 @@ DisownLatch(Latch *latch) * we return all of them in one call, but we will return at least one. */ int -WaitLatch(Latch *latch, int wakeEvents, long timeout, +WaitLatch(Latch *latch, int wakeEvents, int64 timeout, uint32 wait_event_info) { return WaitLatchOrSocket(latch, wakeEvents, PGINVALID_SOCKET, timeout, @@ -388,7 +388,7 @@ WaitLatch(Latch *latch, int wakeEvents, long timeout, */ int WaitLatchOrSocket(Latch *latch, int wakeEvents, pgsocket sock, - long timeout, uint32 wait_event_info) + int64 timeout, uint32 wait_event_info) { int ret = 0; int rc; @@ -1155,14 +1155,14 @@ WaitEventAdjustWin32(WaitEventSet *set, WaitEvent *event) * values associated with the registered event. */ int -WaitEventSetWait(WaitEventSet *set, long timeout, +WaitEventSetWait(WaitEventSet *set, int64 timeout, WaitEvent *occurred_events, int nevents, uint32 wait_event_info) { int returned_events = 0; instr_time start_time; instr_time cur_time; - long cur_timeout = -1; + int64 cur_timeout = -1; Assert(nevents > 0); @@ -1247,7 +1247,7 @@ WaitEventSetWait(WaitEventSet *set, long timeout, { INSTR_TIME_SET_CURRENT(cur_time); INSTR_TIME_SUBTRACT(cur_time, start_time); - cur_timeout = timeout - (long) INSTR_TIME_GET_MILLISEC(cur_time); + cur_timeout = timeout - INSTR_TIME_GET_MILLISEC(cur_time); if (cur_timeout <= 0) break; } diff --git a/src/backend/storage/ipc/shmem.c b/src/backend/storage/ipc/shmem.c index 2892a573e4..582c63a5e6 100644 --- a/src/backend/storage/ipc/shmem.c +++ b/src/backend/storage/ipc/shmem.c @@ -335,8 +335,8 @@ InitShmemIndex(void) */ HTAB * ShmemInitHash(const char *name, /* table string name for shmem index */ - long init_size, /* initial table size */ - long max_size, /* max size of the table */ + uint64 init_size, /* initial table size */ + uint64 max_size, /* max size of the table */ HASHCTL *infoP, /* info about key and bucket size */ int hash_flags) /* info about infoP */ { diff --git a/src/backend/storage/lmgr/condition_variable.c b/src/backend/storage/lmgr/condition_variable.c index 37b6a4eecd..43c662aaeb 100644 --- a/src/backend/storage/lmgr/condition_variable.c +++ b/src/backend/storage/lmgr/condition_variable.c @@ -129,10 +129,10 @@ ConditionVariableSleep(ConditionVariable *cv, uint32 wait_event_info) * See ConditionVariableSleep() for general usage. */ bool -ConditionVariableTimedSleep(ConditionVariable *cv, long timeout, +ConditionVariableTimedSleep(ConditionVariable *cv, int64 timeout, uint32 wait_event_info) { - long cur_timeout = -1; + int64 cur_timeout = -1; instr_time start_time; instr_time cur_time; @@ -217,7 +217,7 @@ ConditionVariableTimedSleep(ConditionVariable *cv, long timeout, { INSTR_TIME_SET_CURRENT(cur_time); INSTR_TIME_SUBTRACT(cur_time, start_time); - cur_timeout = timeout - (long) INSTR_TIME_GET_MILLISEC(cur_time); + cur_timeout = timeout - (int64) INSTR_TIME_GET_MILLISEC(cur_time); /* Have we crossed the timeout threshold? */ if (cur_timeout <= 0) diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 0a6f80963b..9bb9c1fda9 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -109,7 +109,7 @@ int PostAuthDelay = 0; */ /* max_stack_depth converted to bytes for speed of checking */ -static long max_stack_depth_bytes = 100 * 1024L; +static uint64 max_stack_depth_bytes = 100 * 1024UL; /* * Stack base pointer -- initialized by PostmasterMain and inherited by @@ -2016,7 +2016,7 @@ exec_bind_message(StringInfo input_message) * Process an "Execute" message for a portal */ static void -exec_execute_message(const char *portal_name, long max_rows) +exec_execute_message(const char *portal_name, uint64 max_rows) { CommandDest dest; DestReceiver *receiver; @@ -2302,7 +2302,7 @@ check_log_duration(char *msec_str, bool was_logged) if (log_duration || log_min_duration_sample >= 0 || log_min_duration_statement >= 0 || xact_is_sampled) { - long secs; + int64 secs; int usecs; int msecs; bool exceeded_duration; @@ -3302,12 +3302,12 @@ bool stack_is_too_deep(void) { char stack_top_loc; - long stack_depth; + int64 stack_depth; /* * Compute distance from reference point to my local variables */ - stack_depth = (long) (stack_base_ptr - &stack_top_loc); + stack_depth = (int64) (stack_base_ptr - &stack_top_loc); /* * Take abs value, since stacks grow up on some machines, down on others @@ -3336,7 +3336,7 @@ stack_is_too_deep(void) * Note we assume that the same max_stack_depth applies to both stacks. */ #if defined(__ia64__) || defined(__ia64) - stack_depth = (long) (ia64_get_bsp() - register_stack_base_ptr); + stack_depth = (int64) (ia64_get_bsp() - register_stack_base_ptr); if (stack_depth > max_stack_depth_bytes && register_stack_base_ptr != NULL) @@ -3350,8 +3350,8 @@ stack_is_too_deep(void) bool check_max_stack_depth(int *newval, void **extra, GucSource source) { - long newval_bytes = *newval * 1024L; - long stack_rlimit = get_stack_depth_rlimit(); + uint64 newval_bytes = *newval * 1024UL; + uint64 stack_rlimit = get_stack_depth_rlimit(); if (stack_rlimit > 0 && newval_bytes > stack_rlimit - STACK_DEPTH_SLOP) { @@ -3367,7 +3367,7 @@ check_max_stack_depth(int *newval, void **extra, GucSource source) void assign_max_stack_depth(int newval, void *extra) { - long newval_bytes = newval * 1024L; + uint64 newval_bytes = newval * 1024UL; max_stack_depth_bytes = newval_bytes; } @@ -4696,7 +4696,7 @@ static void log_disconnections(int code, Datum arg) { Port *port = MyProcPort; - long secs; + int64 secs; int usecs; int msecs; int hours, diff --git a/src/backend/tcop/pquery.c b/src/backend/tcop/pquery.c index 0f5801e046..f519ce7def 100644 --- a/src/backend/tcop/pquery.c +++ b/src/backend/tcop/pquery.c @@ -44,7 +44,7 @@ static void ProcessQuery(PlannedStmt *plan, static void FillPortalStore(Portal portal, bool isTopLevel); static uint64 RunFromStore(Portal portal, ScanDirection direction, uint64 count, DestReceiver *dest); -static uint64 PortalRunSelect(Portal portal, bool forward, long count, +static uint64 PortalRunSelect(Portal portal, bool forward, int64 count, DestReceiver *dest); static void PortalRunUtility(Portal portal, PlannedStmt *pstmt, bool isTopLevel, bool setHoldSnapshot, @@ -55,7 +55,7 @@ static void PortalRunMulti(Portal portal, char *completionTag); static uint64 DoPortalRunFetch(Portal portal, FetchDirection fdirection, - long count, + int64 count, DestReceiver *dest); static void DoPortalRewind(Portal portal); @@ -683,7 +683,7 @@ PortalSetResultFormat(Portal portal, int nFormats, int16 *formats) * suspended due to exhaustion of the count parameter. */ bool -PortalRun(Portal portal, long count, bool isTopLevel, bool run_once, +PortalRun(Portal portal, int64 count, bool isTopLevel, bool run_once, DestReceiver *dest, DestReceiver *altdest, char *completionTag) { @@ -871,7 +871,7 @@ PortalRun(Portal portal, long count, bool isTopLevel, bool run_once, static uint64 PortalRunSelect(Portal portal, bool forward, - long count, + int64 count, DestReceiver *dest) { QueryDesc *queryDesc; @@ -1391,7 +1391,7 @@ PortalRunMulti(Portal portal, uint64 PortalRunFetch(Portal portal, FetchDirection fdirection, - long count, + int64 count, DestReceiver *dest) { uint64 result; @@ -1493,7 +1493,7 @@ PortalRunFetch(Portal portal, static uint64 DoPortalRunFetch(Portal portal, FetchDirection fdirection, - long count, + int64 count, DestReceiver *dest) { bool forward; @@ -1531,7 +1531,7 @@ DoPortalRunFetch(Portal portal, * In practice, if the goal is less than halfway back to the * start, it's better to scan from where we are. * - * Also, if current portalPos is outside the range of "long", + * Also, if current portalPos is outside the range of "int64", * do it the hard way to avoid possible overflow of the count * argument to PortalRunSelect. We must exclude exactly * LONG_MAX, as well, lest the count look like FETCH_ALL. @@ -1549,7 +1549,7 @@ DoPortalRunFetch(Portal portal, } else { - long pos = (long) portal->portalPos; + int64 pos = (int64) portal->portalPos; if (portal->atEnd) pos++; /* need one extra fetch if off end */ diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c index 0b6c9d5ea8..ddd471c059 100644 --- a/src/backend/utils/adt/timestamp.c +++ b/src/backend/utils/adt/timestamp.c @@ -1655,7 +1655,7 @@ timeofday(PG_FUNCTION_ARGS) */ void TimestampDifference(TimestampTz start_time, TimestampTz stop_time, - long *secs, int *microsecs) + int64 *secs, int *microsecs) { TimestampTz diff = stop_time - start_time; @@ -1666,7 +1666,7 @@ TimestampDifference(TimestampTz start_time, TimestampTz stop_time, } else { - *secs = (long) (diff / USECS_PER_SEC); + *secs = (int64) (diff / USECS_PER_SEC); *microsecs = (int) (diff % USECS_PER_SEC); } } diff --git a/src/backend/utils/hash/dynahash.c b/src/backend/utils/hash/dynahash.c index b5381958e7..7769c79861 100644 --- a/src/backend/utils/hash/dynahash.c +++ b/src/backend/utils/hash/dynahash.c @@ -142,7 +142,7 @@ typedef HASHBUCKET *HASHSEGMENT; typedef struct { slock_t mutex; /* spinlock for this freelist */ - long nentries; /* number of entries in associated buckets */ + uint64 nentries; /* number of entries in associated buckets */ HASHELEMENT *freeList; /* chain of free elements */ } FreeListData; @@ -170,8 +170,8 @@ struct HASHHDR /* These fields can change, but not in a partitioned table */ /* Also, dsize can't change in a shared table, even if unpartitioned */ - long dsize; /* directory size */ - long nsegs; /* number of allocated segments (<= dsize) */ + uint64 dsize; /* directory size */ + uint64 nsegs; /* number of allocated segments (<= dsize) */ uint32 max_bucket; /* ID of maximum bucket in use */ uint32 high_mask; /* mask to modulo into entire table */ uint32 low_mask; /* mask to modulo into lower half of table */ @@ -179,10 +179,10 @@ struct HASHHDR /* These fields are fixed at hashtable creation */ Size keysize; /* hash key length in bytes */ Size entrysize; /* total user element size in bytes */ - long num_partitions; /* # partitions (must be power of 2), or 0 */ - long ffactor; /* target fill factor */ - long max_dsize; /* 'dsize' limit if directory is fixed size */ - long ssize; /* segment size --- must be power of 2 */ + uint64 num_partitions; /* # partitions (must be power of 2), or 0 */ + uint64 ffactor; /* target fill factor */ + uint64 max_dsize; /* 'dsize' limit if directory is fixed size */ + uint64 ssize; /* segment size --- must be power of 2 */ int sshift; /* segment shift = log2(ssize) */ int nelem_alloc; /* number of entries to allocate at once */ @@ -192,8 +192,8 @@ struct HASHHDR * Count statistics here. NB: stats code doesn't bother with mutex, so * counts could be corrupted a bit in a partitioned table. */ - long accesses; - long collisions; + uint64 accesses; + uint64 collisions; #endif }; @@ -224,7 +224,7 @@ struct HTAB /* We keep local copies of these fixed values to reduce contention */ Size keysize; /* hash key length in bytes */ - long ssize; /* segment size --- must be power of 2 */ + uint64 ssize; /* segment size --- must be power of 2 */ int sshift; /* segment shift = log2(ssize) */ }; @@ -245,9 +245,9 @@ struct HTAB #define MOD(x,y) ((x) & ((y)-1)) #ifdef HASH_STATISTICS -static long hash_accesses, - hash_collisions, - hash_expansions; +static uint64 hash_accesses, + hash_collisions, + hash_expansions; #endif /* @@ -261,10 +261,10 @@ static bool expand_table(HTAB *hashp); static HASHBUCKET get_hash_entry(HTAB *hashp, int freelist_idx); static void hdefault(HTAB *hashp); static int choose_nelem_alloc(Size entrysize); -static bool init_htab(HTAB *hashp, long nelem); +static bool init_htab(HTAB *hashp, uint64 nelem); static void hash_corrupted(HTAB *hashp); -static long next_pow2_long(long num); -static int next_pow2_int(long num); +static uint64 next_pow2_uint64(uint64 num); +static int next_pow2_int(uint64 num); static void register_seq_scan(HTAB *hashp); static void deregister_seq_scan(HTAB *hashp); static bool has_seq_scans(HTAB *hashp); @@ -314,7 +314,7 @@ string_compare(const char *key1, const char *key2, Size keysize) * large nelem will penalize hash_seq_search speed without buying much. */ HTAB * -hash_create(const char *tabname, long nelem, HASHCTL *info, int flags) +hash_create(const char *tabname, uint64 nelem, HASHCTL *info, int flags) { HTAB *hashp; HASHHDR *hctl; @@ -634,7 +634,7 @@ choose_nelem_alloc(Size entrysize) * arrays */ static bool -init_htab(HTAB *hashp, long nelem) +init_htab(HTAB *hashp, uint64 nelem) { HASHHDR *hctl = hashp->hctl; HASHSEGMENT *segp; @@ -730,10 +730,10 @@ init_htab(HTAB *hashp, long nelem) * NB: assumes that all hash structure parameters have default values! */ Size -hash_estimate_size(long num_entries, Size entrysize) +hash_estimate_size(uint64 num_entries, Size entrysize) { Size size; - long nBuckets, + uint64 nBuckets, nSegments, nDirEntries, nElementAllocs, @@ -741,9 +741,9 @@ hash_estimate_size(long num_entries, Size entrysize) elementAllocCnt; /* estimate number of buckets wanted */ - nBuckets = next_pow2_long((num_entries - 1) / DEF_FFACTOR + 1); + nBuckets = next_pow2_uint64((num_entries - 1) / DEF_FFACTOR + 1); /* # of segments needed for nBuckets */ - nSegments = next_pow2_long((nBuckets - 1) / DEF_SEGSIZE + 1); + nSegments = next_pow2_uint64((nBuckets - 1) / DEF_SEGSIZE + 1); /* directory entries */ nDirEntries = DEF_DIRSIZE; while (nDirEntries < nSegments) @@ -776,17 +776,17 @@ hash_estimate_size(long num_entries, Size entrysize) * * XXX this had better agree with the behavior of init_htab()... */ -long -hash_select_dirsize(long num_entries) +uint64 +hash_select_dirsize(uint64 num_entries) { - long nBuckets, + uint64 nBuckets, nSegments, nDirEntries; /* estimate number of buckets wanted */ - nBuckets = next_pow2_long((num_entries - 1) / DEF_FFACTOR + 1); + nBuckets = next_pow2_uint64((num_entries - 1) / DEF_FFACTOR + 1); /* # of segments needed for nBuckets */ - nSegments = next_pow2_long((nBuckets - 1) / DEF_SEGSIZE + 1); + nSegments = next_pow2_uint64((nBuckets - 1) / DEF_SEGSIZE + 1); /* directory entries */ nDirEntries = DEF_DIRSIZE; while (nDirEntries < nSegments) @@ -837,8 +837,8 @@ hash_stats(const char *where, HTAB *hashp) fprintf(stderr, "%s: this HTAB -- accesses %ld collisions %ld\n", where, hashp->hctl->accesses, hashp->hctl->collisions); - fprintf(stderr, "hash_stats: entries %ld keysize %ld maxp %u segmentcount %ld\n", - hash_get_num_entries(hashp), (long) hashp->hctl->keysize, + fprintf(stderr, "hash_stats: entries %ld keysize %llu maxp %u segmentcount %ld\n", + hash_get_num_entries(hashp), (uint64) hashp->hctl->keysize, hashp->hctl->max_bucket, hashp->hctl->nsegs); fprintf(stderr, "%s: total accesses %ld total collisions %ld\n", where, hash_accesses, hash_collisions); @@ -927,8 +927,8 @@ hash_search_with_hash_value(HTAB *hashp, int freelist_idx = FREELIST_IDX(hctl, hashvalue); Size keysize; uint32 bucket; - long segment_num; - long segment_ndx; + uint64 segment_num; + uint64 segment_ndx; HASHSEGMENT segp; HASHBUCKET currBucket; HASHBUCKET *prevBucketPtr; @@ -955,7 +955,7 @@ hash_search_with_hash_value(HTAB *hashp, * order of these tests is to try to check cheaper conditions first. */ if (!IS_PARTITIONED(hctl) && !hashp->frozen && - hctl->freeList[0].nentries / (long) (hctl->max_bucket + 1) >= hctl->ffactor && + hctl->freeList[0].nentries / (uint64) (hctl->max_bucket + 1) >= hctl->ffactor && !has_seq_scans(hashp)) (void) expand_table(hashp); } @@ -1123,8 +1123,8 @@ hash_update_hash_key(HTAB *hashp, Size keysize; uint32 bucket; uint32 newbucket; - long segment_num; - long segment_ndx; + uint64 segment_num; + uint64 segment_ndx; HASHSEGMENT segp; HASHBUCKET currBucket; HASHBUCKET *prevBucketPtr; @@ -1332,11 +1332,11 @@ get_hash_entry(HTAB *hashp, int freelist_idx) /* * hash_get_num_entries -- get the number of entries in a hashtable */ -long +uint64 hash_get_num_entries(HTAB *hashp) { int i; - long sum = hashp->hctl->freeList[0].nentries; + uint64 sum = hashp->hctl->freeList[0].nentries; /* * We currently don't bother with acquiring the mutexes; it's only @@ -1392,9 +1392,9 @@ hash_seq_search(HASH_SEQ_STATUS *status) HTAB *hashp; HASHHDR *hctl; uint32 max_bucket; - long ssize; - long segment_num; - long segment_ndx; + uint64 ssize; + uint64 segment_num; + uint64 segment_ndx; HASHSEGMENT segp; uint32 curBucket; HASHELEMENT *curElem; @@ -1505,11 +1505,11 @@ expand_table(HTAB *hashp) HASHHDR *hctl = hashp->hctl; HASHSEGMENT old_seg, new_seg; - long old_bucket, + uint64 old_bucket, new_bucket; - long new_segnum, + uint64 new_segnum, new_segndx; - long old_segnum, + uint64 old_segnum, old_segndx; HASHBUCKET *oldlink, *newlink; @@ -1577,7 +1577,7 @@ expand_table(HTAB *hashp) currElement = nextElement) { nextElement = currElement->link; - if ((long) calc_bucket(hctl, currElement->hashvalue) == old_bucket) + if ((uint64) calc_bucket(hctl, currElement->hashvalue) == old_bucket) { *oldlink = currElement; oldlink = &currElement->link; @@ -1601,9 +1601,9 @@ dir_realloc(HTAB *hashp) { HASHSEGMENT *p; HASHSEGMENT *old_p; - long new_dsize; - long old_dirsize; - long new_dirsize; + uint64 new_dsize; + uint64 old_dirsize; + uint64 new_dirsize; if (hashp->hctl->max_dsize != NO_MAX_DSIZE) return false; @@ -1716,10 +1716,10 @@ hash_corrupted(HTAB *hashp) /* calculate ceil(log base 2) of num */ int -my_log2(long num) +my_log2(uint64 num) { int i; - long limit; + uint64 limit; /* guard against too-large input, which would put us into infinite loop */ if (num > LONG_MAX / 2) @@ -1730,9 +1730,9 @@ my_log2(long num) return i; } -/* calculate first power of 2 >= num, bounded to what will fit in a long */ -static long -next_pow2_long(long num) +/* calculate first power of 2 >= num, bounded to what will fit in a uint64 */ +static uint64 +next_pow2_uint64(uint64 num) { /* my_log2's internal range check is sufficient */ return 1L << my_log2(num); @@ -1740,7 +1740,7 @@ next_pow2_long(long num) /* calculate first power of 2 >= num, bounded to what will fit in an int */ static int -next_pow2_int(long num) +next_pow2_int(uint64 num) { if (num > INT_MAX / 2) num = INT_MAX / 2; diff --git a/src/backend/utils/misc/sampling.c b/src/backend/utils/misc/sampling.c index 361c15614e..05d2fd581c 100644 --- a/src/backend/utils/misc/sampling.c +++ b/src/backend/utils/misc/sampling.c @@ -37,7 +37,7 @@ */ BlockNumber BlockSampler_Init(BlockSampler bs, BlockNumber nblocks, int samplesize, - long randseed) + uint64 randseed) { bs->N = nblocks; /* measured table size */ @@ -230,7 +230,7 @@ reservoir_get_next_S(ReservoirState rs, double t, int n) *---------- */ void -sampler_random_init_state(long seed, SamplerRandomState randstate) +sampler_random_init_state(uint64 seed, SamplerRandomState randstate) { randstate[0] = 0x330e; /* same as pg_erand48, but could be anything */ randstate[1] = (unsigned short) seed; diff --git a/src/backend/utils/sort/logtape.c b/src/backend/utils/sort/logtape.c index 4f78b55fba..01396ca230 100644 --- a/src/backend/utils/sort/logtape.c +++ b/src/backend/utils/sort/logtape.c @@ -93,9 +93,9 @@ */ typedef struct TapeBlockTrailer { - long prev; /* previous block on this tape, or -1 on first + int64 prev; /* previous block on this tape, or -1 on first * block */ - long next; /* next block on this tape, or # of valid + int64 next; /* next block on this tape, or # of valid * bytes on last block (if < 0) */ } TapeBlockTrailer; @@ -138,10 +138,10 @@ typedef struct LogicalTape * When concatenation of worker tape BufFiles is performed, an offset to * the first block in the unified BufFile space is applied during reads. */ - long firstBlockNumber; - long curBlockNumber; - long nextBlockNumber; - long offsetBlockNumber; + int64 firstBlockNumber; + int64 curBlockNumber; + int64 nextBlockNumber; + int64 offsetBlockNumber; /* * Buffer for current data block(s). @@ -173,9 +173,9 @@ struct LogicalTapeSet * blocks that are in unused holes between worker spaces following BufFile * concatenation. */ - long nBlocksAllocated; /* # of blocks allocated */ - long nBlocksWritten; /* # of blocks used in underlying file */ - long nHoleBlocks; /* # of "hole" blocks left */ + uint64 nBlocksAllocated; /* # of blocks allocated */ + uint64 nBlocksWritten; /* # of blocks used in underlying file */ + uint64 nHoleBlocks; /* # of "hole" blocks left */ /* * We store the numbers of recycled-and-available blocks in freeBlocks[]. @@ -186,19 +186,19 @@ struct LogicalTapeSet * LogicalTapeSetForgetFreeSpace(). */ bool forgetFreeSpace; /* are we remembering free blocks? */ - long *freeBlocks; /* resizable array holding minheap */ - long nFreeBlocks; /* # of currently free blocks */ - Size freeBlocksLen; /* current allocated length of freeBlocks[] */ + uint64 *freeBlocks; /* resizable array */ + int nFreeBlocks; /* # of currently free blocks */ + int freeBlocksLen; /* current allocated length of freeBlocks[] */ /* The array of logical tapes. */ int nTapes; /* # of logical tapes in set */ LogicalTape tapes[FLEXIBLE_ARRAY_MEMBER]; /* has nTapes nentries */ }; -static void ltsWriteBlock(LogicalTapeSet *lts, long blocknum, void *buffer); -static void ltsReadBlock(LogicalTapeSet *lts, long blocknum, void *buffer); -static long ltsGetFreeBlock(LogicalTapeSet *lts); -static void ltsReleaseBlock(LogicalTapeSet *lts, long blocknum); +static void ltsWriteBlock(LogicalTapeSet *lts, int64 blocknum, void *buffer); +static void ltsReadBlock(LogicalTapeSet *lts, int64 blocknum, void *buffer); +static int64 ltsGetFreeBlock(LogicalTapeSet *lts); +static void ltsReleaseBlock(LogicalTapeSet *lts, int64 blocknum); static void ltsConcatWorkerTapes(LogicalTapeSet *lts, TapeShare *shared, SharedFileSet *fileset); static void ltsInitReadBuffer(LogicalTapeSet *lts, LogicalTape *lt); @@ -210,7 +210,7 @@ static void ltsInitReadBuffer(LogicalTapeSet *lts, LogicalTape *lt); * No need for an error return convention; we ereport() on any error. */ static void -ltsWriteBlock(LogicalTapeSet *lts, long blocknum, void *buffer) +ltsWriteBlock(LogicalTapeSet *lts, int64 blocknum, void *buffer) { /* * BufFile does not support "holes", so if we're about to write a block @@ -258,7 +258,7 @@ ltsWriteBlock(LogicalTapeSet *lts, long blocknum, void *buffer) * module should never attempt to read a block it doesn't know is there. */ static void -ltsReadBlock(LogicalTapeSet *lts, long blocknum, void *buffer) +ltsReadBlock(LogicalTapeSet *lts, int64 blocknum, void *buffer) { if (BufFileSeekBlock(lts->pfile, blocknum) != 0 || BufFileRead(lts->pfile, buffer, BLCKSZ) != BLCKSZ) @@ -282,7 +282,7 @@ ltsReadFillBuffer(LogicalTapeSet *lts, LogicalTape *lt) do { char *thisbuf = lt->buffer + lt->nbytes; - long datablocknum = lt->nextBlockNumber; + int64 datablocknum = lt->nextBlockNumber; /* Fetch next block number */ if (datablocknum == -1L) @@ -344,7 +344,7 @@ parent_offset(unsigned long i) * Select the lowest currently unused block by taking the first element from * the freelist min heap. */ -static long +static int64 ltsGetFreeBlock(LogicalTapeSet *lts) { long *heap = lts->freeBlocks; @@ -400,7 +400,7 @@ ltsGetFreeBlock(LogicalTapeSet *lts) * Return a block# to the freelist. */ static void -ltsReleaseBlock(LogicalTapeSet *lts, long blocknum) +ltsReleaseBlock(LogicalTapeSet *lts, int64 blocknum) { long *heap; unsigned long pos; @@ -424,8 +424,8 @@ ltsReleaseBlock(LogicalTapeSet *lts, long blocknum) return; lts->freeBlocksLen *= 2; - lts->freeBlocks = (long *) repalloc(lts->freeBlocks, - lts->freeBlocksLen * sizeof(long)); + lts->freeBlocks = (uint64 *) repalloc(lts->freeBlocks, + lts->freeBlocksLen * sizeof(int64)); } heap = lts->freeBlocks; @@ -460,8 +460,8 @@ ltsConcatWorkerTapes(LogicalTapeSet *lts, TapeShare *shared, SharedFileSet *fileset) { LogicalTape *lt = NULL; - long tapeblocks = 0L; - long nphysicalblocks = 0L; + int64 tapeblocks = 0L; + int64 nphysicalblocks = 0L; int i; /* Should have at least one worker tape, plus leader's tape */ @@ -593,7 +593,7 @@ LogicalTapeSetCreate(int ntapes, TapeShare *shared, SharedFileSet *fileset, lts->nHoleBlocks = 0L; lts->forgetFreeSpace = false; lts->freeBlocksLen = 32; /* reasonable initial guess */ - lts->freeBlocks = (long *) palloc(lts->freeBlocksLen * sizeof(long)); + lts->freeBlocks = (uint64 *) palloc(lts->freeBlocksLen * sizeof(uint64)); lts->nFreeBlocks = 0; lts->nTapes = ntapes; @@ -719,7 +719,7 @@ LogicalTapeWrite(LogicalTapeSet *lts, int tapenum, if (lt->pos >= TapeBlockPayloadSize) { /* Buffer full, dump it out */ - long nextBlockNumber; + int64 nextBlockNumber; if (!lt->dirty) { @@ -1048,7 +1048,7 @@ LogicalTapeBackspace(LogicalTapeSet *lts, int tapenum, size_t size) seekpos = (size_t) lt->pos; /* part within this block */ while (size > seekpos) { - long prev = TapeBlockGetTrailer(lt->buffer)->prev; + int64 prev = TapeBlockGetTrailer(lt->buffer)->prev; if (prev == -1L) { @@ -1093,7 +1093,7 @@ LogicalTapeBackspace(LogicalTapeSet *lts, int tapenum, size_t size) */ void LogicalTapeSeek(LogicalTapeSet *lts, int tapenum, - long blocknum, int offset) + int64 blocknum, int offset) { LogicalTape *lt; @@ -1127,7 +1127,7 @@ LogicalTapeSeek(LogicalTapeSet *lts, int tapenum, */ void LogicalTapeTell(LogicalTapeSet *lts, int tapenum, - long *blocknum, int *offset) + int64 *blocknum, int *offset) { LogicalTape *lt; @@ -1149,7 +1149,7 @@ LogicalTapeTell(LogicalTapeSet *lts, int tapenum, /* * Obtain total disk space currently used by a LogicalTapeSet, in blocks. */ -long +int64 LogicalTapeSetBlocks(LogicalTapeSet *lts) { return lts->nBlocksAllocated - lts->nHoleBlocks; diff --git a/src/bin/pg_basebackup/receivelog.c b/src/bin/pg_basebackup/receivelog.c index 62a342f77c..488f12dc6f 100644 --- a/src/bin/pg_basebackup/receivelog.c +++ b/src/bin/pg_basebackup/receivelog.c @@ -37,8 +37,8 @@ static bool still_sending = true; /* feedback still needs to be sent? */ static PGresult *HandleCopyStream(PGconn *conn, StreamCtl *stream, XLogRecPtr *stoppos); -static int CopyStreamPoll(PGconn *conn, long timeout_ms, pgsocket stop_socket); -static int CopyStreamReceive(PGconn *conn, long timeout, pgsocket stop_socket, +static int CopyStreamPoll(PGconn *conn, int64 timeout_ms, pgsocket stop_socket); +static int CopyStreamReceive(PGconn *conn, int64 timeout, pgsocket stop_socket, char **buffer); static bool ProcessKeepaliveMsg(PGconn *conn, StreamCtl *stream, char *copybuf, int len, XLogRecPtr blockpos, TimestampTz *last_status); @@ -48,7 +48,7 @@ static PGresult *HandleEndOfCopyStream(PGconn *conn, StreamCtl *stream, char *co XLogRecPtr blockpos, XLogRecPtr *stoppos); static bool CheckCopyStreamStop(PGconn *conn, StreamCtl *stream, XLogRecPtr blockpos, XLogRecPtr *stoppos); -static long CalculateCopyStreamSleeptime(TimestampTz now, int standby_message_timeout, +static int64 CalculateCopyStreamSleeptime(TimestampTz now, int standby_message_timeout, TimestampTz last_status); static bool ReadEndOfStreamingResult(PGresult *res, XLogRecPtr *startpos, @@ -742,7 +742,7 @@ HandleCopyStream(PGconn *conn, StreamCtl *stream, { int r; TimestampTz now; - long sleeptime; + int64 sleeptime; /* * Check if we should continue streaming, or abort at this point. @@ -858,7 +858,7 @@ error: * or interrupted by signal or stop_socket input, and -1 on an error. */ static int -CopyStreamPoll(PGconn *conn, long timeout_ms, pgsocket stop_socket) +CopyStreamPoll(PGconn *conn, int64 timeout_ms, pgsocket stop_socket) { int ret; fd_set input_mask; @@ -920,7 +920,7 @@ CopyStreamPoll(PGconn *conn, long timeout_ms, pgsocket stop_socket) * -1 on error. -2 if the server ended the COPY. */ static int -CopyStreamReceive(PGconn *conn, long timeout, pgsocket stop_socket, +CopyStreamReceive(PGconn *conn, int64 timeout, pgsocket stop_socket, char **buffer) { char *copybuf = NULL; @@ -1228,12 +1228,12 @@ CheckCopyStreamStop(PGconn *conn, StreamCtl *stream, XLogRecPtr blockpos, /* * Calculate how long send/receive loops should sleep */ -static long +static int64 CalculateCopyStreamSleeptime(TimestampTz now, int standby_message_timeout, TimestampTz last_status) { TimestampTz status_targettime = 0; - long sleeptime; + int64 sleeptime; if (standby_message_timeout && still_sending) status_targettime = last_status + @@ -1241,7 +1241,7 @@ CalculateCopyStreamSleeptime(TimestampTz now, int standby_message_timeout, if (status_targettime > 0) { - long secs; + int64 secs; int usecs; feTimestampDifference(now, diff --git a/src/include/executor/spi.h b/src/include/executor/spi.h index 06de20ada5..e54c968aca 100644 --- a/src/include/executor/spi.h +++ b/src/include/executor/spi.h @@ -84,24 +84,24 @@ extern PGDLLIMPORT int SPI_result; extern int SPI_connect(void); extern int SPI_connect_ext(int options); extern int SPI_finish(void); -extern int SPI_execute(const char *src, bool read_only, long tcount); +extern int SPI_execute(const char *src, bool read_only, int64 tcount); extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, - bool read_only, long tcount); + bool read_only, int64 tcount); extern int SPI_execute_plan_with_paramlist(SPIPlanPtr plan, ParamListInfo params, - bool read_only, long tcount); -extern int SPI_exec(const char *src, long tcount); + bool read_only, int64 tcount); +extern int SPI_exec(const char *src, int64 tcount); extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, - long tcount); + int64 tcount); extern int SPI_execute_snapshot(SPIPlanPtr plan, Datum *Values, const char *Nulls, Snapshot snapshot, Snapshot crosscheck_snapshot, - bool read_only, bool fire_triggers, long tcount); + bool read_only, bool fire_triggers, int64 tcount); extern int SPI_execute_with_args(const char *src, int nargs, Oid *argtypes, Datum *Values, const char *Nulls, - bool read_only, long tcount); + bool read_only, int64 tcount); extern SPIPlanPtr SPI_prepare(const char *src, int nargs, Oid *argtypes); extern SPIPlanPtr SPI_prepare_cursor(const char *src, int nargs, Oid *argtypes, int cursorOptions); @@ -151,10 +151,10 @@ extern Portal SPI_cursor_open_with_args(const char *name, extern Portal SPI_cursor_open_with_paramlist(const char *name, SPIPlanPtr plan, ParamListInfo params, bool read_only); extern Portal SPI_cursor_find(const char *name); -extern void SPI_cursor_fetch(Portal portal, bool forward, long count); -extern void SPI_cursor_move(Portal portal, bool forward, long count); -extern void SPI_scroll_cursor_fetch(Portal, FetchDirection direction, long count); -extern void SPI_scroll_cursor_move(Portal, FetchDirection direction, long count); +extern void SPI_cursor_fetch(Portal portal, bool forward, int64 count); +extern void SPI_cursor_move(Portal portal, bool forward, int64 count); +extern void SPI_scroll_cursor_fetch(Portal, FetchDirection direction, int64 count); +extern void SPI_scroll_cursor_move(Portal, FetchDirection direction, int64 count); extern void SPI_cursor_close(Portal portal); extern int SPI_register_relation(EphemeralNamedRelation enr); diff --git a/src/include/pgtime.h b/src/include/pgtime.h index 0fc76d0e60..3d2fdedd89 100644 --- a/src/include/pgtime.h +++ b/src/include/pgtime.h @@ -33,7 +33,7 @@ struct pg_tm int tm_wday; int tm_yday; int tm_isdst; - long int tm_gmtoff; + int64 tm_gmtoff; const char *tm_zone; }; @@ -48,18 +48,18 @@ typedef struct pg_tzenum pg_tzenum; extern struct pg_tm *pg_localtime(const pg_time_t *timep, const pg_tz *tz); extern struct pg_tm *pg_gmtime(const pg_time_t *timep); extern int pg_next_dst_boundary(const pg_time_t *timep, - long int *before_gmtoff, + int64 *before_gmtoff, int *before_isdst, pg_time_t *boundary, - long int *after_gmtoff, + int64 *after_gmtoff, int *after_isdst, const pg_tz *tz); extern bool pg_interpret_timezone_abbrev(const char *abbrev, const pg_time_t *timep, - long int *gmtoff, + int64 *gmtoff, int *isdst, const pg_tz *tz); -extern bool pg_get_timezone_offset(const pg_tz *tz, long int *gmtoff); +extern bool pg_get_timezone_offset(const pg_tz *tz, int64 *gmtoff); extern const char *pg_get_timezone_name(pg_tz *tz); extern bool pg_tz_acceptable(pg_tz *tz); @@ -75,7 +75,7 @@ extern pg_tz *log_timezone; extern void pg_timezone_initialize(void); extern pg_tz *pg_tzset(const char *tzname); -extern pg_tz *pg_tzset_offset(long gmtoffset); +extern pg_tz *pg_tzset_offset(int64 gmtoffset); extern pg_tzenum *pg_tzenumerate_start(void); extern pg_tz *pg_tzenumerate_next(pg_tzenum *dir); diff --git a/src/include/portability/instr_time.h b/src/include/portability/instr_time.h index d6459327cc..0a51120fc4 100644 --- a/src/include/portability/instr_time.h +++ b/src/include/portability/instr_time.h @@ -136,7 +136,7 @@ typedef struct timespec instr_time; (((double) (t).tv_sec) + ((double) (t).tv_nsec) / 1000000000.0) #define INSTR_TIME_GET_MILLISEC(t) \ - (((double) (t).tv_sec * 1000.0) + ((double) (t).tv_nsec) / 1000000.0) + (((int64) (t).tv_sec * 1000.0) + ((int64) (t).tv_nsec) / 1000000.0) #define INSTR_TIME_GET_MICROSEC(t) \ (((uint64) (t).tv_sec * (uint64) 1000000) + (uint64) ((t).tv_nsec / 1000)) diff --git a/src/include/storage/buffile.h b/src/include/storage/buffile.h index 60433f35b4..7178247396 100644 --- a/src/include/storage/buffile.h +++ b/src/include/storage/buffile.h @@ -42,9 +42,9 @@ extern size_t BufFileRead(BufFile *file, void *ptr, size_t size); extern size_t BufFileWrite(BufFile *file, void *ptr, size_t size); extern int BufFileSeek(BufFile *file, int fileno, off_t offset, int whence); extern void BufFileTell(BufFile *file, int *fileno, off_t *offset); -extern int BufFileSeekBlock(BufFile *file, long blknum); +extern int BufFileSeekBlock(BufFile *file, uint64 blknum); extern int64 BufFileSize(BufFile *file); -extern long BufFileAppend(BufFile *target, BufFile *source); +extern uint64 BufFileAppend(BufFile *target, BufFile *source); extern BufFile *BufFileCreateShared(SharedFileSet *fileset, const char *name); extern void BufFileExportShared(BufFile *file); diff --git a/src/include/storage/condition_variable.h b/src/include/storage/condition_variable.h index bfe5c89b54..cb245c09c5 100644 --- a/src/include/storage/condition_variable.h +++ b/src/include/storage/condition_variable.h @@ -43,7 +43,7 @@ extern void ConditionVariableInit(ConditionVariable *cv); * the condition variable. */ extern void ConditionVariableSleep(ConditionVariable *cv, uint32 wait_event_info); -extern bool ConditionVariableTimedSleep(ConditionVariable *cv, long timeout, +extern bool ConditionVariableTimedSleep(ConditionVariable *cv, int64 timeout, uint32 wait_event_info); extern void ConditionVariableCancelSleep(void); diff --git a/src/include/storage/latch.h b/src/include/storage/latch.h index 46ae56cae3..3c013ca860 100644 --- a/src/include/storage/latch.h +++ b/src/include/storage/latch.h @@ -169,13 +169,13 @@ extern int AddWaitEventToSet(WaitEventSet *set, uint32 events, pgsocket fd, Latch *latch, void *user_data); extern void ModifyWaitEvent(WaitEventSet *set, int pos, uint32 events, Latch *latch); -extern int WaitEventSetWait(WaitEventSet *set, long timeout, +extern int WaitEventSetWait(WaitEventSet *set, int64 timeout, WaitEvent *occurred_events, int nevents, uint32 wait_event_info); -extern int WaitLatch(Latch *latch, int wakeEvents, long timeout, +extern int WaitLatch(Latch *latch, int wakeEvents, int64 timeout, uint32 wait_event_info); extern int WaitLatchOrSocket(Latch *latch, int wakeEvents, - pgsocket sock, long timeout, uint32 wait_event_info); + pgsocket sock, int64 timeout, uint32 wait_event_info); /* * Unix implementation uses SIGUSR1 for inter-process signaling. diff --git a/src/include/storage/shmem.h b/src/include/storage/shmem.h index 0c1af89206..4b75f33be9 100644 --- a/src/include/storage/shmem.h +++ b/src/include/storage/shmem.h @@ -39,7 +39,7 @@ extern void *ShmemAllocNoError(Size size); extern void *ShmemAllocUnlocked(Size size); extern bool ShmemAddrIsValid(const void *addr); extern void InitShmemIndex(void); -extern HTAB *ShmemInitHash(const char *name, long init_size, long max_size, +extern HTAB *ShmemInitHash(const char *name, uint64 init_size, uint64 max_size, HASHCTL *infoP, int hash_flags); extern void *ShmemInitStruct(const char *name, Size size, bool *foundPtr); extern Size add_size(Size s1, Size s2); diff --git a/src/include/tcop/pquery.h b/src/include/tcop/pquery.h index 4ad6324e2d..367c31cabb 100644 --- a/src/include/tcop/pquery.h +++ b/src/include/tcop/pquery.h @@ -33,13 +33,13 @@ extern void PortalStart(Portal portal, ParamListInfo params, extern void PortalSetResultFormat(Portal portal, int nFormats, int16 *formats); -extern bool PortalRun(Portal portal, long count, bool isTopLevel, +extern bool PortalRun(Portal portal, int64 count, bool isTopLevel, bool run_once, DestReceiver *dest, DestReceiver *altdest, char *completionTag); extern uint64 PortalRunFetch(Portal portal, FetchDirection fdirection, - long count, + int64 count, DestReceiver *dest); #endif /* PQUERY_H */ diff --git a/src/include/utils/dynahash.h b/src/include/utils/dynahash.h index 768b952176..0c75534897 100644 --- a/src/include/utils/dynahash.h +++ b/src/include/utils/dynahash.h @@ -14,6 +14,6 @@ #ifndef DYNAHASH_H #define DYNAHASH_H -extern int my_log2(long num); +extern int my_log2(uint64 num); #endif /* DYNAHASH_H */ diff --git a/src/include/utils/hsearch.h b/src/include/utils/hsearch.h index f1deb9beab..dd0cd98962 100644 --- a/src/include/utils/hsearch.h +++ b/src/include/utils/hsearch.h @@ -64,11 +64,11 @@ typedef struct HTAB HTAB; /* Only those fields indicated by hash_flags need be set */ typedef struct HASHCTL { - long num_partitions; /* # partitions (must be power of 2) */ - long ssize; /* segment size */ - long dsize; /* (initial) directory size */ - long max_dsize; /* limit to dsize if dir size is limited */ - long ffactor; /* fill factor */ + uint64 num_partitions; /* # partitions (must be power of 2) */ + uint64 ssize; /* segment size */ + uint64 dsize; /* (initial) directory size */ + uint64 max_dsize; /* limit to dsize if dir size is limited */ + uint64 ffactor; /* fill factor */ Size keysize; /* hash key length in bytes */ Size entrysize; /* total user element size in bytes */ HashValueFunc hash; /* hash function */ @@ -123,7 +123,7 @@ typedef struct * string_hash, tag_hash, uint32_hash, or oid_hash. Just set HASH_BLOBS or * not. Use HASH_FUNCTION only when you want something other than those. */ -extern HTAB *hash_create(const char *tabname, long nelem, +extern HTAB *hash_create(const char *tabname, uint64 nelem, HASHCTL *info, int flags); extern void hash_destroy(HTAB *hashp); extern void hash_stats(const char *where, HTAB *hashp); @@ -135,13 +135,13 @@ extern void *hash_search_with_hash_value(HTAB *hashp, const void *keyPtr, bool *foundPtr); extern bool hash_update_hash_key(HTAB *hashp, void *existingEntry, const void *newKeyPtr); -extern long hash_get_num_entries(HTAB *hashp); +extern uint64 hash_get_num_entries(HTAB *hashp); extern void hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp); extern void *hash_seq_search(HASH_SEQ_STATUS *status); extern void hash_seq_term(HASH_SEQ_STATUS *status); extern void hash_freeze(HTAB *hashp); -extern Size hash_estimate_size(long num_entries, Size entrysize); -extern long hash_select_dirsize(long num_entries); +extern Size hash_estimate_size(uint64 num_entries, Size entrysize); +extern uint64 hash_select_dirsize(uint64 num_entries); extern Size hash_get_shared_size(HASHCTL *info, int flags); extern void AtEOXact_HashTables(bool isCommit); extern void AtEOSubXact_HashTables(bool isCommit, int nestDepth); diff --git a/src/include/utils/sampling.h b/src/include/utils/sampling.h index 74646846b2..cbcbeb6fd7 100644 --- a/src/include/utils/sampling.h +++ b/src/include/utils/sampling.h @@ -19,7 +19,7 @@ /* Random generator for sampling code */ typedef unsigned short SamplerRandomState[3]; -extern void sampler_random_init_state(long seed, +extern void sampler_random_init_state(uint64 seed, SamplerRandomState randstate); extern double sampler_random_fract(SamplerRandomState randstate); @@ -38,7 +38,7 @@ typedef struct typedef BlockSamplerData *BlockSampler; extern BlockNumber BlockSampler_Init(BlockSampler bs, BlockNumber nblocks, - int samplesize, long randseed); + int samplesize, uint64 randseed); extern bool BlockSampler_HasMore(BlockSampler bs); extern BlockNumber BlockSampler_Next(BlockSampler bs); diff --git a/src/include/utils/timestamp.h b/src/include/utils/timestamp.h index 03a1de569f..78fdf05583 100644 --- a/src/include/utils/timestamp.h +++ b/src/include/utils/timestamp.h @@ -71,7 +71,7 @@ extern TimestampTz GetCurrentTimestamp(void); extern TimestampTz GetSQLCurrentTimestamp(int32 typmod); extern Timestamp GetSQLLocalTimestamp(int32 typmod); extern void TimestampDifference(TimestampTz start_time, TimestampTz stop_time, - long *secs, int *microsecs); + int64 *secs, int *microsecs); extern bool TimestampDifferenceExceeds(TimestampTz start_time, TimestampTz stop_time, int msec); diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c index 5acf604f63..3ce5848247 100644 --- a/src/pl/plpgsql/src/pl_exec.c +++ b/src/pl/plpgsql/src/pl_exec.c @@ -358,7 +358,7 @@ static Datum exec_eval_expr(PLpgSQL_execstate *estate, Oid *rettype, int32 *rettypmod); static int exec_run_select(PLpgSQL_execstate *estate, - PLpgSQL_expr *expr, long maxtuples, Portal *portalP); + PLpgSQL_expr *expr, uint64 maxtuples, Portal *portalP); static int exec_for_query(PLpgSQL_execstate *estate, PLpgSQL_stmt_forq *stmt, Portal portal, bool prefetch_ok); static ParamListInfo setup_param_list(PLpgSQL_execstate *estate, @@ -4085,7 +4085,7 @@ exec_stmt_execsql(PLpgSQL_execstate *estate, PLpgSQL_stmt_execsql *stmt) { ParamListInfo paramLI; - long tcount; + int64 tcount; int rc; PLpgSQL_expr *expr = stmt->sqlstmt; int too_many_rows_level = 0; @@ -4683,7 +4683,7 @@ static int exec_stmt_fetch(PLpgSQL_execstate *estate, PLpgSQL_stmt_fetch *stmt) { PLpgSQL_var *curvar; - long how_many = stmt->how_many; + int64 how_many = stmt->how_many; SPITupleTable *tuptab; Portal portal; char *curname; @@ -5831,7 +5831,7 @@ exec_eval_expr(PLpgSQL_execstate *estate, */ static int exec_run_select(PLpgSQL_execstate *estate, - PLpgSQL_expr *expr, long maxtuples, Portal *portalP) + PLpgSQL_expr *expr, uint64 maxtuples, Portal *portalP) { ParamListInfo paramLI; int rc; diff --git a/src/pl/plpgsql/src/plpgsql.h b/src/pl/plpgsql/src/plpgsql.h index 69df3306fd..0cea7270cf 100644 --- a/src/pl/plpgsql/src/plpgsql.h +++ b/src/pl/plpgsql/src/plpgsql.h @@ -798,7 +798,7 @@ typedef struct PLpgSQL_stmt_fetch PLpgSQL_variable *target; /* target (record or row) */ int curvar; /* cursor variable to fetch from */ FetchDirection direction; /* fetch direction */ - long how_many; /* count, if constant (expr is NULL) */ + int64 how_many; /* count, if constant (expr is NULL) */ PLpgSQL_expr *expr; /* count, if expression */ bool is_move; /* is this a fetch or move? */ bool returns_multiple_rows; /* can return more than one row? */ @@ -1027,7 +1027,7 @@ typedef struct PLpgSQL_function /* these fields change when the function is used */ struct PLpgSQL_execstate *cur_estate; - unsigned long use_count; + uint64 use_count; } PLpgSQL_function; /* diff --git a/src/pl/plpython/plpy_spi.c b/src/pl/plpython/plpy_spi.c index 99c1b4f28f..91079f4c99 100644 --- a/src/pl/plpython/plpy_spi.c +++ b/src/pl/plpython/plpy_spi.c @@ -25,7 +25,7 @@ #include "utils/memutils.h" #include "utils/syscache.h" -static PyObject *PLy_spi_execute_query(char *query, long limit); +static PyObject *PLy_spi_execute_query(char *query, uint64 limit); static PyObject *PLy_spi_execute_fetch_result(SPITupleTable *tuptable, uint64 rows, int status); static void PLy_spi_exception_set(PyObject *excclass, ErrorData *edata); @@ -158,7 +158,7 @@ PLy_spi_execute(PyObject *self, PyObject *args) char *query; PyObject *plan; PyObject *list = NULL; - long limit = 0; + uint64 limit = 0; if (PyArg_ParseTuple(args, "s|l", &query, &limit)) return PLy_spi_execute_query(query, limit); @@ -174,7 +174,7 @@ PLy_spi_execute(PyObject *self, PyObject *args) } PyObject * -PLy_spi_execute_plan(PyObject *ob, PyObject *list, long limit) +PLy_spi_execute_plan(PyObject *ob, PyObject *list, uint64 limit) { volatile int nargs; int i, @@ -305,7 +305,7 @@ PLy_spi_execute_plan(PyObject *ob, PyObject *list, long limit) } static PyObject * -PLy_spi_execute_query(char *query, long limit) +PLy_spi_execute_query(char *query, uint64 limit) { int rv; volatile MemoryContext oldcontext; diff --git a/src/pl/plpython/plpy_spi.h b/src/pl/plpython/plpy_spi.h index a5e2e60da7..66e8a43aae 100644 --- a/src/pl/plpython/plpy_spi.h +++ b/src/pl/plpython/plpy_spi.h @@ -10,7 +10,7 @@ extern PyObject *PLy_spi_prepare(PyObject *self, PyObject *args); extern PyObject *PLy_spi_execute(PyObject *self, PyObject *args); -extern PyObject *PLy_spi_execute_plan(PyObject *ob, PyObject *list, long limit); +extern PyObject *PLy_spi_execute_plan(PyObject *ob, PyObject *list, uint64 limit); typedef struct PLyExceptionEntry { diff --git a/src/timezone/localtime.c b/src/timezone/localtime.c index 333f27300a..926c677c41 100644 --- a/src/timezone/localtime.c +++ b/src/timezone/localtime.c @@ -1623,10 +1623,10 @@ increment_overflow_time(pg_time_t *tp, int32 j) */ int pg_next_dst_boundary(const pg_time_t *timep, - long int *before_gmtoff, + int64 *before_gmtoff, int *before_isdst, pg_time_t *boundary, - long int *after_gmtoff, + int64 *after_gmtoff, int *after_isdst, const pg_tz *tz) { @@ -1771,7 +1771,7 @@ pg_next_dst_boundary(const pg_time_t *timep, bool pg_interpret_timezone_abbrev(const char *abbrev, const pg_time_t *timep, - long int *gmtoff, + int64 *gmtoff, int *isdst, const pg_tz *tz) { @@ -1863,7 +1863,7 @@ pg_interpret_timezone_abbrev(const char *abbrev, * into *gmtoff and return true, else return false. */ bool -pg_get_timezone_offset(const pg_tz *tz, long int *gmtoff) +pg_get_timezone_offset(const pg_tz *tz, int64 *gmtoff) { /* * The zone could have more than one ttinfo, if it's historically used --------------2.24.1--
>From c51fe40fcb6841a888fe3f5311845486180b92d1 Mon Sep 17 00:00:00 2001 From: David Fetter <da...@fetter.org> Date: Fri, 31 Jan 2020 07:08:48 -0800 Subject: [PATCH v6 2/3] Spread bitutils into hashing To: hackers MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="------------2.24.1" This is a multi-part message in MIME format. --------------2.24.1 Content-Type: text/plain; charset=UTF-8; format=fixed Content-Transfer-Encoding: 8bit diff --git a/src/backend/access/hash/hashpage.c b/src/backend/access/hash/hashpage.c index 55d85644a4..29dca21be2 100644 --- a/src/backend/access/hash/hashpage.c +++ b/src/backend/access/hash/hashpage.c @@ -30,6 +30,7 @@ #include "access/hash.h" #include "access/hash_xlog.h" +#include "port/pg_bitutils.h" #include "miscadmin.h" #include "storage/lmgr.h" #include "storage/predicate.h" @@ -502,7 +503,6 @@ _hash_init_metabuffer(Buffer buf, double num_tuples, RegProcedure procid, double dnumbuckets; uint32 num_buckets; uint32 spare_index; - uint32 i; /* * Choose the number of initial bucket pages to match the fill factor @@ -543,14 +543,8 @@ _hash_init_metabuffer(Buffer buf, double num_tuples, RegProcedure procid, metap->hashm_ffactor = ffactor; metap->hashm_bsize = HashGetMaxBitmapSize(page); /* find largest bitmap array size that will fit in page size */ - for (i = _hash_log2(metap->hashm_bsize); i > 0; --i) - { - if ((1 << i) <= metap->hashm_bsize) - break; - } - Assert(i > 0); - metap->hashm_bmsize = 1 << i; - metap->hashm_bmshift = i + BYTE_TO_BIT; + metap->hashm_bmsize = 1 << pg_leftmost_one_pos32(metap->hashm_bsize); + metap->hashm_bmshift = pg_leftmost_one_pos32(metap->hashm_bsize) + BYTE_TO_BIT; Assert((1 << BMPG_SHIFT(metap)) == (BMPG_MASK(metap) + 1)); /* @@ -570,7 +564,7 @@ _hash_init_metabuffer(Buffer buf, double num_tuples, RegProcedure procid, * Set highmask as next immediate ((2 ^ x) - 1), which should be * sufficient to cover num_buckets. */ - metap->hashm_highmask = (1 << (_hash_log2(num_buckets + 1))) - 1; + metap->hashm_highmask = next_power_of_2_32(num_buckets + 1) - 1; metap->hashm_lowmask = (metap->hashm_highmask >> 1); MemSet(metap->hashm_spares, 0, sizeof(metap->hashm_spares)); @@ -657,13 +651,12 @@ restart_expand: * Can't split anymore if maxbucket has reached its maximum possible * value. * - * Ideally we'd allow bucket numbers up to UINT_MAX-1 (no higher because - * the calculation maxbucket+1 mustn't overflow). Currently we restrict - * to half that because of overflow looping in _hash_log2() and - * insufficient space in hashm_spares[]. It's moot anyway because an - * index with 2^32 buckets would certainly overflow BlockNumber and hence - * _hash_alloc_buckets() would fail, but if we supported buckets smaller - * than a disk block then this would be an independent constraint. + * Ideally we'd allow bucket numbers up to UINT_MAX-1 (no higher because the + * calculation maxbucket+1 mustn't overflow). Currently we restrict to half + * that because of insufficient space in hashm_spares[]. It's moot anyway + * because an index with 2^32 buckets would certainly overflow BlockNumber + * and hence _hash_alloc_buckets() would fail, but if we supported buckets + * smaller than a disk block then this would be an independent constraint. * * If you change this, see also the maximum initial number of buckets in * _hash_init(). diff --git a/src/backend/access/hash/hashsort.c b/src/backend/access/hash/hashsort.c index 9cb41d62e7..322379788c 100644 --- a/src/backend/access/hash/hashsort.c +++ b/src/backend/access/hash/hashsort.c @@ -27,6 +27,7 @@ #include "access/hash.h" #include "commands/progress.h" +#include "port/pg_bitutils.h" #include "miscadmin.h" #include "pgstat.h" #include "utils/tuplesort.h" @@ -69,7 +70,7 @@ _h_spoolinit(Relation heap, Relation index, uint32 num_buckets) * NOTE : This hash mask calculation should be in sync with similar * calculation in _hash_init_metabuffer. */ - hspool->high_mask = (((uint32) 1) << _hash_log2(num_buckets + 1)) - 1; + hspool->high_mask = next_power_of_2_32(num_buckets + 1) - 1; hspool->low_mask = (hspool->high_mask >> 1); hspool->max_buckets = num_buckets - 1; diff --git a/src/backend/access/hash/hashutil.c b/src/backend/access/hash/hashutil.c index 9efc8016bc..738572ca40 100644 --- a/src/backend/access/hash/hashutil.c +++ b/src/backend/access/hash/hashutil.c @@ -17,6 +17,7 @@ #include "access/hash.h" #include "access/reloptions.h" #include "access/relscan.h" +#include "port/pg_bitutils.h" #include "storage/buf_internals.h" #include "utils/lsyscache.h" #include "utils/rel.h" @@ -134,21 +135,6 @@ _hash_hashkey2bucket(uint32 hashkey, uint32 maxbucket, return bucket; } -/* - * _hash_log2 -- returns ceil(lg2(num)) - */ -uint32 -_hash_log2(uint32 num) -{ - uint32 i, - limit; - - limit = 1; - for (i = 0; limit < num; limit <<= 1, i++) - ; - return i; -} - /* * _hash_spareindex -- returns spare index / global splitpoint phase of the * bucket @@ -159,7 +145,7 @@ _hash_spareindex(uint32 num_bucket) uint32 splitpoint_group; uint32 splitpoint_phases; - splitpoint_group = _hash_log2(num_bucket); + splitpoint_group = ceil_log2_32(num_bucket); if (splitpoint_group < HASH_SPLITPOINT_GROUPS_WITH_ONE_PHASE) return splitpoint_group; diff --git a/src/backend/utils/hash/dynahash.c b/src/backend/utils/hash/dynahash.c index 7769c79861..2409a413d2 100644 --- a/src/backend/utils/hash/dynahash.c +++ b/src/backend/utils/hash/dynahash.c @@ -87,6 +87,7 @@ #include "access/xact.h" #include "common/hashfn.h" +#include "port/pg_bitutils.h" #include "storage/shmem.h" #include "storage/spin.h" #include "utils/dynahash.h" @@ -1718,16 +1719,11 @@ hash_corrupted(HTAB *hashp) int my_log2(uint64 num) { - int i; - uint64 limit; - /* guard against too-large input, which would put us into infinite loop */ if (num > LONG_MAX / 2) num = LONG_MAX / 2; - for (i = 0, limit = 1; limit < num; i++, limit <<= 1) - ; - return i; + return ceil_log2_64(num); } /* calculate first power of 2 >= num, bounded to what will fit in a uint64 */ diff --git a/src/include/access/hash.h b/src/include/access/hash.h index 2707e1924b..b6407813e7 100644 --- a/src/include/access/hash.h +++ b/src/include/access/hash.h @@ -450,7 +450,6 @@ extern uint32 _hash_datum2hashkey(Relation rel, Datum key); extern uint32 _hash_datum2hashkey_type(Relation rel, Datum key, Oid keytype); extern Bucket _hash_hashkey2bucket(uint32 hashkey, uint32 maxbucket, uint32 highmask, uint32 lowmask); -extern uint32 _hash_log2(uint32 num); extern uint32 _hash_spareindex(uint32 num_bucket); extern uint32 _hash_get_totalbuckets(uint32 splitpoint_phase); extern void _hash_checkpage(Relation rel, Buffer buf, int flags); diff --git a/src/include/lib/simplehash.h b/src/include/lib/simplehash.h index 5a6783f653..1a35a054d8 100644 --- a/src/include/lib/simplehash.h +++ b/src/include/lib/simplehash.h @@ -57,6 +57,8 @@ * backwards, unless they're empty or already at their optimal position. */ +#include "port/pg_bitutils.h" + /* helpers */ #define SH_MAKE_PREFIX(a) CppConcat(a,_) #define SH_MAKE_NAME(name) SH_MAKE_NAME_(SH_MAKE_PREFIX(SH_PREFIX),name) @@ -215,27 +217,6 @@ SH_SCOPE void SH_STAT(SH_TYPE * tb); #ifndef SIMPLEHASH_H #define SIMPLEHASH_H -/* FIXME: can we move these to a central location? */ - -/* calculate ceil(log base 2) of num */ -static inline uint64 -sh_log2(uint64 num) -{ - int i; - uint64 limit; - - for (i = 0, limit = 1; limit < num; i++, limit <<= 1) - ; - return i; -} - -/* calculate first power of 2 >= num */ -static inline uint64 -sh_pow2(uint64 num) -{ - return ((uint64) 1) << sh_log2(num); -} - #ifdef FRONTEND #define sh_error(...) pg_log_error(__VA_ARGS__) #define sh_log(...) pg_log_info(__VA_ARGS__) @@ -259,7 +240,7 @@ SH_COMPUTE_PARAMETERS(SH_TYPE * tb, uint32 newsize) size = Max(newsize, 2); /* round up size to the next power of 2, that's how bucketing works */ - size = sh_pow2(size); + size = next_power_of_2_64(size); Assert(size <= SH_MAX_SIZE); /* @@ -434,7 +415,7 @@ SH_GROW(SH_TYPE * tb, uint32 newsize) uint32 startelem = 0; uint32 copyelem; - Assert(oldsize == sh_pow2(oldsize)); + Assert(oldsize == next_power_of_2_64(oldsize)); Assert(oldsize != SH_MAX_SIZE); Assert(oldsize < newsize); diff --git a/src/include/port/pg_bitutils.h b/src/include/port/pg_bitutils.h index 498e532308..88a9ea5b7f 100644 --- a/src/include/port/pg_bitutils.h +++ b/src/include/port/pg_bitutils.h @@ -20,19 +20,18 @@ extern PGDLLIMPORT const uint8 pg_number_of_ones[256]; /* * pg_leftmost_one_pos32 * Returns the position of the most significant set bit in "word", - * measured from the least significant bit. word must not be 0. + * measured from the least significant bit. */ static inline int pg_leftmost_one_pos32(uint32 word) { #ifdef HAVE__BUILTIN_CLZ - Assert(word != 0); - - return 31 - __builtin_clz(word); + return word ? 31 - __builtin_clz(word) : 0; #else int shift = 32 - 8; - Assert(word != 0); + if (word == 0) + return 0; while ((word >> shift) == 0) shift -= 8; @@ -49,19 +48,18 @@ static inline int pg_leftmost_one_pos64(uint64 word) { #ifdef HAVE__BUILTIN_CLZ - Assert(word != 0); - #if defined(HAVE_LONG_INT_64) - return 63 - __builtin_clzl(word); + return word ? 63 - __builtin_clzl(word) : 0; #elif defined(HAVE_LONG_LONG_INT_64) - return 63 - __builtin_clzll(word); + return word ? 63 - __builtin_clzll(word) : 0; #else #error must have a working 64-bit integer datatype #endif #else /* !HAVE__BUILTIN_CLZ */ int shift = 64 - 8; - Assert(word != 0); + if (word == 0) + return 0; while ((word >> shift) == 0) shift -= 8; @@ -73,19 +71,18 @@ pg_leftmost_one_pos64(uint64 word) /* * pg_rightmost_one_pos32 * Returns the position of the least significant set bit in "word", - * measured from the least significant bit. word must not be 0. + * measured from the least significant bit. */ static inline int pg_rightmost_one_pos32(uint32 word) { #ifdef HAVE__BUILTIN_CTZ - Assert(word != 0); - - return __builtin_ctz(word); + return word ? __builtin_ctz(word) : 32; #else int result = 0; - Assert(word != 0); + if (word == 0) + return 32; while ((word & 255) == 0) { @@ -105,19 +102,18 @@ static inline int pg_rightmost_one_pos64(uint64 word) { #ifdef HAVE__BUILTIN_CTZ - Assert(word != 0); - #if defined(HAVE_LONG_INT_64) - return __builtin_ctzl(word); + return word ? __builtin_ctzl(word) : 64; #elif defined(HAVE_LONG_LONG_INT_64) - return __builtin_ctzll(word); + return word ? __builtin_ctzll(word) : 64; #else #error must have a working 64-bit integer datatype #endif #else /* !HAVE__BUILTIN_CTZ */ int result = 0; - Assert(word != 0); + if (word == 0) + return 64; while ((word & 255) == 0) { @@ -145,4 +141,34 @@ pg_rotate_right32(uint32 word, int n) return (word >> n) | (word << (sizeof(word) * BITS_PER_BYTE - n)); } +/* ceil(lg2(num)) */ +static inline uint32 +ceil_log2_32(uint32 num) +{ + Assert(num > 0); + return pg_leftmost_one_pos32(num-1) + 1; +} + +static inline uint64 +ceil_log2_64(uint64 num) +{ + Assert(num > 0); + return pg_leftmost_one_pos64(num-1) + 1; +} + +/* Calculate the first power of 2 >= num */ +static inline uint32 +next_power_of_2_32(uint32 num) +{ + Assert(num > 0); + return ((uint32) 1) << (pg_leftmost_one_pos32(num-1) + 1); +} + +static inline uint64 +next_power_of_2_64(uint64 num) +{ + Assert(num > 0); + return ((uint64) 1) << (pg_leftmost_one_pos64(num-1) + 1); +} + #endif /* PG_BITUTILS_H */ --------------2.24.1--
>From b7eb194c473ca399a8e8afcd279bb3480fe9dacf Mon Sep 17 00:00:00 2001 From: David Fetter <da...@fetter.org> Date: Fri, 31 Jan 2020 08:32:26 -0800 Subject: [PATCH v6 3/3] Reduced operations in floor_log2 To: hackers MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="------------2.24.1" This is a multi-part message in MIME format. --------------2.24.1 Content-Type: text/plain; charset=UTF-8; format=fixed Content-Transfer-Encoding: 8bit diff --git a/src/backend/utils/adt/array_selfuncs.c b/src/backend/utils/adt/array_selfuncs.c index d97e60a3ab..12170cb7f2 100644 --- a/src/backend/utils/adt/array_selfuncs.c +++ b/src/backend/utils/adt/array_selfuncs.c @@ -20,6 +20,7 @@ #include "catalog/pg_collation.h" #include "catalog/pg_operator.h" #include "catalog/pg_statistic.h" +#include "port/pg_bitutils.h" #include "utils/array.h" #include "utils/builtins.h" #include "utils/lsyscache.h" @@ -1089,35 +1090,9 @@ calc_distr(const float *p, int n, int m, float rest) static int floor_log2(uint32 n) { - int logval = 0; - if (n == 0) return -1; - if (n >= (1 << 16)) - { - n >>= 16; - logval += 16; - } - if (n >= (1 << 8)) - { - n >>= 8; - logval += 8; - } - if (n >= (1 << 4)) - { - n >>= 4; - logval += 4; - } - if (n >= (1 << 2)) - { - n >>= 2; - logval += 2; - } - if (n >= (1 << 1)) - { - logval += 1; - } - return logval; + return 1 << pg_leftmost_one_pos32(n); } /* --------------2.24.1--