PostgreSQL Source Code git master
dshash.h File Reference
#include "utils/dsa.h"
Include dependency graph for dshash.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  dshash_parameters
 
struct  dshash_seq_status
 

Macros

#define DSHASH_HANDLE_INVALID   ((dshash_table_handle) InvalidDsaPointer)
 

Typedefs

typedef struct dshash_table dshash_table
 
typedef dsa_pointer dshash_table_handle
 
typedef uint32 dshash_hash
 
typedef int(* dshash_compare_function) (const void *a, const void *b, size_t size, void *arg)
 
typedef dshash_hash(* dshash_hash_function) (const void *v, size_t size, void *arg)
 
typedef void(* dshash_copy_function) (void *dest, const void *src, size_t size, void *arg)
 
typedef struct dshash_parameters dshash_parameters
 
typedef struct dshash_table_item dshash_table_item
 
typedef struct dshash_seq_status dshash_seq_status
 

Functions

dshash_tabledshash_create (dsa_area *area, const dshash_parameters *params, void *arg)
 
dshash_tabledshash_attach (dsa_area *area, const dshash_parameters *params, dshash_table_handle handle, void *arg)
 
void dshash_detach (dshash_table *hash_table)
 
dshash_table_handle dshash_get_hash_table_handle (dshash_table *hash_table)
 
void dshash_destroy (dshash_table *hash_table)
 
void * dshash_find (dshash_table *hash_table, const void *key, bool exclusive)
 
void * dshash_find_or_insert (dshash_table *hash_table, const void *key, bool *found)
 
bool dshash_delete_key (dshash_table *hash_table, const void *key)
 
void dshash_delete_entry (dshash_table *hash_table, void *entry)
 
void dshash_release_lock (dshash_table *hash_table, void *entry)
 
void dshash_seq_init (dshash_seq_status *status, dshash_table *hash_table, bool exclusive)
 
void * dshash_seq_next (dshash_seq_status *status)
 
void dshash_seq_term (dshash_seq_status *status)
 
void dshash_delete_current (dshash_seq_status *status)
 
int dshash_memcmp (const void *a, const void *b, size_t size, void *arg)
 
dshash_hash dshash_memhash (const void *v, size_t size, void *arg)
 
void dshash_memcpy (void *dest, const void *src, size_t size, void *arg)
 
int dshash_strcmp (const void *a, const void *b, size_t size, void *arg)
 
dshash_hash dshash_strhash (const void *v, size_t size, void *arg)
 
void dshash_strcpy (void *dest, const void *src, size_t size, void *arg)
 
void dshash_dump (dshash_table *hash_table)
 

Macro Definition Documentation

◆ DSHASH_HANDLE_INVALID

#define DSHASH_HANDLE_INVALID   ((dshash_table_handle) InvalidDsaPointer)

Definition at line 27 of file dshash.h.

Typedef Documentation

◆ dshash_compare_function

typedef int(* dshash_compare_function) (const void *a, const void *b, size_t size, void *arg)

Definition at line 33 of file dshash.h.

◆ dshash_copy_function

typedef void(* dshash_copy_function) (void *dest, const void *src, size_t size, void *arg)

Definition at line 41 of file dshash.h.

◆ dshash_hash

Definition at line 30 of file dshash.h.

◆ dshash_hash_function

typedef dshash_hash(* dshash_hash_function) (const void *v, size_t size, void *arg)

Definition at line 37 of file dshash.h.

◆ dshash_parameters

◆ dshash_seq_status

◆ dshash_table

typedef struct dshash_table dshash_table

Definition at line 21 of file dshash.h.

◆ dshash_table_handle

Definition at line 24 of file dshash.h.

◆ dshash_table_item

Definition at line 66 of file dshash.h.

Function Documentation

◆ dshash_attach()

dshash_table * dshash_attach ( dsa_area area,
const dshash_parameters params,
dshash_table_handle  handle,
void *  arg 
)

Definition at line 270 of file dshash.c.

272{
273 dshash_table *hash_table;
274 dsa_pointer control;
275
276 /* Allocate the backend-local object representing the hash table. */
277 hash_table = palloc(sizeof(dshash_table));
278
279 /* Find the control object in shared memory. */
280 control = handle;
281
282 /* Set up the local hash table struct. */
283 hash_table->area = area;
284 hash_table->params = *params;
285 hash_table->arg = arg;
286 hash_table->control = dsa_get_address(area, control);
287 Assert(hash_table->control->magic == DSHASH_MAGIC);
288
289 /*
290 * These will later be set to the correct values by
291 * ensure_valid_bucket_pointers(), at which time we'll be holding a
292 * partition lock for interlocking against concurrent resizing.
293 */
294 hash_table->buckets = NULL;
295 hash_table->size_log2 = 0;
296
297 return hash_table;
298}
void * dsa_get_address(dsa_area *area, dsa_pointer dp)
Definition: dsa.c:942
uint64 dsa_pointer
Definition: dsa.h:62
#define DSHASH_MAGIC
Definition: dshash.c:63
Assert(PointerIsAligned(start, uint64))
void * palloc(Size size)
Definition: mcxt.c:1317
void * arg
dshash_parameters params
Definition: dshash.c:106
dsa_pointer * buckets
Definition: dshash.c:109
dsa_area * area
Definition: dshash.c:105
void * arg
Definition: dshash.c:107
size_t size_log2
Definition: dshash.c:110
dshash_table_control * control
Definition: dshash.c:108

References dshash_table::area, dshash_table::arg, arg, Assert(), dshash_table::buckets, dshash_table::control, dsa_get_address(), DSHASH_MAGIC, dshash_table_control::magic, palloc(), dshash_table::params, and dshash_table::size_log2.

Referenced by init_dsm_registry(), logicalrep_launcher_attach_dshmem(), pgstat_attach_shmem(), and SharedRecordTypmodRegistryAttach().

◆ dshash_create()

dshash_table * dshash_create ( dsa_area area,
const dshash_parameters params,
void *  arg 
)

Definition at line 206 of file dshash.c.

207{
208 dshash_table *hash_table;
209 dsa_pointer control;
210
211 /* Allocate the backend-local object representing the hash table. */
212 hash_table = palloc(sizeof(dshash_table));
213
214 /* Allocate the control object in shared memory. */
215 control = dsa_allocate(area, sizeof(dshash_table_control));
216
217 /* Set up the local and shared hash table structs. */
218 hash_table->area = area;
219 hash_table->params = *params;
220 hash_table->arg = arg;
221 hash_table->control = dsa_get_address(area, control);
222 hash_table->control->handle = control;
223 hash_table->control->magic = DSHASH_MAGIC;
224 hash_table->control->lwlock_tranche_id = params->tranche_id;
225
226 /* Set up the array of lock partitions. */
227 {
229 int tranche_id = hash_table->control->lwlock_tranche_id;
230 int i;
231
232 for (i = 0; i < DSHASH_NUM_PARTITIONS; ++i)
233 {
234 LWLockInitialize(&partitions[i].lock, tranche_id);
235 partitions[i].count = 0;
236 }
237 }
238
239 /*
240 * Set up the initial array of buckets. Our initial size is the same as
241 * the number of partitions.
242 */
244 hash_table->control->buckets =
248 if (!DsaPointerIsValid(hash_table->control->buckets))
249 {
250 dsa_free(area, control);
252 (errcode(ERRCODE_OUT_OF_MEMORY),
253 errmsg("out of memory"),
254 errdetail("Failed on DSA request of size %zu.",
256 }
257 hash_table->buckets = dsa_get_address(area,
258 hash_table->control->buckets);
259 hash_table->size_log2 = hash_table->control->size_log2;
260
261 return hash_table;
262}
dsa_pointer dsa_allocate_extended(dsa_area *area, size_t size, int flags)
Definition: dsa.c:671
void dsa_free(dsa_area *area, dsa_pointer dp)
Definition: dsa.c:826
#define dsa_allocate(area, size)
Definition: dsa.h:109
#define DSA_ALLOC_NO_OOM
Definition: dsa.h:74
#define DsaPointerIsValid(x)
Definition: dsa.h:106
#define DSA_ALLOC_ZERO
Definition: dsa.h:75
#define DSHASH_NUM_PARTITIONS
Definition: dshash.c:60
#define DSHASH_NUM_PARTITIONS_LOG2
Definition: dshash.c:59
int errdetail(const char *fmt,...)
Definition: elog.c:1203
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
int i
Definition: isn.c:74
void LWLockInitialize(LWLock *lock, int tranche_id)
Definition: lwlock.c:718
static int partitions
Definition: pgbench.c:224
size_t size_log2
Definition: dshash.c:96
dshash_partition partitions[DSHASH_NUM_PARTITIONS]
Definition: dshash.c:87
dshash_table_handle handle
Definition: dshash.c:85
dsa_pointer buckets
Definition: dshash.c:97

References dshash_table::area, dshash_table::arg, arg, dshash_table_control::buckets, dshash_table::buckets, dshash_table::control, DSA_ALLOC_NO_OOM, DSA_ALLOC_ZERO, dsa_allocate, dsa_allocate_extended(), dsa_free(), dsa_get_address(), DsaPointerIsValid, DSHASH_MAGIC, DSHASH_NUM_PARTITIONS, DSHASH_NUM_PARTITIONS_LOG2, ereport, errcode(), errdetail(), errmsg(), ERROR, dshash_table_control::handle, i, dshash_table_control::lwlock_tranche_id, LWLockInitialize(), dshash_table_control::magic, palloc(), dshash_table::params, dshash_table_control::partitions, partitions, dshash_table_control::size_log2, dshash_table::size_log2, and dshash_parameters::tranche_id.

Referenced by init_dsm_registry(), logicalrep_launcher_attach_dshmem(), SharedRecordTypmodRegistryInit(), and StatsShmemInit().

◆ dshash_delete_current()

void dshash_delete_current ( dshash_seq_status status)

Definition at line 757 of file dshash.c.

758{
759 dshash_table *hash_table = status->hash_table;
760 dshash_table_item *item = status->curitem;
761 size_t partition PG_USED_FOR_ASSERTS_ONLY;
762
763 partition = PARTITION_FOR_HASH(item->hash);
764
765 Assert(status->exclusive);
766 Assert(hash_table->control->magic == DSHASH_MAGIC);
767 Assert(LWLockHeldByMeInMode(PARTITION_LOCK(hash_table, partition),
768 LW_EXCLUSIVE));
769
770 delete_item(hash_table, item);
771}
#define PG_USED_FOR_ASSERTS_ONLY
Definition: c.h:224
#define PARTITION_LOCK(hash_table, i)
Definition: dshash.c:192
static void delete_item(dshash_table *hash_table, dshash_table_item *item)
Definition: dshash.c:832
#define PARTITION_FOR_HASH(hash)
Definition: dshash.c:140
bool LWLockHeldByMeInMode(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:2011
@ LW_EXCLUSIVE
Definition: lwlock.h:114
bool exclusive
Definition: dshash.h:80
dshash_table_item * curitem
Definition: dshash.h:77
dshash_table * hash_table
Definition: dshash.h:74
dshash_hash hash
Definition: dshash.c:49

References Assert(), dshash_table::control, dshash_seq_status::curitem, delete_item(), DSHASH_MAGIC, dshash_seq_status::exclusive, dshash_table_item::hash, dshash_seq_status::hash_table, LW_EXCLUSIVE, LWLockHeldByMeInMode(), dshash_table_control::magic, PARTITION_FOR_HASH, PARTITION_LOCK, and PG_USED_FOR_ASSERTS_ONLY.

Referenced by pgstat_free_entry().

◆ dshash_delete_entry()

void dshash_delete_entry ( dshash_table hash_table,
void *  entry 
)

Definition at line 541 of file dshash.c.

542{
543 dshash_table_item *item = ITEM_FROM_ENTRY(entry);
544 size_t partition = PARTITION_FOR_HASH(item->hash);
545
546 Assert(hash_table->control->magic == DSHASH_MAGIC);
547 Assert(LWLockHeldByMeInMode(PARTITION_LOCK(hash_table, partition),
548 LW_EXCLUSIVE));
549
550 delete_item(hash_table, item);
551 LWLockRelease(PARTITION_LOCK(hash_table, partition));
552}
#define ITEM_FROM_ENTRY(entry)
Definition: dshash.c:118
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1899

References Assert(), dshash_table::control, delete_item(), DSHASH_MAGIC, dshash_table_item::hash, ITEM_FROM_ENTRY, LW_EXCLUSIVE, LWLockHeldByMeInMode(), LWLockRelease(), dshash_table_control::magic, PARTITION_FOR_HASH, and PARTITION_LOCK.

Referenced by pgstat_free_entry().

◆ dshash_delete_key()

bool dshash_delete_key ( dshash_table hash_table,
const void *  key 
)

Definition at line 503 of file dshash.c.

504{
506 size_t partition;
507 bool found;
508
509 Assert(hash_table->control->magic == DSHASH_MAGIC);
511
512 hash = hash_key(hash_table, key);
513 partition = PARTITION_FOR_HASH(hash);
514
515 LWLockAcquire(PARTITION_LOCK(hash_table, partition), LW_EXCLUSIVE);
517
518 if (delete_key_from_bucket(hash_table, key,
519 &BUCKET_FOR_HASH(hash_table, hash)))
520 {
521 Assert(hash_table->control->partitions[partition].count > 0);
522 found = true;
523 --hash_table->control->partitions[partition].count;
524 }
525 else
526 found = false;
527
528 LWLockRelease(PARTITION_LOCK(hash_table, partition));
529
530 return found;
531}
static bool delete_key_from_bucket(dshash_table *hash_table, const void *key, dsa_pointer *bucket_head)
Definition: dshash.c:1006
static dshash_hash hash_key(dshash_table *hash_table, const void *key)
Definition: dshash.c:1063
#define ASSERT_NO_PARTITION_LOCKS_HELD_BY_ME(hash_table)
Definition: dshash.c:195
static void ensure_valid_bucket_pointers(dshash_table *hash_table)
Definition: dshash.c:937
#define BUCKET_FOR_HASH(hash_table, hash)
Definition: dshash.c:161
uint32 dshash_hash
Definition: dshash.h:30
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1179
static unsigned hash(unsigned *uv, int n)
Definition: rege_dfa.c:715
size_t count
Definition: dshash.c:76

References Assert(), ASSERT_NO_PARTITION_LOCKS_HELD_BY_ME, BUCKET_FOR_HASH, dshash_table::control, dshash_partition::count, delete_key_from_bucket(), DSHASH_MAGIC, ensure_valid_bucket_pointers(), hash(), hash_key(), sort-test::key, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), dshash_table_control::magic, PARTITION_FOR_HASH, PARTITION_LOCK, and dshash_table_control::partitions.

Referenced by ApplyLauncherForgetWorkerStartTime(), and find_or_make_matching_shared_tupledesc().

◆ dshash_destroy()

void dshash_destroy ( dshash_table hash_table)

Definition at line 323 of file dshash.c.

324{
325 size_t size;
326 size_t i;
327
328 Assert(hash_table->control->magic == DSHASH_MAGIC);
330
331 /* Free all the entries. */
332 size = NUM_BUCKETS(hash_table->size_log2);
333 for (i = 0; i < size; ++i)
334 {
335 dsa_pointer item_pointer = hash_table->buckets[i];
336
337 while (DsaPointerIsValid(item_pointer))
338 {
339 dshash_table_item *item;
340 dsa_pointer next_item_pointer;
341
342 item = dsa_get_address(hash_table->area, item_pointer);
343 next_item_pointer = item->next;
344 dsa_free(hash_table->area, item_pointer);
345 item_pointer = next_item_pointer;
346 }
347 }
348
349 /*
350 * Vandalize the control block to help catch programming errors where
351 * other backends access the memory formerly occupied by this hash table.
352 */
353 hash_table->control->magic = 0;
354
355 /* Free the active table and control object. */
356 dsa_free(hash_table->area, hash_table->control->buckets);
357 dsa_free(hash_table->area, hash_table->control->handle);
358
359 pfree(hash_table);
360}
#define NUM_BUCKETS(size_log2)
Definition: dshash.c:127
void pfree(void *pointer)
Definition: mcxt.c:1524
dsa_pointer next
Definition: dshash.c:47

References dshash_table::area, Assert(), dshash_table_control::buckets, dshash_table::buckets, dshash_table::control, dsa_free(), dsa_get_address(), DsaPointerIsValid, DSHASH_MAGIC, ensure_valid_bucket_pointers(), dshash_table_control::handle, i, dshash_table_control::magic, dshash_table_item::next, NUM_BUCKETS, pfree(), and dshash_table::size_log2.

◆ dshash_detach()

void dshash_detach ( dshash_table hash_table)

Definition at line 307 of file dshash.c.

308{
310
311 /* The hash table may have been destroyed. Just free local memory. */
312 pfree(hash_table);
313}

References ASSERT_NO_PARTITION_LOCKS_HELD_BY_ME, and pfree().

Referenced by pgstat_detach_shmem(), shared_record_typmod_registry_detach(), and StatsShmemInit().

◆ dshash_dump()

void dshash_dump ( dshash_table hash_table)

Definition at line 778 of file dshash.c.

779{
780 size_t i;
781 size_t j;
782
783 Assert(hash_table->control->magic == DSHASH_MAGIC);
785
786 for (i = 0; i < DSHASH_NUM_PARTITIONS; ++i)
787 {
788 Assert(!LWLockHeldByMe(PARTITION_LOCK(hash_table, i)));
790 }
791
793
794 fprintf(stderr,
795 "hash table size = %zu\n", (size_t) 1 << hash_table->size_log2);
796 for (i = 0; i < DSHASH_NUM_PARTITIONS; ++i)
797 {
798 dshash_partition *partition = &hash_table->control->partitions[i];
799 size_t begin = BUCKET_INDEX_FOR_PARTITION(i, hash_table->size_log2);
800 size_t end = BUCKET_INDEX_FOR_PARTITION(i + 1, hash_table->size_log2);
801
802 fprintf(stderr, " partition %zu\n", i);
803 fprintf(stderr,
804 " active buckets (key count = %zu)\n", partition->count);
805
806 for (j = begin; j < end; ++j)
807 {
808 size_t count = 0;
809 dsa_pointer bucket = hash_table->buckets[j];
810
811 while (DsaPointerIsValid(bucket))
812 {
813 dshash_table_item *item;
814
815 item = dsa_get_address(hash_table->area, bucket);
816
817 bucket = item->next;
818 ++count;
819 }
820 fprintf(stderr, " bucket %zu (key count = %zu)\n", j, count);
821 }
822 }
823
824 for (i = 0; i < DSHASH_NUM_PARTITIONS; ++i)
825 LWLockRelease(PARTITION_LOCK(hash_table, i));
826}
#define fprintf(file, fmt, msg)
Definition: cubescan.l:21
#define BUCKET_INDEX_FOR_PARTITION(partition, size_log2)
Definition: dshash.c:153
int j
Definition: isn.c:75
bool LWLockHeldByMe(LWLock *lock)
Definition: lwlock.c:1967
@ LW_SHARED
Definition: lwlock.h:115

References dshash_table::area, Assert(), ASSERT_NO_PARTITION_LOCKS_HELD_BY_ME, BUCKET_INDEX_FOR_PARTITION, dshash_table::buckets, dshash_table::control, dshash_partition::count, dsa_get_address(), DsaPointerIsValid, DSHASH_MAGIC, DSHASH_NUM_PARTITIONS, ensure_valid_bucket_pointers(), fprintf, i, j, LW_SHARED, LWLockAcquire(), LWLockHeldByMe(), LWLockRelease(), dshash_table_control::magic, dshash_table_item::next, PARTITION_LOCK, dshash_table_control::partitions, and dshash_table::size_log2.

◆ dshash_find()

void * dshash_find ( dshash_table hash_table,
const void *  key,
bool  exclusive 
)

Definition at line 390 of file dshash.c.

391{
393 size_t partition;
394 dshash_table_item *item;
395
396 hash = hash_key(hash_table, key);
397 partition = PARTITION_FOR_HASH(hash);
398
399 Assert(hash_table->control->magic == DSHASH_MAGIC);
401
402 LWLockAcquire(PARTITION_LOCK(hash_table, partition),
403 exclusive ? LW_EXCLUSIVE : LW_SHARED);
405
406 /* Search the active bucket. */
407 item = find_in_bucket(hash_table, key, BUCKET_FOR_HASH(hash_table, hash));
408
409 if (!item)
410 {
411 /* Not found. */
412 LWLockRelease(PARTITION_LOCK(hash_table, partition));
413 return NULL;
414 }
415 else
416 {
417 /* The caller will free the lock by calling dshash_release_lock. */
418 return ENTRY_FROM_ITEM(item);
419 }
420}
#define ENTRY_FROM_ITEM(item)
Definition: dshash.c:114
static dshash_table_item * find_in_bucket(dshash_table *hash_table, const void *key, dsa_pointer item_pointer)
Definition: dshash.c:951

References Assert(), ASSERT_NO_PARTITION_LOCKS_HELD_BY_ME, BUCKET_FOR_HASH, dshash_table::control, DSHASH_MAGIC, ensure_valid_bucket_pointers(), ENTRY_FROM_ITEM, find_in_bucket(), hash(), hash_key(), sort-test::key, LW_EXCLUSIVE, LW_SHARED, LWLockAcquire(), LWLockRelease(), dshash_table_control::magic, PARTITION_FOR_HASH, and PARTITION_LOCK.

Referenced by ApplyLauncherGetWorkerStartTime(), find_or_make_matching_shared_tupledesc(), lookup_rowtype_tupdesc_internal(), pgstat_drop_entry(), pgstat_get_entry_ref(), and pgstat_release_entry_ref().

◆ dshash_find_or_insert()

void * dshash_find_or_insert ( dshash_table hash_table,
const void *  key,
bool *  found 
)

Definition at line 433 of file dshash.c.

436{
438 size_t partition_index;
439 dshash_partition *partition;
440 dshash_table_item *item;
441
442 hash = hash_key(hash_table, key);
443 partition_index = PARTITION_FOR_HASH(hash);
444 partition = &hash_table->control->partitions[partition_index];
445
446 Assert(hash_table->control->magic == DSHASH_MAGIC);
448
449restart:
450 LWLockAcquire(PARTITION_LOCK(hash_table, partition_index),
453
454 /* Search the active bucket. */
455 item = find_in_bucket(hash_table, key, BUCKET_FOR_HASH(hash_table, hash));
456
457 if (item)
458 *found = true;
459 else
460 {
461 *found = false;
462
463 /* Check if we are getting too full. */
464 if (partition->count > MAX_COUNT_PER_PARTITION(hash_table))
465 {
466 /*
467 * The load factor (= keys / buckets) for all buckets protected by
468 * this partition is > 0.75. Presumably the same applies
469 * generally across the whole hash table (though we don't attempt
470 * to track that directly to avoid contention on some kind of
471 * central counter; we just assume that this partition is
472 * representative). This is a good time to resize.
473 *
474 * Give up our existing lock first, because resizing needs to
475 * reacquire all the locks in the right order to avoid deadlocks.
476 */
477 LWLockRelease(PARTITION_LOCK(hash_table, partition_index));
478 resize(hash_table, hash_table->size_log2 + 1);
479
480 goto restart;
481 }
482
483 /* Finally we can try to insert the new item. */
484 item = insert_into_bucket(hash_table, key,
485 &BUCKET_FOR_HASH(hash_table, hash));
486 item->hash = hash;
487 /* Adjust per-lock-partition counter for load factor knowledge. */
488 ++partition->count;
489 }
490
491 /* The caller must release the lock with dshash_release_lock. */
492 return ENTRY_FROM_ITEM(item);
493}
static dshash_table_item * insert_into_bucket(dshash_table *hash_table, const void *key, dsa_pointer *bucket)
Definition: dshash.c:986
#define MAX_COUNT_PER_PARTITION(hash_table)
Definition: dshash.c:135
static void resize(dshash_table *hash_table, size_t new_size_log2)
Definition: dshash.c:858

References Assert(), ASSERT_NO_PARTITION_LOCKS_HELD_BY_ME, BUCKET_FOR_HASH, dshash_table::control, dshash_partition::count, DSHASH_MAGIC, ensure_valid_bucket_pointers(), ENTRY_FROM_ITEM, find_in_bucket(), dshash_table_item::hash, hash(), hash_key(), insert_into_bucket(), sort-test::key, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), dshash_table_control::magic, MAX_COUNT_PER_PARTITION, PARTITION_FOR_HASH, PARTITION_LOCK, dshash_table_control::partitions, resize(), and dshash_table::size_log2.

Referenced by ApplyLauncherSetWorkerStartTime(), find_or_make_matching_shared_tupledesc(), GetNamedDSMSegment(), pgstat_get_entry_ref(), pgstat_read_statsfile(), and SharedRecordTypmodRegistryInit().

◆ dshash_get_hash_table_handle()

dshash_table_handle dshash_get_hash_table_handle ( dshash_table hash_table)

◆ dshash_memcmp()

int dshash_memcmp ( const void *  a,
const void *  b,
size_t  size,
void *  arg 
)

Definition at line 572 of file dshash.c.

573{
574 return memcmp(a, b, size);
575}
int b
Definition: isn.c:71
int a
Definition: isn.c:70

References a, and b.

◆ dshash_memcpy()

void dshash_memcpy ( void *  dest,
const void *  src,
size_t  size,
void *  arg 
)

Definition at line 590 of file dshash.c.

591{
592 (void) memcpy(dest, src, size);
593}

References generate_unaccent_rules::dest.

◆ dshash_memhash()

dshash_hash dshash_memhash ( const void *  v,
size_t  size,
void *  arg 
)

Definition at line 581 of file dshash.c.

582{
583 return tag_hash(v, size);
584}
uint32 tag_hash(const void *key, Size keysize)
Definition: hashfn.c:677

References tag_hash().

◆ dshash_release_lock()

◆ dshash_seq_init()

void dshash_seq_init ( dshash_seq_status status,
dshash_table hash_table,
bool  exclusive 
)

◆ dshash_seq_next()

void * dshash_seq_next ( dshash_seq_status status)

Definition at line 657 of file dshash.c.

658{
659 dsa_pointer next_item_pointer;
660
661 /*
662 * Not yet holding any partition locks. Need to determine the size of the
663 * hash table, it could have been resized since we were looking last.
664 * Since we iterate in partition order, we can start by unconditionally
665 * lock partition 0.
666 *
667 * Once we hold the lock, no resizing can happen until the scan ends. So
668 * we don't need to repeatedly call ensure_valid_bucket_pointers().
669 */
670 if (status->curpartition == -1)
671 {
672 Assert(status->curbucket == 0);
674
675 status->curpartition = 0;
676
678 status->curpartition),
679 status->exclusive ? LW_EXCLUSIVE : LW_SHARED);
680
682
683 status->nbuckets =
685 next_item_pointer = status->hash_table->buckets[status->curbucket];
686 }
687 else
688 next_item_pointer = status->pnextitem;
689
691 status->curpartition),
692 status->exclusive ? LW_EXCLUSIVE : LW_SHARED));
693
694 /* Move to the next bucket if we finished the current bucket */
695 while (!DsaPointerIsValid(next_item_pointer))
696 {
697 int next_partition;
698
699 if (++status->curbucket >= status->nbuckets)
700 {
701 /* all buckets have been scanned. finish. */
702 return NULL;
703 }
704
705 /* Check if move to the next partition */
706 next_partition =
708 status->hash_table->size_log2);
709
710 if (status->curpartition != next_partition)
711 {
712 /*
713 * Move to the next partition. Lock the next partition then
714 * release the current, not in the reverse order to avoid
715 * concurrent resizing. Avoid dead lock by taking lock in the
716 * same order with resize().
717 */
719 next_partition),
720 status->exclusive ? LW_EXCLUSIVE : LW_SHARED);
722 status->curpartition));
723 status->curpartition = next_partition;
724 }
725
726 next_item_pointer = status->hash_table->buckets[status->curbucket];
727 }
728
729 status->curitem =
730 dsa_get_address(status->hash_table->area, next_item_pointer);
731
732 /*
733 * The caller may delete the item. Store the next item in case of
734 * deletion.
735 */
736 status->pnextitem = status->curitem->next;
737
738 return ENTRY_FROM_ITEM(status->curitem);
739}
#define PARTITION_FOR_BUCKET_INDEX(bucket_idx, size_log2)
Definition: dshash.c:157

References dshash_table::area, Assert(), ASSERT_NO_PARTITION_LOCKS_HELD_BY_ME, dshash_table::buckets, dshash_table::control, dshash_seq_status::curbucket, dshash_seq_status::curitem, dshash_seq_status::curpartition, dsa_get_address(), DsaPointerIsValid, ensure_valid_bucket_pointers(), ENTRY_FROM_ITEM, dshash_seq_status::exclusive, dshash_seq_status::hash_table, LW_EXCLUSIVE, LW_SHARED, LWLockAcquire(), LWLockHeldByMeInMode(), LWLockRelease(), dshash_seq_status::nbuckets, dshash_table_item::next, NUM_BUCKETS, PARTITION_FOR_BUCKET_INDEX, PARTITION_LOCK, dshash_seq_status::pnextitem, dshash_table_control::size_log2, and dshash_table::size_log2.

Referenced by pgstat_build_snapshot(), pgstat_drop_database_and_contents(), pgstat_drop_matching_entries(), pgstat_reset_matching_entries(), and pgstat_write_statsfile().

◆ dshash_seq_term()

◆ dshash_strcmp()

int dshash_strcmp ( const void *  a,
const void *  b,
size_t  size,
void *  arg 
)

Definition at line 599 of file dshash.c.

600{
601 Assert(strlen((const char *) a) < size);
602 Assert(strlen((const char *) b) < size);
603
604 return strcmp((const char *) a, (const char *) b);
605}

References a, Assert(), and b.

◆ dshash_strcpy()

void dshash_strcpy ( void *  dest,
const void *  src,
size_t  size,
void *  arg 
)

Definition at line 622 of file dshash.c.

623{
624 Assert(strlen((const char *) src) < size);
625
626 (void) strcpy((char *) dest, (const char *) src);
627}

References Assert(), and generate_unaccent_rules::dest.

◆ dshash_strhash()

dshash_hash dshash_strhash ( const void *  v,
size_t  size,
void *  arg 
)

Definition at line 611 of file dshash.c.

612{
613 Assert(strlen((const char *) v) < size);
614
615 return string_hash((const char *) v, size);
616}
uint32 string_hash(const void *key, Size keysize)
Definition: hashfn.c:660

References Assert(), and string_hash().