hashCtl.keysize = sizeof(TrgmStateKey);
hashCtl.entrysize = sizeof(TrgmState);
hashCtl.hcxt = CurrentMemoryContext;
- hashCtl.hash = tag_hash;
trgmNFA->states = hash_create("Trigram NFA",
1024,
&hashCtl,
- HASH_ELEM | HASH_CONTEXT | HASH_FUNCTION);
+ HASH_ELEM | HASH_BLOBS | HASH_CONTEXT);
/* Create initial state: ambiguous prefix, NFA's initial state */
MemSet(&initkey, 0, sizeof(initkey));
MemSet(&ctl, 0, sizeof(ctl));
ctl.keysize = sizeof(ConnCacheKey);
ctl.entrysize = sizeof(ConnCacheEntry);
- ctl.hash = tag_hash;
/* allocate ConnectionHash in the cache context */
ctl.hcxt = CacheMemoryContext;
ConnectionHash = hash_create("postgres_fdw connections", 8,
&ctl,
- HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT);
+ HASH_ELEM | HASH_BLOBS | HASH_CONTEXT);
/*
* Register some callback functions that manage connection cleanup.
hashCtl.keysize = sizeof(BlockNumber);
hashCtl.entrysize = sizeof(ParentMapEntry);
hashCtl.hcxt = CurrentMemoryContext;
- hashCtl.hash = oid_hash;
buildstate->parentMap = hash_create("gistbuild parent map",
1024,
&hashCtl,
- HASH_ELEM | HASH_CONTEXT
- | HASH_FUNCTION);
+ HASH_ELEM | HASH_BLOBS | HASH_CONTEXT);
}
static void
* nodeBuffersTab hash is association between index blocks and it's
* buffers.
*/
+ memset(&hashCtl, 0, sizeof(hashCtl));
hashCtl.keysize = sizeof(BlockNumber);
hashCtl.entrysize = sizeof(GISTNodeBuffer);
hashCtl.hcxt = CurrentMemoryContext;
- hashCtl.hash = tag_hash;
- hashCtl.match = memcmp;
gfbb->nodeBuffersTab = hash_create("gistbuildbuffers",
1024,
&hashCtl,
- HASH_ELEM | HASH_CONTEXT
- | HASH_FUNCTION | HASH_COMPARE);
+ HASH_ELEM | HASH_BLOBS | HASH_CONTEXT);
gfbb->bufferEmptyingQueue = NIL;
hash_ctl.keysize = sizeof(TidHashKey);
hash_ctl.entrysize = sizeof(UnresolvedTupData);
hash_ctl.hcxt = state->rs_cxt;
- hash_ctl.hash = tag_hash;
state->rs_unresolved_tups =
hash_create("Rewrite / Unresolved ctids",
128, /* arbitrary initial size */
&hash_ctl,
- HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT);
+ HASH_ELEM | HASH_BLOBS | HASH_CONTEXT);
hash_ctl.entrysize = sizeof(OldToNewMappingData);
hash_create("Rewrite / Old to new tid map",
128, /* arbitrary initial size */
&hash_ctl,
- HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT);
+ HASH_ELEM | HASH_BLOBS | HASH_CONTEXT);
MemoryContextSwitchTo(old_cxt);
hash_ctl.keysize = sizeof(TransactionId);
hash_ctl.entrysize = sizeof(RewriteMappingFile);
hash_ctl.hcxt = state->rs_cxt;
- hash_ctl.hash = tag_hash;
state->rs_logical_mappings =
hash_create("Logical rewrite mapping",
128, /* arbitrary initial size */
&hash_ctl,
- HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT);
+ HASH_ELEM | HASH_BLOBS | HASH_CONTEXT);
}
/*
memset(&ctl, 0, sizeof(ctl));
ctl.keysize = sizeof(xl_invalid_page_key);
ctl.entrysize = sizeof(xl_invalid_page);
- ctl.hash = tag_hash;
invalid_page_tab = hash_create("XLOG invalid-page table",
100,
&ctl,
- HASH_ELEM | HASH_FUNCTION);
+ HASH_ELEM | HASH_BLOBS);
}
/* we currently assume xl_invalid_page_key contains no padding */
memset(&ctl, 0, sizeof(ctl));
ctl.keysize = sizeof(Oid);
ctl.entrysize = sizeof(SeqTableData);
- ctl.hash = oid_hash;
seqhashtab = hash_create("Sequence values", 16, &ctl,
- HASH_ELEM | HASH_FUNCTION);
+ HASH_ELEM | HASH_BLOBS);
}
/*
MemSet(&hash_ctl, 0, sizeof(hash_ctl));
hash_ctl.keysize = sizeof(BlockNumber);
hash_ctl.entrysize = sizeof(PagetableEntry);
- hash_ctl.hash = tag_hash;
hash_ctl.hcxt = tbm->mcxt;
tbm->pagetable = hash_create("TIDBitmap",
128, /* start small and extend */
&hash_ctl,
- HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT);
+ HASH_ELEM | HASH_BLOBS | HASH_CONTEXT);
/* If entry1 is valid, push it into the hashtable */
if (tbm->status == TBM_ONE_PAGE)
MemSet(&ctl, 0, sizeof(ctl));
ctl.keysize = sizeof(OprProofCacheKey);
ctl.entrysize = sizeof(OprProofCacheEntry);
- ctl.hash = tag_hash;
OprProofCacheHash = hash_create("Btree proof lookup cache", 256,
- &ctl, HASH_ELEM | HASH_FUNCTION);
+ &ctl, HASH_ELEM | HASH_BLOBS);
/* Arrange to flush cache on pg_amop changes */
CacheRegisterSyscacheCallback(AMOPOPID,
MemSet(&ctl, 0, sizeof(ctl));
ctl.keysize = sizeof(OprCacheKey);
ctl.entrysize = sizeof(OprCacheEntry);
- ctl.hash = tag_hash;
OprCacheHash = hash_create("Operator lookup cache", 256,
- &ctl, HASH_ELEM | HASH_FUNCTION);
+ &ctl, HASH_ELEM | HASH_BLOBS);
/* Arrange to flush cache on pg_operator and pg_cast changes */
CacheRegisterSyscacheCallback(OPERNAMENSP,
*/
hctl.keysize = sizeof(Oid);
hctl.entrysize = sizeof(avl_dbase);
- hctl.hash = oid_hash;
hctl.hcxt = tmpcxt;
dbhash = hash_create("db hash", 20, &hctl, /* magic number here FIXME */
- HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT);
+ HASH_ELEM | HASH_BLOBS | HASH_CONTEXT);
/* start by inserting the new database */
score = 0;
MemSet(&ctl, 0, sizeof(ctl));
ctl.keysize = sizeof(Oid);
ctl.entrysize = sizeof(av_relation);
- ctl.hash = oid_hash;
table_toast_map = hash_create("TOAST to main relid map",
100,
&ctl,
- HASH_ELEM | HASH_FUNCTION);
+ HASH_ELEM | HASH_BLOBS);
/*
* Scan pg_class to determine which tables to vacuum.
MemSet(&ctl, 0, sizeof(ctl));
ctl.keysize = sizeof(CheckpointerRequest);
ctl.entrysize = sizeof(struct CheckpointerSlotMapping);
- ctl.hash = tag_hash;
ctl.hcxt = CurrentMemoryContext;
htab = hash_create("CompactCheckpointerRequestQueue",
CheckpointerShmem->num_requests,
&ctl,
- HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT);
+ HASH_ELEM | HASH_BLOBS | HASH_CONTEXT);
/*
* The basic idea here is that a request can be skipped if it's followed
memset(&hash_ctl, 0, sizeof(hash_ctl));
hash_ctl.keysize = sizeof(Oid);
hash_ctl.entrysize = sizeof(Oid);
- hash_ctl.hash = oid_hash;
hash_ctl.hcxt = CurrentMemoryContext;
htab = hash_create("Temporary table of OIDs",
PGSTAT_TAB_HASH_SIZE,
&hash_ctl,
- HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT);
+ HASH_ELEM | HASH_BLOBS | HASH_CONTEXT);
rel = heap_open(catalogid, AccessShareLock);
snapshot = RegisterSnapshot(GetLatestSnapshot());
memset(&hash_ctl, 0, sizeof(hash_ctl));
hash_ctl.keysize = sizeof(Oid);
hash_ctl.entrysize = sizeof(PgStat_BackendFunctionEntry);
- hash_ctl.hash = oid_hash;
pgStatFunctions = hash_create("Function stat entries",
PGSTAT_FUNCTION_HASH_SIZE,
&hash_ctl,
- HASH_ELEM | HASH_FUNCTION);
+ HASH_ELEM | HASH_BLOBS);
}
/* Get the stats entry for this function, create if necessary */
memset(&hash_ctl, 0, sizeof(hash_ctl));
hash_ctl.keysize = sizeof(Oid);
hash_ctl.entrysize = sizeof(PgStat_StatTabEntry);
- hash_ctl.hash = oid_hash;
dbentry->tables = hash_create("Per-database table",
PGSTAT_TAB_HASH_SIZE,
&hash_ctl,
- HASH_ELEM | HASH_FUNCTION);
+ HASH_ELEM | HASH_BLOBS);
hash_ctl.keysize = sizeof(Oid);
hash_ctl.entrysize = sizeof(PgStat_StatFuncEntry);
- hash_ctl.hash = oid_hash;
dbentry->functions = hash_create("Per-database function",
PGSTAT_FUNCTION_HASH_SIZE,
&hash_ctl,
- HASH_ELEM | HASH_FUNCTION);
+ HASH_ELEM | HASH_BLOBS);
}
/*
memset(&hash_ctl, 0, sizeof(hash_ctl));
hash_ctl.keysize = sizeof(Oid);
hash_ctl.entrysize = sizeof(PgStat_StatDBEntry);
- hash_ctl.hash = oid_hash;
hash_ctl.hcxt = pgStatLocalContext;
dbhash = hash_create("Databases hash", PGSTAT_DB_HASH_SIZE, &hash_ctl,
- HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT);
+ HASH_ELEM | HASH_BLOBS | HASH_CONTEXT);
/*
* Clear out global and archiver statistics so they start from zero in
memset(&hash_ctl, 0, sizeof(hash_ctl));
hash_ctl.keysize = sizeof(Oid);
hash_ctl.entrysize = sizeof(PgStat_StatTabEntry);
- hash_ctl.hash = oid_hash;
hash_ctl.hcxt = pgStatLocalContext;
dbentry->tables = hash_create("Per-database table",
PGSTAT_TAB_HASH_SIZE,
&hash_ctl,
- HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT);
+ HASH_ELEM | HASH_BLOBS | HASH_CONTEXT);
hash_ctl.keysize = sizeof(Oid);
hash_ctl.entrysize = sizeof(PgStat_StatFuncEntry);
- hash_ctl.hash = oid_hash;
hash_ctl.hcxt = pgStatLocalContext;
dbentry->functions = hash_create("Per-database function",
PGSTAT_FUNCTION_HASH_SIZE,
&hash_ctl,
- HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT);
+ HASH_ELEM | HASH_BLOBS | HASH_CONTEXT);
/*
* If requested, read the data from the database-specific
hash_ctl.keysize = sizeof(TransactionId);
hash_ctl.entrysize = sizeof(ReorderBufferTXNByIdEnt);
- hash_ctl.hash = tag_hash;
hash_ctl.hcxt = buffer->context;
buffer->by_txn = hash_create("ReorderBufferByXid", 1000, &hash_ctl,
- HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT);
+ HASH_ELEM | HASH_BLOBS | HASH_CONTEXT);
buffer->by_txn_last_xid = InvalidTransactionId;
buffer->by_txn_last_txn = NULL;
hash_ctl.keysize = sizeof(ReorderBufferTupleCidKey);
hash_ctl.entrysize = sizeof(ReorderBufferTupleCidEnt);
- hash_ctl.hash = tag_hash;
hash_ctl.hcxt = rb->context;
/*
*/
txn->tuplecid_hash =
hash_create("ReorderBufferTupleCid", txn->ntuplecids, &hash_ctl,
- HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT);
+ HASH_ELEM | HASH_BLOBS | HASH_CONTEXT);
dlist_foreach(iter, &txn->tuplecids)
{
memset(&hash_ctl, 0, sizeof(hash_ctl));
hash_ctl.keysize = sizeof(Oid);
hash_ctl.entrysize = sizeof(ReorderBufferToastEnt);
- hash_ctl.hash = tag_hash;
hash_ctl.hcxt = rb->context;
txn->toast_hash = hash_create("ReorderBufferToastHash", 5, &hash_ctl,
- HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT);
+ HASH_ELEM | HASH_BLOBS | HASH_CONTEXT);
}
/*
/* BufferTag maps to Buffer */
info.keysize = sizeof(BufferTag);
info.entrysize = sizeof(BufferLookupEnt);
- info.hash = tag_hash;
info.num_partitions = NUM_BUFFER_PARTITIONS;
SharedBufHash = ShmemInitHash("Shared Buffer Lookup Table",
size, size,
&info,
- HASH_ELEM | HASH_FUNCTION | HASH_PARTITION);
+ HASH_ELEM | HASH_BLOBS | HASH_PARTITION);
}
/*
MemSet(&hash_ctl, 0, sizeof(hash_ctl));
hash_ctl.keysize = sizeof(int32);
hash_ctl.entrysize = sizeof(PrivateRefCountArray);
- hash_ctl.hash = oid_hash; /* a bit more efficient than tag_hash */
PrivateRefCountHash = hash_create("PrivateRefCount", 100, &hash_ctl,
- HASH_ELEM | HASH_FUNCTION);
+ HASH_ELEM | HASH_BLOBS);
}
/*
MemSet(&info, 0, sizeof(info));
info.keysize = sizeof(BufferTag);
info.entrysize = sizeof(LocalBufferLookupEnt);
- info.hash = tag_hash;
LocalBufHash = hash_create("Local Buffer Lookup Table",
nbufs,
&info,
- HASH_ELEM | HASH_FUNCTION);
+ HASH_ELEM | HASH_BLOBS);
if (!LocalBufHash)
elog(ERROR, "could not initialize local buffer hash table");
InitLocks(void)
{
HASHCTL info;
- int hash_flags;
long init_table_size,
max_table_size;
bool found;
MemSet(&info, 0, sizeof(info));
info.keysize = sizeof(LOCKTAG);
info.entrysize = sizeof(LOCK);
- info.hash = tag_hash;
info.num_partitions = NUM_LOCK_PARTITIONS;
- hash_flags = (HASH_ELEM | HASH_FUNCTION | HASH_PARTITION);
LockMethodLockHash = ShmemInitHash("LOCK hash",
init_table_size,
max_table_size,
&info,
- hash_flags);
+ HASH_ELEM | HASH_BLOBS | HASH_PARTITION);
/* Assume an average of 2 holders per lock */
max_table_size *= 2;
info.entrysize = sizeof(PROCLOCK);
info.hash = proclock_hash;
info.num_partitions = NUM_LOCK_PARTITIONS;
- hash_flags = (HASH_ELEM | HASH_FUNCTION | HASH_PARTITION);
LockMethodProcLockHash = ShmemInitHash("PROCLOCK hash",
init_table_size,
max_table_size,
&info,
- hash_flags);
+ HASH_ELEM | HASH_FUNCTION | HASH_PARTITION);
/*
* Allocate fast-path structures.
info.keysize = sizeof(LOCALLOCKTAG);
info.entrysize = sizeof(LOCALLOCK);
- info.hash = tag_hash;
- hash_flags = (HASH_ELEM | HASH_FUNCTION);
LockMethodLocalHash = hash_create("LOCALLOCK hash",
16,
&info,
- hash_flags);
+ HASH_ELEM | HASH_BLOBS);
}
MemSet(&ctl, 0, sizeof(ctl));
ctl.keysize = sizeof(lwlock_stats_key);
ctl.entrysize = sizeof(lwlock_stats);
- ctl.hash = tag_hash;
ctl.hcxt = lwlock_stats_cxt;
lwlock_stats_htab = hash_create("lwlock stats", 16384, &ctl,
- HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT);
+ HASH_ELEM | HASH_BLOBS | HASH_CONTEXT);
if (!exit_registered)
{
on_shmem_exit(print_lwlock_stats, 0);
* the lock partition number from the hashcode.
*/
#define PredicateLockTargetTagHashCode(predicatelocktargettag) \
- (tag_hash((predicatelocktargettag), sizeof(PREDICATELOCKTARGETTAG)))
+ get_hash_value(PredicateLockTargetHash, predicatelocktargettag)
/*
* Given a predicate lock tag, and the hash for its target,
InitPredicateLocks(void)
{
HASHCTL info;
- int hash_flags;
long max_table_size;
Size requestSize;
bool found;
MemSet(&info, 0, sizeof(info));
info.keysize = sizeof(PREDICATELOCKTARGETTAG);
info.entrysize = sizeof(PREDICATELOCKTARGET);
- info.hash = tag_hash;
info.num_partitions = NUM_PREDICATELOCK_PARTITIONS;
- hash_flags = (HASH_ELEM | HASH_FUNCTION | HASH_PARTITION | HASH_FIXED_SIZE);
PredicateLockTargetHash = ShmemInitHash("PREDICATELOCKTARGET hash",
max_table_size,
max_table_size,
&info,
- hash_flags);
+ HASH_ELEM | HASH_BLOBS |
+ HASH_PARTITION | HASH_FIXED_SIZE);
/* Assume an average of 2 xacts per target */
max_table_size *= 2;
info.entrysize = sizeof(PREDICATELOCK);
info.hash = predicatelock_hash;
info.num_partitions = NUM_PREDICATELOCK_PARTITIONS;
- hash_flags = (HASH_ELEM | HASH_FUNCTION | HASH_PARTITION | HASH_FIXED_SIZE);
PredicateLockHash = ShmemInitHash("PREDICATELOCK hash",
max_table_size,
max_table_size,
&info,
- hash_flags);
+ HASH_ELEM | HASH_FUNCTION |
+ HASH_PARTITION | HASH_FIXED_SIZE);
/*
* Compute size for serializable transaction hashtable. Note these
MemSet(&info, 0, sizeof(info));
info.keysize = sizeof(SERIALIZABLEXIDTAG);
info.entrysize = sizeof(SERIALIZABLEXID);
- info.hash = tag_hash;
- hash_flags = (HASH_ELEM | HASH_FUNCTION | HASH_FIXED_SIZE);
SerializableXidHash = ShmemInitHash("SERIALIZABLEXID hash",
max_table_size,
max_table_size,
&info,
- hash_flags);
+ HASH_ELEM | HASH_BLOBS |
+ HASH_FIXED_SIZE);
/*
* Allocate space for tracking rw-conflicts in lists attached to the
MemSet(&hash_ctl, 0, sizeof(hash_ctl));
hash_ctl.keysize = sizeof(PREDICATELOCKTARGETTAG);
hash_ctl.entrysize = sizeof(LOCALPREDICATELOCK);
- hash_ctl.hash = tag_hash;
LocalPredicateLockHash = hash_create("Local predicate lock",
max_predicate_locks_per_xact,
&hash_ctl,
- HASH_ELEM | HASH_FUNCTION);
+ HASH_ELEM | HASH_BLOBS);
return snapshot;
}
MemSet(&hash_ctl, 0, sizeof(hash_ctl));
hash_ctl.keysize = sizeof(RelFileNode);
hash_ctl.entrysize = sizeof(PendingOperationEntry);
- hash_ctl.hash = tag_hash;
hash_ctl.hcxt = pendingOpsCxt;
pendingOpsTable = hash_create("Pending Ops Table",
100L,
&hash_ctl,
- HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT);
+ HASH_ELEM | HASH_BLOBS | HASH_CONTEXT);
pendingUnlinks = NIL;
}
}
MemSet(&ctl, 0, sizeof(ctl));
ctl.keysize = sizeof(RelFileNodeBackend);
ctl.entrysize = sizeof(SMgrRelationData);
- ctl.hash = tag_hash;
SMgrRelationHash = hash_create("smgr relation table", 400,
- &ctl, HASH_ELEM | HASH_FUNCTION);
+ &ctl, HASH_ELEM | HASH_BLOBS);
first_unowned_reln = NULL;
}
MemSet(&count_hash_ctl, 0, sizeof(count_hash_ctl));
count_hash_ctl.keysize = sizeof(int);
count_hash_ctl.entrysize = sizeof(DECountItem);
- count_hash_ctl.hash = tag_hash;
count_hash_ctl.hcxt = CurrentMemoryContext;
count_tab = hash_create("Array distinct element count table",
64,
&count_hash_ctl,
- HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT);
+ HASH_ELEM | HASH_BLOBS | HASH_CONTEXT);
/* Initialize counters. */
b_current = 1;
memset(&ctl, 0, sizeof(ctl));
ctl.keysize = sizeof(Oid);
ctl.entrysize = sizeof(collation_cache_entry);
- ctl.hash = oid_hash;
collation_cache = hash_create("Collation cache", 100, &ctl,
- HASH_ELEM | HASH_FUNCTION);
+ HASH_ELEM | HASH_BLOBS);
}
cache_entry = hash_search(collation_cache, &collation, HASH_ENTER, &found);
memset(&ctl, 0, sizeof(ctl));
ctl.keysize = sizeof(Oid);
ctl.entrysize = sizeof(RI_ConstraintInfo);
- ctl.hash = oid_hash;
ri_constraint_cache = hash_create("RI constraint cache",
RI_INIT_CONSTRAINTHASHSIZE,
- &ctl, HASH_ELEM | HASH_FUNCTION);
+ &ctl, HASH_ELEM | HASH_BLOBS);
/* Arrange to flush cache on pg_constraint changes */
CacheRegisterSyscacheCallback(CONSTROID,
memset(&ctl, 0, sizeof(ctl));
ctl.keysize = sizeof(RI_QueryKey);
ctl.entrysize = sizeof(RI_QueryHashEntry);
- ctl.hash = tag_hash;
ri_query_cache = hash_create("RI query cache",
RI_INIT_QUERYHASHSIZE,
- &ctl, HASH_ELEM | HASH_FUNCTION);
+ &ctl, HASH_ELEM | HASH_BLOBS);
memset(&ctl, 0, sizeof(ctl));
ctl.keysize = sizeof(RI_CompareKey);
ctl.entrysize = sizeof(RI_CompareHashEntry);
- ctl.hash = tag_hash;
ri_compare_cache = hash_create("RI compare cache",
RI_INIT_QUERYHASHSIZE,
- &ctl, HASH_ELEM | HASH_FUNCTION);
+ &ctl, HASH_ELEM | HASH_BLOBS);
}
MemSet(&ctl, 0, sizeof(ctl));
ctl.keysize = sizeof(AttoptCacheKey);
ctl.entrysize = sizeof(AttoptCacheEntry);
- ctl.hash = tag_hash;
AttoptCacheHash =
hash_create("Attopt cache", 256, &ctl,
- HASH_ELEM | HASH_FUNCTION);
+ HASH_ELEM | HASH_BLOBS);
/* Make sure we've initialized CacheMemoryContext. */
if (!CacheMemoryContext)
MemSet(&ctl, 0, sizeof(ctl));
ctl.keysize = sizeof(EventTriggerEvent);
ctl.entrysize = sizeof(EventTriggerCacheEntry);
- ctl.hash = tag_hash;
ctl.hcxt = EventTriggerCacheContext;
cache = hash_create("Event Trigger Cache", 32, &ctl,
- HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT);
+ HASH_ELEM | HASH_BLOBS | HASH_CONTEXT);
/*
* Prepare to scan pg_event_trigger in name order.
MemSet(&ctl, 0, sizeof(ctl));
ctl.keysize = sizeof(Oid);
ctl.entrysize = sizeof(OpClassCacheEnt);
- ctl.hash = oid_hash;
OpClassCache = hash_create("Operator class cache", 64,
- &ctl, HASH_ELEM | HASH_FUNCTION);
+ &ctl, HASH_ELEM | HASH_BLOBS);
/* Also make sure CacheMemoryContext exists */
if (!CacheMemoryContext)
MemSet(&ctl, 0, sizeof(ctl));
ctl.keysize = sizeof(Oid);
ctl.entrysize = sizeof(RelIdCacheEnt);
- ctl.hash = oid_hash;
RelationIdCache = hash_create("Relcache by OID", INITRELCACHESIZE,
- &ctl, HASH_ELEM | HASH_FUNCTION);
+ &ctl, HASH_ELEM | HASH_BLOBS);
/*
* relation mapper needs to be initialized too
MemSet(&ctl, 0, sizeof(ctl));
ctl.keysize = sizeof(RelfilenodeMapKey);
ctl.entrysize = sizeof(RelfilenodeMapEntry);
- ctl.hash = tag_hash;
ctl.hcxt = CacheMemoryContext;
/*
*/
RelfilenodeMapHash =
hash_create("RelfilenodeMap cache", 1024, &ctl,
- HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT);
+ HASH_ELEM | HASH_BLOBS | HASH_CONTEXT);
/* Watch for invalidation events. */
CacheRegisterRelcacheCallback(RelfilenodeMapInvalidateCallback,
MemSet(&ctl, 0, sizeof(ctl));
ctl.keysize = sizeof(Oid);
ctl.entrysize = sizeof(TableSpaceCacheEntry);
- ctl.hash = oid_hash;
TableSpaceCacheHash =
hash_create("TableSpace cache", 16, &ctl,
- HASH_ELEM | HASH_FUNCTION);
+ HASH_ELEM | HASH_BLOBS);
/* Make sure we've initialized CacheMemoryContext. */
if (!CacheMemoryContext)
MemSet(&ctl, 0, sizeof(ctl));
ctl.keysize = sizeof(Oid);
ctl.entrysize = sizeof(TSParserCacheEntry);
- ctl.hash = oid_hash;
TSParserCacheHash = hash_create("Tsearch parser cache", 4,
- &ctl, HASH_ELEM | HASH_FUNCTION);
+ &ctl, HASH_ELEM | HASH_BLOBS);
/* Flush cache on pg_ts_parser changes */
CacheRegisterSyscacheCallback(TSPARSEROID, InvalidateTSCacheCallBack,
PointerGetDatum(TSParserCacheHash));
MemSet(&ctl, 0, sizeof(ctl));
ctl.keysize = sizeof(Oid);
ctl.entrysize = sizeof(TSDictionaryCacheEntry);
- ctl.hash = oid_hash;
TSDictionaryCacheHash = hash_create("Tsearch dictionary cache", 8,
- &ctl, HASH_ELEM | HASH_FUNCTION);
+ &ctl, HASH_ELEM | HASH_BLOBS);
/* Flush cache on pg_ts_dict and pg_ts_template changes */
CacheRegisterSyscacheCallback(TSDICTOID, InvalidateTSCacheCallBack,
PointerGetDatum(TSDictionaryCacheHash));
MemSet(&ctl, 0, sizeof(ctl));
ctl.keysize = sizeof(Oid);
ctl.entrysize = sizeof(TSConfigCacheEntry);
- ctl.hash = oid_hash;
TSConfigCacheHash = hash_create("Tsearch configuration cache", 16,
- &ctl, HASH_ELEM | HASH_FUNCTION);
+ &ctl, HASH_ELEM | HASH_BLOBS);
/* Flush cache on pg_ts_config and pg_ts_config_map changes */
CacheRegisterSyscacheCallback(TSCONFIGOID, InvalidateTSCacheCallBack,
PointerGetDatum(TSConfigCacheHash));
MemSet(&ctl, 0, sizeof(ctl));
ctl.keysize = sizeof(Oid);
ctl.entrysize = sizeof(TypeCacheEntry);
- ctl.hash = oid_hash;
TypeCacheHash = hash_create("Type information cache", 64,
- &ctl, HASH_ELEM | HASH_FUNCTION);
+ &ctl, HASH_ELEM | HASH_BLOBS);
/* Also set up callbacks for SI invalidations */
CacheRegisterRelcacheCallback(TypeCacheRelCallback, (Datum) 0);
MemSet(&ctl, 0, sizeof(ctl));
ctl.keysize = REC_HASH_KEYS * sizeof(Oid);
ctl.entrysize = sizeof(RecordCacheEntry);
- ctl.hash = tag_hash;
RecordCacheHash = hash_create("Record information cache", 64,
- &ctl, HASH_ELEM | HASH_FUNCTION);
+ &ctl, HASH_ELEM | HASH_BLOBS);
/* Also make sure CacheMemoryContext exists */
if (!CacheMemoryContext)
MemSet(&hash_ctl, 0, sizeof(hash_ctl));
hash_ctl.keysize = sizeof(Oid);
hash_ctl.entrysize = sizeof(CFuncHashTabEntry);
- hash_ctl.hash = oid_hash;
CFuncHash = hash_create("CFuncHash",
100,
&hash_ctl,
- HASH_ELEM | HASH_FUNCTION);
+ HASH_ELEM | HASH_BLOBS);
}
entry = (CFuncHashTabEntry *)
* in local memory, we typically use palloc() which will throw error on
* failure. The code in this file has to cope with both cases.
*
+ * dynahash.c provides support for these types of lookup keys:
+ *
+ * 1. Null-terminated C strings (truncated if necessary to fit in keysize),
+ * compared as though by strcmp(). This is the default behavior.
+ *
+ * 2. Arbitrary binary data of size keysize, compared as though by memcmp().
+ * (Caller must ensure there are no undefined padding bits in the keys!)
+ * This is selected by specifying HASH_BLOBS flag to hash_create.
+ *
+ * 3. More complex key behavior can be selected by specifying user-supplied
+ * hashing, comparison, and/or key-copying functions. At least a hashing
+ * function must be supplied; comparison defaults to memcmp() and key copying
+ * to memcpy() when a user-defined hashing function is selected.
+ *
* Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
hashp->tabname = (char *) (hashp + 1);
strcpy(hashp->tabname, tabname);
+ /*
+ * Select the appropriate hash function (see comments at head of file).
+ */
if (flags & HASH_FUNCTION)
hashp->hash = info->hash;
+ else if (flags & HASH_BLOBS)
+ {
+ /* We can optimize hashing for common key sizes */
+ Assert(flags & HASH_ELEM);
+ if (info->keysize == sizeof(uint32))
+ hashp->hash = uint32_hash;
+ else
+ hashp->hash = tag_hash;
+ }
else
hashp->hash = string_hash; /* default hash function */
/*
* 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.)
+ * otherwise.
+ *
+ * Note: explicitly specifying string_hash is deprecated, because this
+ * might not work for callers in loadable modules on some platforms due to
+ * referencing a trampoline instead of the string_hash function proper.
+ * Just let it default, eh?
*/
if (flags & HASH_COMPARE)
hashp->match = info->match;
else
hashp->keycopy = memcpy;
+ /* And select the entry allocation function, too. */
if (flags & HASH_ALLOC)
hashp->alloc = info->alloc;
else
}
/*
- * oid_hash: hash function for keys that are OIDs
+ * uint32_hash: hash function for keys that are uint32 or int32
*
* (tag_hash works for this case too, but is slower)
*/
uint32
-oid_hash(const void *key, Size keysize)
+uint32_hash(const void *key, Size keysize)
{
- Assert(keysize == sizeof(Oid));
- return DatumGetUInt32(hash_uint32((uint32) *((const Oid *) key)));
+ Assert(keysize == sizeof(uint32));
+ return DatumGetUInt32(hash_uint32(*((const uint32 *) key)));
}
/*
memset(&hash_ctl, 0, sizeof(hash_ctl));
hash_ctl.keysize = sizeof(ComboCidKeyData);
hash_ctl.entrysize = sizeof(ComboCidEntryData);
- hash_ctl.hash = tag_hash;
hash_ctl.hcxt = TopTransactionContext;
comboHash = hash_create("Combo CIDs",
CCID_HASH_SIZE,
&hash_ctl,
- HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT);
+ HASH_ELEM | HASH_BLOBS | HASH_CONTEXT);
comboCids = (ComboCidKeyData *)
MemoryContextAlloc(TopTransactionContext,
/*
* Key copying functions must have this signature. The return value is not
- * used. (The definition is set up to allow memcpy() and strncpy() to be
+ * used. (The definition is set up to allow memcpy() and strlcpy() to be
* used directly.)
*/
typedef void *(*HashCopyFunc) (void *dest, const void *src, Size keysize);
} HASHCTL;
/* Flags to indicate which parameters are supplied */
-#define HASH_PARTITION 0x001 /* Hashtable is used w/partitioned locking */
-#define HASH_SEGMENT 0x002 /* Set segment size */
-#define HASH_DIRSIZE 0x004 /* Set directory size (initial and max) */
-#define HASH_FFACTOR 0x008 /* Set fill factor */
-#define HASH_FUNCTION 0x010 /* Set user defined hash function */
-#define HASH_ELEM 0x020 /* Set keysize and entrysize */
-#define HASH_SHARED_MEM 0x040 /* Hashtable is in shared memory */
-#define HASH_ATTACH 0x080 /* Do not initialize hctl */
-#define HASH_ALLOC 0x100 /* Set memory allocator */
-#define HASH_CONTEXT 0x200 /* Set memory allocation context */
-#define HASH_COMPARE 0x400 /* Set user defined comparison function */
-#define HASH_KEYCOPY 0x800 /* Set user defined key-copying function */
-#define HASH_FIXED_SIZE 0x1000 /* Initial size is a hard limit */
+#define HASH_PARTITION 0x0001 /* Hashtable is used w/partitioned locking */
+#define HASH_SEGMENT 0x0002 /* Set segment size */
+#define HASH_DIRSIZE 0x0004 /* Set directory size (initial and max) */
+#define HASH_FFACTOR 0x0008 /* Set fill factor */
+#define HASH_ELEM 0x0010 /* Set keysize and entrysize */
+#define HASH_BLOBS 0x0020 /* Select support functions for binary keys */
+#define HASH_FUNCTION 0x0040 /* Set user defined hash function */
+#define HASH_COMPARE 0x0080 /* Set user defined comparison function */
+#define HASH_KEYCOPY 0x0100 /* Set user defined key-copying function */
+#define HASH_ALLOC 0x0200 /* Set memory allocator */
+#define HASH_CONTEXT 0x0400 /* Set memory allocation context */
+#define HASH_SHARED_MEM 0x0800 /* Hashtable is in shared memory */
+#define HASH_ATTACH 0x1000 /* Do not initialize hctl */
+#define HASH_FIXED_SIZE 0x2000 /* Initial size is a hard limit */
/* max_dsize value to indicate expansible directory */
/*
* prototypes for functions in hashfn.c
+ *
+ * Note: It is deprecated for callers of hash_create to explicitly specify
+ * 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 uint32 string_hash(const void *key, Size keysize);
extern uint32 tag_hash(const void *key, Size keysize);
-extern uint32 oid_hash(const void *key, Size keysize);
+extern uint32 uint32_hash(const void *key, Size keysize);
extern uint32 bitmap_hash(const void *key, Size keysize);
extern int bitmap_match(const void *key1, const void *key2, Size keysize);
+#define oid_hash uint32_hash /* Remove me eventually */
+
#endif /* HSEARCH_H */
memset(&hash_ctl, 0, sizeof(hash_ctl));
hash_ctl.keysize = sizeof(Oid);
hash_ctl.entrysize = sizeof(plperl_interp_desc);
- hash_ctl.hash = oid_hash;
plperl_interp_hash = hash_create("PL/Perl interpreters",
8,
&hash_ctl,
- HASH_ELEM | HASH_FUNCTION);
+ HASH_ELEM | HASH_BLOBS);
memset(&hash_ctl, 0, sizeof(hash_ctl));
hash_ctl.keysize = sizeof(plperl_proc_key);
hash_ctl.entrysize = sizeof(plperl_proc_ptr);
- hash_ctl.hash = tag_hash;
plperl_proc_hash = hash_create("PL/Perl procedures",
32,
&hash_ctl,
- HASH_ELEM | HASH_FUNCTION);
+ HASH_ELEM | HASH_BLOBS);
/*
* Save the default opmask.
memset(&ctl, 0, sizeof(ctl));
ctl.keysize = sizeof(PLpgSQL_func_hashkey);
ctl.entrysize = sizeof(plpgsql_HashEnt);
- ctl.hash = tag_hash;
plpgsql_HashTable = hash_create("PLpgSQL function cache",
FUNCS_PER_USER,
&ctl,
- HASH_ELEM | HASH_FUNCTION);
+ HASH_ELEM | HASH_BLOBS);
}
static PLpgSQL_function *
memset(&hash_ctl, 0, sizeof(hash_ctl));
hash_ctl.keysize = sizeof(int);
hash_ctl.entrysize = sizeof(PLyExceptionEntry);
- hash_ctl.hash = tag_hash;
PLy_spi_exceptions = hash_create("SPI exceptions", 256,
- &hash_ctl, HASH_ELEM | HASH_FUNCTION);
+ &hash_ctl, HASH_ELEM | HASH_BLOBS);
PLy_generate_spi_exceptions(excmod, PLy_exc_spi_error);
}
memset(&hash_ctl, 0, sizeof(hash_ctl));
hash_ctl.keysize = sizeof(PLyProcedureKey);
hash_ctl.entrysize = sizeof(PLyProcedureEntry);
- hash_ctl.hash = tag_hash;
PLy_procedure_cache = hash_create("PL/Python procedures", 32, &hash_ctl,
- HASH_ELEM | HASH_FUNCTION);
+ HASH_ELEM | HASH_BLOBS);
}
/*
memset(&hash_ctl, 0, sizeof(hash_ctl));
hash_ctl.keysize = sizeof(Oid);
hash_ctl.entrysize = sizeof(pltcl_interp_desc);
- hash_ctl.hash = oid_hash;
pltcl_interp_htab = hash_create("PL/Tcl interpreters",
8,
&hash_ctl,
- HASH_ELEM | HASH_FUNCTION);
+ HASH_ELEM | HASH_BLOBS);
/************************************************************
* Create the hash table for function lookup
memset(&hash_ctl, 0, sizeof(hash_ctl));
hash_ctl.keysize = sizeof(pltcl_proc_key);
hash_ctl.entrysize = sizeof(pltcl_proc_ptr);
- hash_ctl.hash = tag_hash;
pltcl_proc_htab = hash_create("PL/Tcl functions",
100,
&hash_ctl,
- HASH_ELEM | HASH_FUNCTION);
+ HASH_ELEM | HASH_BLOBS);
pltcl_pm_init_done = true;
}