*
* dynahash.c supports both local-to-a-backend hash tables and hash tables in
* shared memory. For shared hash tables, it is the caller's responsibility
*
* dynahash.c supports both local-to-a-backend hash tables and hash tables in
* shared memory. For shared hash tables, it is the caller's responsibility
- * to provide appropriate access interlocking. The simplest convention is
- * that a single LWLock protects the whole hash table. Searches (HASH_FIND or
+ * to provide appropriate access interlocking. The simplest convention is
+ * that a single LWLock protects the whole hash table. Searches (HASH_FIND or
* hash_seq_search) need only shared lock, but any update requires exclusive
* lock. For heavily-used shared tables, the single-lock approach creates a
* concurrency bottleneck, so we also support "partitioned" locking wherein
* there are multiple LWLocks guarding distinct subsets of the table. To use
* a hash table in partitioned mode, the HASH_PARTITION flag must be given
* hash_seq_search) need only shared lock, but any update requires exclusive
* lock. For heavily-used shared tables, the single-lock approach creates a
* concurrency bottleneck, so we also support "partitioned" locking wherein
* there are multiple LWLocks guarding distinct subsets of the table. To use
* a hash table in partitioned mode, the HASH_PARTITION flag must be given
* Therefore, each hash bucket chain operates independently, and no fields
* of the hash header change after init except nentries and freeList.
* A partitioned table uses a spinlock to guard changes of those two fields.
* This lets any subset of the hash buckets be treated as a separately
* Therefore, each hash bucket chain operates independently, and no fields
* of the hash header change after init except nentries and freeList.
* A partitioned table uses a spinlock to guard changes of those two fields.
* This lets any subset of the hash buckets be treated as a separately
* lookup key's hash value as a partition number --- this will work because
* of the way calc_bucket() maps hash values to bucket numbers.
*
* lookup key's hash value as a partition number --- this will work because
* of the way calc_bucket() maps hash values to bucket numbers.
*
/* These fields are fixed at hashtable creation */
Size keysize; /* hash key length in bytes */
Size entrysize; /* total user element size in bytes */
/* These fields are fixed at hashtable creation */
Size keysize; /* hash key length in bytes */
Size entrysize; /* total user element size in bytes */
long ffactor; /* target fill factor */
long max_dsize; /* 'dsize' limit if directory is fixed size */
long ssize; /* segment size --- must be power of 2 */
long ffactor; /* target fill factor */
long max_dsize; /* 'dsize' limit if directory is fixed size */
long ssize; /* segment size --- must be power of 2 */
- * Count statistics here. NB: stats code doesn't bother with mutex,
- * so counts could be corrupted a bit in a partitioned table.
+ * Count statistics here. NB: stats code doesn't bother with mutex, so
+ * counts could be corrupted a bit in a partitioned table.
- * If you don't specify a match function, it defaults to string_compare
- * if you used string_hash (either explicitly or by default) and to memcmp
+ * If you don't specify a match function, it defaults to string_compare if
+ * you used string_hash (either explicitly or by default) and to memcmp
* otherwise. (Prior to PostgreSQL 7.4, memcmp was always used.)
*/
if (flags & HASH_COMPARE)
* otherwise. (Prior to PostgreSQL 7.4, memcmp was always used.)
*/
if (flags & HASH_COMPARE)
* This reduces problems with run-time out-of-shared-memory conditions.
*
* For a non-shared hash table, preallocate the requested number of
* This reduces problems with run-time out-of-shared-memory conditions.
*
* For a non-shared hash table, preallocate the requested number of
- * elements if it's less than our chosen nelem_alloc. This avoids
- * wasting space if the caller correctly estimates a small table size.
+ * elements if it's less than our chosen nelem_alloc. This avoids wasting
+ * space if the caller correctly estimates a small table size.
- * The idea here is to choose nelem_alloc at least 32, but round up
- * so that the allocation request will be a power of 2 or just less.
- * This makes little difference for hash tables in shared memory,
- * but for hash tables managed by palloc, the allocation request
- * will be rounded up to a power of 2 anyway. If we fail to take
- * this into account, we'll waste as much as half the allocated space.
+ * The idea here is to choose nelem_alloc at least 32, but round up so
+ * that the allocation request will be a power of 2 or just less. This
+ * makes little difference for hash tables in shared memory, but for hash
+ * tables managed by palloc, the allocation request will be rounded up to
+ * a power of 2 anyway. If we fail to take this into account, we'll waste
+ * as much as half the allocated space.
/* Check if it is time to split a bucket */
/* Can't split if running in partitioned mode */
if (!IS_PARTITIONED(hctl) &&
/* Check if it is time to split a bucket */
/* Can't split if running in partitioned mode */
if (!IS_PARTITIONED(hctl) &&