99#define SH_MAKE_PREFIX(a) CppConcat(a,_)
100#define SH_MAKE_NAME(name) SH_MAKE_NAME_(SH_MAKE_PREFIX(SH_PREFIX),name)
101#define SH_MAKE_NAME_(a,b) CppConcat(a,b)
106#define SH_TYPE SH_MAKE_NAME(hash)
107#define SH_STATUS SH_MAKE_NAME(status)
108#define SH_STATUS_EMPTY SH_MAKE_NAME(SH_EMPTY)
109#define SH_STATUS_IN_USE SH_MAKE_NAME(SH_IN_USE)
110#define SH_ITERATOR SH_MAKE_NAME(iterator)
113#define SH_CREATE SH_MAKE_NAME(create)
114#define SH_DESTROY SH_MAKE_NAME(destroy)
115#define SH_RESET SH_MAKE_NAME(reset)
116#define SH_INSERT SH_MAKE_NAME(insert)
117#define SH_INSERT_HASH SH_MAKE_NAME(insert_hash)
118#define SH_DELETE_ITEM SH_MAKE_NAME(delete_item)
119#define SH_DELETE SH_MAKE_NAME(delete)
120#define SH_LOOKUP SH_MAKE_NAME(lookup)
121#define SH_LOOKUP_HASH SH_MAKE_NAME(lookup_hash)
122#define SH_GROW SH_MAKE_NAME(grow)
123#define SH_START_ITERATE SH_MAKE_NAME(start_iterate)
124#define SH_START_ITERATE_AT SH_MAKE_NAME(start_iterate_at)
125#define SH_ITERATE SH_MAKE_NAME(iterate)
126#define SH_ALLOCATE SH_MAKE_NAME(allocate)
127#define SH_FREE SH_MAKE_NAME(free)
128#define SH_STAT SH_MAKE_NAME(stat)
131#define SH_COMPUTE_PARAMETERS SH_MAKE_NAME(compute_parameters)
132#define SH_NEXT SH_MAKE_NAME(next)
133#define SH_PREV SH_MAKE_NAME(prev)
134#define SH_DISTANCE_FROM_OPTIMAL SH_MAKE_NAME(distance)
135#define SH_INITIAL_BUCKET SH_MAKE_NAME(initial_bucket)
136#define SH_ENTRY_HASH SH_MAKE_NAME(entry_hash)
137#define SH_INSERT_HASH_INTERNAL SH_MAKE_NAME(insert_hash_internal)
138#define SH_LOOKUP_HASH_INTERNAL SH_MAKE_NAME(lookup_hash_internal)
165#ifndef SH_RAW_ALLOCATOR
188#ifdef SH_RAW_ALLOCATOR
217 uint32 hash,
bool *found);
253#ifndef SH_RAW_ALLOCATOR
254#include "utils/memutils.h"
258#define SH_MAX_SIZE (((uint64) PG_UINT32_MAX) + 1)
262#define SH_FILLFACTOR (0.9)
265#define SH_MAX_FILLFACTOR (0.98)
267#ifndef SH_GROW_MAX_DIB
268#define SH_GROW_MAX_DIB 25
271#ifndef SH_GROW_MAX_MOVE
272#define SH_GROW_MAX_MOVE 150
274#ifndef SH_GROW_MIN_FILLFACTOR
276#define SH_GROW_MIN_FILLFACTOR 0.1
280#define SH_COMPARE_KEYS(tb, ahash, akey, b) (ahash == SH_GET_HASH(tb, b) && SH_EQUAL(tb, b->SH_KEY, akey))
282#define SH_COMPARE_KEYS(tb, ahash, akey, b) (SH_EQUAL(tb, b->SH_KEY, akey))
296#define sh_error(...) pg_fatal(__VA_ARGS__)
297#define sh_log(...) pg_log_info(__VA_ARGS__)
300#define sh_error(...) meos_error(ERROR, MEOS_ERR_INTERNAL_ERROR, __VA_ARGS__)
317 size =
Max(newsize, 2);
321 Assert(size <= SH_MAX_SIZE);
328 sh_error(
"hash table too large");
332 tb->sizemask = (
uint32) (size - 1);
338 if (tb->size == SH_MAX_SIZE)
339 tb->grow_threshold = ((double) tb->size) * SH_MAX_FILLFACTOR;
341 tb->grow_threshold = ((double) tb->size) * SH_FILLFACTOR;
348 return hash & tb->sizemask;
355 curelem = (curelem + 1) & tb->sizemask;
357 Assert(curelem != startelem);
366 curelem = (curelem - 1) & tb->sizemask;
368 Assert(curelem != startelem);
377 if (optimal <= bucket)
378 return bucket - optimal;
380 return (tb->size + bucket) - optimal;
387 return SH_GET_HASH(tb, entry);
397#ifndef SH_USE_NONDEFAULT_ALLOCATOR
403#ifdef SH_RAW_ALLOCATOR
406 return MemoryContextAllocExtended(type->ctx, size,
407 MCXT_ALLOC_HUGE | MCXT_ALLOC_ZERO);
429#ifdef SH_RAW_ALLOCATOR
440#ifdef SH_RAW_ALLOCATOR
446 tb->private_data = private_data;
449 size =
Min((
double) SH_MAX_SIZE, ((
double) nelements) / SH_FILLFACTOR);
484 uint64 oldsize = tb->size;
492 Assert(oldsize != SH_MAX_SIZE);
493 Assert(oldsize < newsize);
520 for (i = 0; i < oldsize; i++)
543 copyelem = startelem;
544 for (i = 0; i < oldsize; i++)
557 curelem = startelem2;
562 newentry = &newdata[curelem];
569 curelem =
SH_NEXT(tb, curelem, startelem2);
578 if (copyelem >= oldsize)
610 if (
unlikely(tb->members >= tb->grow_threshold))
612 if (
unlikely(tb->size == SH_MAX_SIZE))
613 sh_error(
"hash table size exceeded");
640 SH_GET_HASH(tb, entry) = hash;
655 if (SH_COMPARE_KEYS(tb, hash, key, entry))
666 if (insertdist > curdist)
669 uint32 emptyelem = curelem;
678 emptyelem =
SH_NEXT(tb, emptyelem, startelem);
679 emptyentry = &data[emptyelem];
683 lastentry = emptyentry;
696 if (
unlikely(++emptydist > SH_GROW_MAX_MOVE) &&
697 ((
double) tb->members / tb->size) >= SH_GROW_MIN_FILLFACTOR)
699 tb->grow_threshold = 0;
711 moveelem = emptyelem;
712 while (moveelem != curelem)
716 moveelem =
SH_PREV(tb, moveelem, startelem);
717 moveentry = &data[moveelem];
720 lastentry = moveentry;
728 SH_GET_HASH(tb, entry) = hash;
735 curelem =
SH_NEXT(tb, curelem, startelem);
746 if (
unlikely(insertdist > SH_GROW_MAX_DIB) &&
747 ((
double) tb->members / tb->size) >= SH_GROW_MIN_FILLFACTOR)
749 tb->grow_threshold = 0;
787 uint32 curelem = startelem;
800 if (SH_COMPARE_KEYS(tb, hash, key, entry))
810 curelem =
SH_NEXT(tb, curelem, startelem);
845 uint32 curelem = startelem;
855 SH_COMPARE_KEYS(tb, hash, key, entry))
874 curelem =
SH_NEXT(tb, curelem, startelem);
875 curentry = &tb->data[curelem];
887 if (curoptimal == curelem)
896 lastentry = curentry;
904 curelem =
SH_NEXT(tb, curelem, startelem);
920 curelem = entry - &tb->data[0];
937 curelem =
SH_NEXT(tb, curelem, startelem);
938 curentry = &tb->data[curelem];
950 if (curoptimal == curelem)
959 lastentry = curentry;
977 for (i = 0; i < tb->size; i++)
988 Assert(startelem < SH_MAX_SIZE);
994 iter->cur = startelem;
995 iter->end = iter->cur;
1013 iter->cur = at & tb->sizemask;
1014 iter->end = iter->cur;
1035 elem = &tb->data[iter->cur];
1038 iter->cur = (iter->cur - 1) & tb->sizemask;
1040 if ((iter->cur & tb->sizemask) == (iter->end & tb->sizemask))
1058 uint32 max_chain_length = 0;
1059 uint32 total_chain_length = 0;
1060 double avg_chain_length;
1065 uint32 total_collisions = 0;
1066 uint32 max_collisions = 0;
1067 double avg_collisions;
1069 for (i = 0; i < tb->size; i++)
1076 elem = &tb->data[i];
1085 if (dist > max_chain_length)
1086 max_chain_length = dist;
1087 total_chain_length += dist;
1089 collisions[optimal]++;
1092 for (i = 0; i < tb->size; i++)
1094 uint32 curcoll = collisions[i];
1101 total_collisions += curcoll;
1102 if (curcoll > max_collisions)
1103 max_collisions = curcoll;
1106 if (tb->members > 0)
1108 fillfactor = tb->members / ((double) tb->size);
1109 avg_chain_length = ((double) total_chain_length) / tb->members;
1110 avg_collisions = ((double) total_collisions) / tb->members;
1115 avg_chain_length = 0;
1132#undef SH_ELEMENT_TYPE
1139#undef SH_USE_NONDEFAULT_ALLOCATOR
1143#undef SH_MAKE_PREFIX
1147#undef SH_MAX_FILLFACTOR
1148#undef SH_GROW_MAX_DIB
1149#undef SH_GROW_MAX_MOVE
1150#undef SH_GROW_MIN_FILLFACTOR
1156#undef SH_STATUS_EMPTY
1157#undef SH_STATUS_IN_USE
1165#undef SH_INSERT_HASH
1166#undef SH_DELETE_ITEM
1169#undef SH_LOOKUP_HASH
1171#undef SH_START_ITERATE
1172#undef SH_START_ITERATE_AT
1179#undef SH_COMPUTE_PARAMETERS
1180#undef SH_COMPARE_KEYS
1181#undef SH_INITIAL_BUCKET
1184#undef SH_DISTANCE_FROM_OPTIMAL
1186#undef SH_INSERT_HASH_INTERNAL
1187#undef SH_LOOKUP_HASH_INTERNAL
#define Min(x, y)
Definition: c.h:1004
#define Max(x, y)
Definition: c.h:998
#define Assert(condition)
Definition: c.h:822
#define unlikely(x)
Definition: c.h:285
#define PG_UINT64_MAX
Definition: c.h:544
size_t Size
Definition: c.h:556
static uint64 pg_nextpower2_64(uint64 num)
Definition: pg_bitutils.h:169
#define SH_RAW_ALLOCATOR
Definition: pgtz.c:49
#define SH_HASH_KEY(tb, key)
Definition: pgtz.c:46
#define SH_ELEMENT_TYPE
Definition: pgtz.c:43
#define SH_KEY_TYPE
Definition: pgtz.c:44
#define SH_SCOPE
Definition: pgtz.c:48
#define palloc0(X)
Definition: postgres.h:65
#define pfree
Definition: postgres.h:68
unsigned int uint32
Definition: postgres_ext_defs.in.h:16
signed int int32
Definition: postgres_ext_defs.in.h:11
unsigned long int uint64
Definition: postgres_ext_defs.in.h:17
#define SH_GROW
Definition: simplehash.h:122
#define SH_STAT
Definition: simplehash.h:128
#define SH_INITIAL_BUCKET
Definition: simplehash.h:135
#define SH_INSERT_HASH
Definition: simplehash.h:117
#define SH_PREV
Definition: simplehash.h:133
#define SH_STATUS
Definition: simplehash.h:107
#define SH_CREATE
Definition: simplehash.h:113
#define SH_LOOKUP_HASH
Definition: simplehash.h:121
#define SH_START_ITERATE
Definition: simplehash.h:123
#define SH_COMPUTE_PARAMETERS
Definition: simplehash.h:131
#define SH_FREE
Definition: simplehash.h:127
#define SH_STATUS_IN_USE
Definition: simplehash.h:109
#define SH_DISTANCE_FROM_OPTIMAL
Definition: simplehash.h:134
#define SH_LOOKUP_HASH_INTERNAL
Definition: simplehash.h:138
#define SH_ITERATOR
Definition: simplehash.h:110
#define SH_NEXT
Definition: simplehash.h:132
#define SH_ITERATE
Definition: simplehash.h:125
#define SH_DELETE
Definition: simplehash.h:119
#define SH_INSERT
Definition: simplehash.h:116
#define SH_INSERT_HASH_INTERNAL
Definition: simplehash.h:137
#define SH_RESET
Definition: simplehash.h:115
#define SH_ENTRY_HASH
Definition: simplehash.h:136
#define SH_DELETE_ITEM
Definition: simplehash.h:118
#define SH_ALLOCATE
Definition: simplehash.h:126
#define SH_LOOKUP
Definition: simplehash.h:120
#define SH_TYPE
Definition: simplehash.h:106
#define SH_START_ITERATE_AT
Definition: simplehash.h:124
#define SH_STATUS_EMPTY
Definition: simplehash.h:108
#define SH_DESTROY
Definition: simplehash.h:114