*
* dynahash
* openGauss dynahash.h file definitions
*
*
* Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/utils/dynahash.h
*
* -------------------------------------------------------------------------
*/
#ifndef DYNAHASH_H
#define DYNAHASH_H
#include "storage/buf/buf_internals.h"
#include "storage/lock/s_lock.h"
#include "utils/hsearch.h"
#define NUM_FREELISTS 32
typedef HASHELEMENT* HASHBUCKET;
typedef HASHBUCKET* HASHSEGMENT;
* Using array of FreeListData instead of separate arrays of mutexes, nentries
* and freeLists prevents, at least partially, sharing one cache line between
* different mutexes (see below).
*/
typedef struct {
slock_t mutex;
long nentries;
HASHELEMENT* freeList;
} FreeListData;
* Header structure for a hash table --- contains all changeable info
*
* In a shared-memory hash table, the HASHHDR is in shared memory, while
* each backend has a local HTAB struct. For a non-shared table, there isn't
* any functional difference between HASHHDR and HTAB, but we separate them
* anyway to share code between shared and non-shared tables.
*/
struct HASHHDR {
* The freelist can become a point of contention on high-concurrency hash
* tables, so we use an array of freelist, each with its own mutex and
* nentries count, instead of just a single one.
*
* If hash table is not partitioned only freeList[0] is used and spinlocks
* are not used at all.
*/
FreeListData freeList[NUM_FREELISTS];
long dsize;
long nsegs;
uint32 max_bucket;
uint32 high_mask;
uint32 low_mask;
Size keysize;
Size entrysize;
long num_partitions;
long ffactor;
long max_dsize;
long ssize;
int sshift;
int nelem_alloc;
#ifdef HASH_STATISTICS
* 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;
#endif
};
#define HTAB_PAD_OFFSET 104
* Top control structure for a hashtable --- in a shared table, each backend
* has its own copy (OK since no fields change at runtime)
*/
struct HTAB {
HASHHDR* hctl;
HASHSEGMENT* dir;
HashValueFunc hash;
HashCompareFunc match;
HashCopyFunc keycopy;
HashAllocFunc alloc;
HashDeallocFunc dealloc;
MemoryContext hcxt;
char* tabname;
bool isshared;
bool isfixed;
bool frozen;
Size keysize;
long ssize;
int sshift;
#ifdef __aarch64__
char pad[PG_CACHE_LINE_SIZE - HTAB_PAD_OFFSET];
#endif
};
extern int my_log2(long num);
template <HASHACTION action>
void* buf_hash_operate(HTAB* hashp, const BufferTag* keyPtr, uint32 hashvalue, bool* foundPtr);
#endif