aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/access/transam/xlogutils.c12
-rw-r--r--src/backend/postmaster/pgstat.c109
-rw-r--r--src/backend/storage/buffer/buf_init.c10
-rw-r--r--src/backend/storage/buffer/buf_table.c44
-rw-r--r--src/backend/storage/freespace/freespace.c19
-rw-r--r--src/backend/storage/ipc/shmem.c24
-rw-r--r--src/backend/storage/lmgr/lock.c41
-rw-r--r--src/backend/storage/smgr/mm.c49
-rw-r--r--src/backend/utils/adt/ri_triggers.c27
-rw-r--r--src/backend/utils/cache/relcache.c30
-rw-r--r--src/backend/utils/hash/dynahash.c558
-rw-r--r--src/backend/utils/hash/hashfn.c160
-rw-r--r--src/backend/utils/mmgr/portalmem.c4
-rw-r--r--src/include/storage/buf_internals.h9
-rw-r--r--src/include/storage/lock.h8
-rw-r--r--src/include/storage/shmem.h6
-rw-r--r--src/include/utils/hsearch.h100
17 files changed, 526 insertions, 684 deletions
diff --git a/src/backend/access/transam/xlogutils.c b/src/backend/access/transam/xlogutils.c
index 4cae914cf41..8bd55026d42 100644
--- a/src/backend/access/transam/xlogutils.c
+++ b/src/backend/access/transam/xlogutils.c
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Header: /cvsroot/pgsql/src/backend/access/transam/xlogutils.c,v 1.18 2001/08/25 18:52:41 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/transam/xlogutils.c,v 1.19 2001/10/01 05:36:13 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -228,9 +228,9 @@ _xl_init_rel_cache(void)
_xlrelarr[0].moreRecently = &(_xlrelarr[0]);
_xlrelarr[0].lessRecently = &(_xlrelarr[0]);
- memset(&ctl, 0, (int) sizeof(ctl));
+ memset(&ctl, 0, sizeof(ctl));
ctl.keysize = sizeof(RelFileNode);
- ctl.datasize = sizeof(XLogRelDesc *);
+ ctl.entrysize = sizeof(XLogRelCacheEntry);
ctl.hash = tag_hash;
_xlrelcache = hash_create(_XLOG_RELCACHESIZE, &ctl,
@@ -249,7 +249,7 @@ _xl_remove_hash_entry(XLogRelDesc **edata, Datum dummy)
rdesc->moreRecently->lessRecently = rdesc->lessRecently;
hentry = (XLogRelCacheEntry *) hash_search(_xlrelcache,
- (char *) &(rdesc->reldata.rd_node), HASH_REMOVE, &found);
+ (void *) &(rdesc->reldata.rd_node), HASH_REMOVE, &found);
if (hentry == NULL)
elog(STOP, "_xl_remove_hash_entry: can't delete from cache");
@@ -321,7 +321,7 @@ XLogOpenRelation(bool redo, RmgrId rmid, RelFileNode rnode)
bool found;
hentry = (XLogRelCacheEntry *)
- hash_search(_xlrelcache, (char *) &rnode, HASH_FIND, &found);
+ hash_search(_xlrelcache, (void *) &rnode, HASH_FIND, &found);
if (hentry == NULL)
elog(STOP, "XLogOpenRelation: error in cache");
@@ -345,7 +345,7 @@ XLogOpenRelation(bool redo, RmgrId rmid, RelFileNode rnode)
res->reldata.rd_node = rnode;
hentry = (XLogRelCacheEntry *)
- hash_search(_xlrelcache, (char *) &rnode, HASH_ENTER, &found);
+ hash_search(_xlrelcache, (void *) &rnode, HASH_ENTER, &found);
if (hentry == NULL)
elog(STOP, "XLogOpenRelation: can't insert into cache");
diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c
index 298e3470d96..6c8ed373a87 100644
--- a/src/backend/postmaster/pgstat.c
+++ b/src/backend/postmaster/pgstat.c
@@ -16,7 +16,7 @@
*
* Copyright (c) 2001, PostgreSQL Global Development Group
*
- * $Header: /cvsroot/pgsql/src/backend/postmaster/pgstat.c,v 1.7 2001/08/23 23:06:37 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/postmaster/pgstat.c,v 1.8 2001/10/01 05:36:13 tgl Exp $
* ----------
*/
#include "postgres.h"
@@ -511,7 +511,8 @@ pgstat_vacuum_tabstat(void)
* Lookup our own database entry
*/
dbentry = (PgStat_StatDBEntry *)hash_search(pgStatDBHash,
- (char *)&MyDatabaseId, HASH_FIND, &found);
+ (void *) &MyDatabaseId,
+ HASH_FIND, &found);
if (!found || dbentry == NULL)
return -1;
@@ -926,8 +927,9 @@ pgstat_fetch_stat_dbentry(Oid dbid)
/*
* Lookup the requested database
*/
- dbentry = (PgStat_StatDBEntry *)hash_search(pgStatDBHash,
- (char *)&dbid, HASH_FIND, &found);
+ dbentry = (PgStat_StatDBEntry *) hash_search(pgStatDBHash,
+ (void *) &dbid,
+ HASH_FIND, &found);
if (!found || dbentry == NULL)
return NULL;
@@ -966,8 +968,9 @@ pgstat_fetch_stat_tabentry(Oid relid)
/*
* Lookup our database.
*/
- dbentry = (PgStat_StatDBEntry *)hash_search(pgStatDBHash,
- (char *)&MyDatabaseId, HASH_FIND, &found);
+ dbentry = (PgStat_StatDBEntry *) hash_search(pgStatDBHash,
+ (void *) &MyDatabaseId,
+ HASH_FIND, &found);
if (!found || dbentry == NULL)
return NULL;
@@ -976,8 +979,9 @@ pgstat_fetch_stat_tabentry(Oid relid)
*/
if (dbentry->tables == NULL)
return NULL;
- tabentry = (PgStat_StatTabEntry *)hash_search(dbentry->tables,
- (char *)&relid, HASH_FIND, &found);
+ tabentry = (PgStat_StatTabEntry *) hash_search(dbentry->tables,
+ (void *) &relid,
+ HASH_FIND, &found);
if (!found || tabentry == NULL)
return NULL;
@@ -1197,9 +1201,9 @@ pgstat_main(int real_argc, char *real_argv[])
* Create the dead backend hashtable
*/
memset(&hash_ctl, 0, sizeof(hash_ctl));
- hash_ctl.keysize = sizeof(int);
- hash_ctl.datasize = sizeof(PgStat_StatBeDead);
- hash_ctl.hash = tag_hash;
+ hash_ctl.keysize = sizeof(int);
+ hash_ctl.entrysize = sizeof(PgStat_StatBeDead);
+ hash_ctl.hash = tag_hash;
pgStatBeDead = hash_create(PGSTAT_BE_HASH_SIZE, &hash_ctl,
HASH_ELEM | HASH_FUNCTION);
if (pgStatBeDead == NULL)
@@ -1720,8 +1724,9 @@ pgstat_add_backend(PgStat_MsgHdr *msg)
*
* If the backend is known to be dead, we ignore this add.
*/
- deadbe = (PgStat_StatBeDead *)hash_search(pgStatBeDead,
- (char *)&(msg->m_procpid), HASH_FIND, &found);
+ deadbe = (PgStat_StatBeDead *) hash_search(pgStatBeDead,
+ (void *) &(msg->m_procpid),
+ HASH_FIND, &found);
if (deadbe == NULL)
{
fprintf(stderr, "PGSTAT: Dead backend table corrupted - abort\n");
@@ -1747,9 +1752,9 @@ pgstat_add_backend(PgStat_MsgHdr *msg)
/*
* Lookup or create the database entry for this backends DB.
*/
- dbentry = (PgStat_StatDBEntry *)hash_search(pgStatDBHash,
- (char *)&(msg->m_databaseid), HASH_ENTER,
- &found);
+ dbentry = (PgStat_StatDBEntry *) hash_search(pgStatDBHash,
+ (void *) &(msg->m_databaseid),
+ HASH_ENTER, &found);
if (dbentry == NULL)
{
fprintf(stderr, "PGSTAT: DB hash table corrupted - abort\n");
@@ -1772,9 +1777,9 @@ pgstat_add_backend(PgStat_MsgHdr *msg)
dbentry->destroy = 0;
memset(&hash_ctl, 0, sizeof(hash_ctl));
- hash_ctl.keysize = sizeof(Oid);
- hash_ctl.datasize = sizeof(PgStat_StatTabEntry);
- hash_ctl.hash = tag_hash;
+ hash_ctl.keysize = sizeof(Oid);
+ hash_ctl.entrysize = sizeof(PgStat_StatTabEntry);
+ hash_ctl.hash = tag_hash;
dbentry->tables = hash_create(PGSTAT_TAB_HASH_SIZE, &hash_ctl,
HASH_ELEM | HASH_FUNCTION);
if (dbentry->tables == NULL)
@@ -1827,8 +1832,9 @@ pgstat_sub_backend(int procpid)
* the counting of backends, not the table access stats they
* sent).
*/
- deadbe = (PgStat_StatBeDead *)hash_search(pgStatBeDead,
- (char *)&procpid, HASH_ENTER, &found);
+ deadbe = (PgStat_StatBeDead *) hash_search(pgStatBeDead,
+ (void *) &procpid,
+ HASH_ENTER, &found);
if (deadbe == NULL)
{
fprintf(stderr, "PGSTAT: dead backend hash table corrupted "
@@ -1914,8 +1920,8 @@ pgstat_write_statsfile(void)
hash_destroy(dbentry->tables);
hentry = hash_search(pgStatDBHash,
- (char *)&(dbentry->databaseid),
- HASH_REMOVE, &found);
+ (void *) &(dbentry->databaseid),
+ HASH_REMOVE, &found);
if (hentry == NULL)
{
fprintf(stderr, "PGSTAT: database hash table corrupted "
@@ -1959,7 +1965,7 @@ pgstat_write_statsfile(void)
if (--(tabentry->destroy) == 0)
{
hentry = hash_search(dbentry->tables,
- (char *)&(tabentry->tableid),
+ (void *) &(tabentry->tableid),
HASH_REMOVE, &found);
if (hentry == NULL)
{
@@ -2047,7 +2053,8 @@ pgstat_write_statsfile(void)
*/
if (--(deadbe->destroy) <= 0)
{
- hentry = hash_search(pgStatBeDead, (char *)&(deadbe->procpid),
+ hentry = hash_search(pgStatBeDead,
+ (void *) &(deadbe->procpid),
HASH_REMOVE, &found);
if (hentry == NULL)
{
@@ -2107,10 +2114,10 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
* Create the DB hashtable
*/
memset(&hash_ctl, 0, sizeof(hash_ctl));
- hash_ctl.keysize = sizeof(Oid);
- hash_ctl.datasize = sizeof(PgStat_StatDBEntry);
- hash_ctl.hash = tag_hash;
- hash_ctl.hcxt = use_mcxt;
+ hash_ctl.keysize = sizeof(Oid);
+ hash_ctl.entrysize = sizeof(PgStat_StatDBEntry);
+ hash_ctl.hash = tag_hash;
+ hash_ctl.hcxt = use_mcxt;
*dbhash = hash_create(PGSTAT_DB_HASH_SIZE, &hash_ctl,
HASH_ELEM | HASH_FUNCTION | mcxt_flags);
if (pgStatDBHash == NULL)
@@ -2175,8 +2182,8 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
/*
* Add to the DB hash
*/
- dbentry = (PgStat_StatDBEntry *)hash_search(*dbhash,
- (char *)&dbbuf.databaseid,
+ dbentry = (PgStat_StatDBEntry *) hash_search(*dbhash,
+ (void *) &dbbuf.databaseid,
HASH_ENTER, &found);
if (dbentry == NULL)
{
@@ -2222,10 +2229,10 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
memset(&hash_ctl, 0, sizeof(hash_ctl));
- hash_ctl.keysize = sizeof(Oid);
- hash_ctl.datasize = sizeof(PgStat_StatTabEntry);
- hash_ctl.hash = tag_hash;
- hash_ctl.hcxt = use_mcxt;
+ hash_ctl.keysize = sizeof(Oid);
+ hash_ctl.entrysize = sizeof(PgStat_StatTabEntry);
+ hash_ctl.hash = tag_hash;
+ hash_ctl.hcxt = use_mcxt;
dbentry->tables = hash_create(PGSTAT_TAB_HASH_SIZE, &hash_ctl,
HASH_ELEM | HASH_FUNCTION | mcxt_flags);
if (dbentry->tables == NULL)
@@ -2286,8 +2293,8 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
if (tabhash == NULL)
break;
- tabentry = (PgStat_StatTabEntry *)hash_search(tabhash,
- (char *)&tabbuf.tableid,
+ tabentry = (PgStat_StatTabEntry *) hash_search(tabhash,
+ (void *) &tabbuf.tableid,
HASH_ENTER, &found);
if (tabentry == NULL)
{
@@ -2411,7 +2418,7 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
* Count backends per database here.
*/
dbentry = (PgStat_StatDBEntry *)hash_search(*dbhash,
- (char *)&((*betab)[havebackends].databaseid),
+ (void *) &((*betab)[havebackends].databaseid),
HASH_FIND, &found);
if (found)
dbentry->n_backends++;
@@ -2525,8 +2532,8 @@ pgstat_recv_tabstat(PgStat_MsgTabstat *msg, int len)
/*
* Lookup the database in the hashtable.
*/
- dbentry = (PgStat_StatDBEntry *)hash_search(pgStatDBHash,
- (char *)&(msg->m_hdr.m_databaseid),
+ dbentry = (PgStat_StatDBEntry *) hash_search(pgStatDBHash,
+ (void *) &(msg->m_hdr.m_databaseid),
HASH_FIND, &found);
if (dbentry == NULL)
{
@@ -2551,8 +2558,8 @@ pgstat_recv_tabstat(PgStat_MsgTabstat *msg, int len)
*/
for (i = 0; i < msg->m_nentries; i++)
{
- tabentry = (PgStat_StatTabEntry *)hash_search(dbentry->tables,
- (char *)&(tabmsg[i].t_id),
+ tabentry = (PgStat_StatTabEntry *) hash_search(dbentry->tables,
+ (void *) &(tabmsg[i].t_id),
HASH_ENTER, &found);
if (tabentry == NULL)
{
@@ -2625,8 +2632,8 @@ pgstat_recv_tabpurge(PgStat_MsgTabpurge *msg, int len)
/*
* Lookup the database in the hashtable.
*/
- dbentry = (PgStat_StatDBEntry *)hash_search(pgStatDBHash,
- (char *)&(msg->m_hdr.m_databaseid),
+ dbentry = (PgStat_StatDBEntry *) hash_search(pgStatDBHash,
+ (void *) &(msg->m_hdr.m_databaseid),
HASH_FIND, &found);
if (dbentry == NULL)
{
@@ -2648,8 +2655,8 @@ pgstat_recv_tabpurge(PgStat_MsgTabpurge *msg, int len)
*/
for (i = 0; i < msg->m_nentries; i++)
{
- tabentry = (PgStat_StatTabEntry *)hash_search(dbentry->tables,
- (char *)&(msg->m_tableid[i]),
+ tabentry = (PgStat_StatTabEntry *) hash_search(dbentry->tables,
+ (void *) &(msg->m_tableid[i]),
HASH_FIND, &found);
if (tabentry == NULL)
{
@@ -2685,8 +2692,8 @@ pgstat_recv_dropdb(PgStat_MsgDropdb *msg, int len)
/*
* Lookup the database in the hashtable.
*/
- dbentry = (PgStat_StatDBEntry *)hash_search(pgStatDBHash,
- (char *)&(msg->m_databaseid),
+ dbentry = (PgStat_StatDBEntry *) hash_search(pgStatDBHash,
+ (void *) &(msg->m_databaseid),
HASH_FIND, &found);
if (dbentry == NULL)
{
@@ -2725,8 +2732,8 @@ pgstat_recv_resetcounter(PgStat_MsgResetcounter *msg, int len)
/*
* Lookup the database in the hashtable.
*/
- dbentry = (PgStat_StatDBEntry *)hash_search(pgStatDBHash,
- (char *)&(msg->m_hdr.m_databaseid),
+ dbentry = (PgStat_StatDBEntry *) hash_search(pgStatDBHash,
+ (void *) &(msg->m_hdr.m_databaseid),
HASH_FIND, &found);
if (dbentry == NULL)
{
@@ -2753,7 +2760,7 @@ pgstat_recv_resetcounter(PgStat_MsgResetcounter *msg, int len)
memset(&hash_ctl, 0, sizeof(hash_ctl));
hash_ctl.keysize = sizeof(Oid);
- hash_ctl.datasize = sizeof(PgStat_StatTabEntry);
+ hash_ctl.entrysize = sizeof(PgStat_StatTabEntry);
hash_ctl.hash = tag_hash;
dbentry->tables = hash_create(PGSTAT_TAB_HASH_SIZE, &hash_ctl,
HASH_ELEM | HASH_FUNCTION);
diff --git a/src/backend/storage/buffer/buf_init.c b/src/backend/storage/buffer/buf_init.c
index 45a2e4aa160..322c45b0319 100644
--- a/src/backend/storage/buffer/buf_init.c
+++ b/src/backend/storage/buffer/buf_init.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/buffer/buf_init.c,v 1.44 2001/09/29 04:02:22 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/buffer/buf_init.c,v 1.45 2001/10/01 05:36:13 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -280,9 +280,7 @@ BufferShmemSize(void)
int size = 0;
/* size of shmem index hash table */
- size += hash_estimate_size(SHMEM_INDEX_SIZE,
- SHMEM_INDEX_KEYSIZE,
- SHMEM_INDEX_DATASIZE);
+ size += hash_estimate_size(SHMEM_INDEX_SIZE, sizeof(ShmemIndexEnt));
/* size of buffer descriptors */
size += MAXALIGN((NBuffers + 1) * sizeof(BufferDesc));
@@ -291,9 +289,7 @@ BufferShmemSize(void)
size += NBuffers * MAXALIGN(BLCKSZ);
/* size of buffer hash table */
- size += hash_estimate_size(NBuffers,
- sizeof(BufferTag),
- sizeof(Buffer));
+ size += hash_estimate_size(NBuffers, sizeof(BufferLookupEnt));
#ifdef BMTRACE
size += (BMT_LIMIT * sizeof(bmtrace)) + sizeof(long);
diff --git a/src/backend/storage/buffer/buf_table.c b/src/backend/storage/buffer/buf_table.c
index 671b13efa0f..85b747b442f 100644
--- a/src/backend/storage/buffer/buf_table.c
+++ b/src/backend/storage/buffer/buf_table.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/buffer/buf_table.c,v 1.22 2001/09/29 04:02:22 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/buffer/buf_table.c,v 1.23 2001/10/01 05:36:13 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -33,54 +33,42 @@
static HTAB *SharedBufHash;
-typedef struct lookup
-{
- BufferTag key;
- Buffer id;
-} LookupEnt;
/*
* Initialize shmem hash table for mapping buffers
*/
void
-InitBufTable()
+InitBufTable(void)
{
HASHCTL info;
- int hash_flags;
/* assume lock is held */
/* BufferTag maps to Buffer */
info.keysize = sizeof(BufferTag);
- info.datasize = sizeof(Buffer);
+ info.entrysize = sizeof(BufferLookupEnt);
info.hash = tag_hash;
- hash_flags = (HASH_ELEM | HASH_FUNCTION);
-
-
- SharedBufHash = (HTAB *) ShmemInitHash("Shared Buffer Lookup Table",
- NBuffers, NBuffers,
- &info, hash_flags);
+ SharedBufHash = ShmemInitHash("Shared Buffer Lookup Table",
+ NBuffers, NBuffers,
+ &info,
+ HASH_ELEM | HASH_FUNCTION);
if (!SharedBufHash)
- {
elog(FATAL, "couldn't initialize shared buffer pool Hash Tbl");
- exit(1);
- }
-
}
BufferDesc *
BufTableLookup(BufferTag *tagPtr)
{
- LookupEnt *result;
+ BufferLookupEnt *result;
bool found;
if (tagPtr->blockNum == P_NEW)
return NULL;
- result = (LookupEnt *)
- hash_search(SharedBufHash, (char *) tagPtr, HASH_FIND, &found);
+ result = (BufferLookupEnt *)
+ hash_search(SharedBufHash, (void *) tagPtr, HASH_FIND, &found);
if (!result)
{
@@ -98,7 +86,7 @@ BufTableLookup(BufferTag *tagPtr)
bool
BufTableDelete(BufferDesc *buf)
{
- LookupEnt *result;
+ BufferLookupEnt *result;
bool found;
/*
@@ -110,8 +98,8 @@ BufTableDelete(BufferDesc *buf)
buf->flags |= BM_DELETED;
- result = (LookupEnt *)
- hash_search(SharedBufHash, (char *) &(buf->tag), HASH_REMOVE, &found);
+ result = (BufferLookupEnt *)
+ hash_search(SharedBufHash, (void *) &(buf->tag), HASH_REMOVE, &found);
if (!(result && found))
{
@@ -134,15 +122,15 @@ BufTableDelete(BufferDesc *buf)
bool
BufTableInsert(BufferDesc *buf)
{
- LookupEnt *result;
+ BufferLookupEnt *result;
bool found;
/* cannot insert it twice */
Assert(buf->flags & BM_DELETED);
buf->flags &= ~(BM_DELETED);
- result = (LookupEnt *)
- hash_search(SharedBufHash, (char *) &(buf->tag), HASH_ENTER, &found);
+ result = (BufferLookupEnt *)
+ hash_search(SharedBufHash, (void *) &(buf->tag), HASH_ENTER, &found);
if (!result)
{
diff --git a/src/backend/storage/freespace/freespace.c b/src/backend/storage/freespace/freespace.c
index b20e8086157..f8fefee8a09 100644
--- a/src/backend/storage/freespace/freespace.c
+++ b/src/backend/storage/freespace/freespace.c
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/freespace/freespace.c,v 1.5 2001/09/29 04:02:23 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/freespace/freespace.c,v 1.6 2001/10/01 05:36:14 tgl Exp $
*
*
* NOTES:
@@ -100,9 +100,6 @@ struct FSMRelation
FSMChunk *relChunks; /* linked list of page info chunks */
};
-#define SHMEM_FSMHASH_KEYSIZE sizeof(RelFileNode)
-#define SHMEM_FSMHASH_DATASIZE (sizeof(FSMRelation) - SHMEM_FSMHASH_KEYSIZE)
-
/*
* Info about individual pages in a relation is stored in chunks to reduce
* allocation overhead. Note that we allow any chunk of a relation's list
@@ -180,8 +177,8 @@ InitFreeSpaceMap(void)
MemSet(FreeSpaceMap, 0, sizeof(FSMHeader));
/* Create hashtable for FSMRelations */
- info.keysize = SHMEM_FSMHASH_KEYSIZE;
- info.datasize = SHMEM_FSMHASH_DATASIZE;
+ info.keysize = sizeof(RelFileNode);
+ info.entrysize = sizeof(FSMRelation);
info.hash = tag_hash;
FreeSpaceMap->relHash = ShmemInitHash("Free Space Map Hash",
@@ -224,9 +221,7 @@ FreeSpaceShmemSize(void)
size = MAXALIGN(sizeof(FSMHeader));
/* hash table, including the FSMRelation objects */
- size += hash_estimate_size(MaxFSMRelations,
- SHMEM_FSMHASH_KEYSIZE,
- SHMEM_FSMHASH_DATASIZE);
+ size += hash_estimate_size(MaxFSMRelations, sizeof(FSMRelation));
/* FSMChunk objects */
nchunks = (MaxFSMPages - 1) / CHUNKPAGES + 1;
@@ -498,7 +493,7 @@ lookup_fsm_rel(RelFileNode *rel)
bool found;
fsmrel = (FSMRelation *) hash_search(FreeSpaceMap->relHash,
- (Pointer) rel,
+ (void *) rel,
HASH_FIND,
&found);
if (!fsmrel)
@@ -524,7 +519,7 @@ create_fsm_rel(RelFileNode *rel)
bool found;
fsmrel = (FSMRelation *) hash_search(FreeSpaceMap->relHash,
- (Pointer) rel,
+ (void *) rel,
HASH_ENTER,
&found);
if (!fsmrel)
@@ -595,7 +590,7 @@ delete_fsm_rel(FSMRelation *fsmrel)
unlink_fsm_rel(fsmrel);
FreeSpaceMap->numRels--;
result = (FSMRelation *) hash_search(FreeSpaceMap->relHash,
- (Pointer) &(fsmrel->key),
+ (void *) &(fsmrel->key),
HASH_REMOVE,
&found);
if (!result || !found)
diff --git a/src/backend/storage/ipc/shmem.c b/src/backend/storage/ipc/shmem.c
index 0ad168680a1..024db5bd533 100644
--- a/src/backend/storage/ipc/shmem.c
+++ b/src/backend/storage/ipc/shmem.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/ipc/shmem.c,v 1.59 2001/09/29 04:02:23 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/ipc/shmem.c,v 1.60 2001/10/01 05:36:14 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -191,7 +191,7 @@ InitShmemIndex(void)
/* create the shared memory shmem index */
info.keysize = SHMEM_INDEX_KEYSIZE;
- info.datasize = SHMEM_INDEX_DATASIZE;
+ info.entrysize = sizeof(ShmemIndexEnt);
hash_flags = HASH_ELEM;
/* This will acquire the shmem index lock, but not release it. */
@@ -208,7 +208,7 @@ InitShmemIndex(void)
strncpy(item.key, "ShmemIndex", SHMEM_INDEX_KEYSIZE);
result = (ShmemIndexEnt *)
- hash_search(ShmemIndex, (char *) &item, HASH_ENTER, &found);
+ hash_search(ShmemIndex, (void *) &item, HASH_ENTER, &found);
if (!result)
elog(FATAL, "InitShmemIndex: corrupted shmem index");
@@ -248,17 +248,15 @@ ShmemInitHash(char *name, /* table string name for shmem index */
* can't grow or other backends wouldn't be able to find it. So, make
* sure we make it big enough to start with.
*
- * The segbase is for calculating pointer values. The shared memory
- * allocator must be specified too.
+ * The shared memory allocator must be specified too.
*/
infoP->dsize = infoP->max_dsize = hash_select_dirsize(max_size);
- infoP->segbase = (long *) ShmemBase;
infoP->alloc = ShmemAlloc;
hash_flags |= HASH_SHARED_MEM | HASH_DIRSIZE;
/* look it up in the shmem index */
location = ShmemInitStruct(name,
- sizeof(HHDR) + infoP->dsize * sizeof(SEG_OFFSET),
+ sizeof(HASHHDR) + infoP->dsize * sizeof(HASHSEGMENT),
&found);
/*
@@ -266,18 +264,18 @@ ShmemInitHash(char *name, /* table string name for shmem index */
* message since they have more information
*/
if (location == NULL)
- return 0;
+ return NULL;
/*
- * it already exists, attach to it rather than allocate and initialize
+ * if it already exists, attach to it rather than allocate and initialize
* new space
*/
if (found)
hash_flags |= HASH_ATTACH;
/* Now provide the header and directory pointers */
- infoP->hctl = (long *) location;
- infoP->dir = (long *) (((char *) location) + sizeof(HHDR));
+ infoP->hctl = (HASHHDR *) location;
+ infoP->dir = (HASHSEGMENT *) (((char *) location) + sizeof(HASHHDR));
return hash_create(init_size, infoP, hash_flags);
}
@@ -325,7 +323,7 @@ ShmemInitStruct(char *name, Size size, bool *foundPtr)
/* look it up in the shmem index */
result = (ShmemIndexEnt *)
- hash_search(ShmemIndex, (char *) &item, HASH_ENTER, foundPtr);
+ hash_search(ShmemIndex, (void *) &item, HASH_ENTER, foundPtr);
if (!result)
{
@@ -359,7 +357,7 @@ ShmemInitStruct(char *name, Size size, bool *foundPtr)
{
/* out of memory */
Assert(ShmemIndex);
- hash_search(ShmemIndex, (char *) &item, HASH_REMOVE, foundPtr);
+ hash_search(ShmemIndex, (void *) &item, HASH_REMOVE, foundPtr);
LWLockRelease(ShmemIndexLock);
*foundPtr = FALSE;
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 34f3c66e617..84204411fac 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lock.c,v 1.98 2001/09/30 00:45:47 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lock.c,v 1.99 2001/10/01 05:36:14 tgl Exp $
*
* NOTES
* Outside modules can create a lock table and acquire/release
@@ -308,8 +308,8 @@ LockMethodTableInit(char *tabName,
* allocate a hash table for LOCK structs. This is used to store
* per-locked-object information.
*/
- info.keysize = SHMEM_LOCKTAB_KEYSIZE;
- info.datasize = SHMEM_LOCKTAB_DATASIZE;
+ info.keysize = sizeof(LOCKTAG);
+ info.entrysize = sizeof(LOCK);
info.hash = tag_hash;
hash_flags = (HASH_ELEM | HASH_FUNCTION);
@@ -328,8 +328,8 @@ LockMethodTableInit(char *tabName,
* allocate a hash table for HOLDER structs. This is used to store
* per-lock-holder information.
*/
- info.keysize = SHMEM_HOLDERTAB_KEYSIZE;
- info.datasize = SHMEM_HOLDERTAB_DATASIZE;
+ info.keysize = sizeof(HOLDERTAG);
+ info.entrysize = sizeof(HOLDER);
info.hash = tag_hash;
hash_flags = (HASH_ELEM | HASH_FUNCTION);
@@ -485,7 +485,8 @@ LockAcquire(LOCKMETHOD lockmethod, LOCKTAG *locktag,
* Find or create a lock with this tag
*/
Assert(lockMethodTable->lockHash->hash == tag_hash);
- lock = (LOCK *) hash_search(lockMethodTable->lockHash, (Pointer) locktag,
+ lock = (LOCK *) hash_search(lockMethodTable->lockHash,
+ (void *) locktag,
HASH_ENTER, &found);
if (!lock)
{
@@ -530,7 +531,8 @@ LockAcquire(LOCKMETHOD lockmethod, LOCKTAG *locktag,
* Find or create a holder entry with this tag
*/
holderTable = lockMethodTable->holderHash;
- holder = (HOLDER *) hash_search(holderTable, (Pointer) &holdertag,
+ holder = (HOLDER *) hash_search(holderTable,
+ (void *) &holdertag,
HASH_ENTER, &found);
if (!holder)
{
@@ -655,7 +657,7 @@ LockAcquire(LOCKMETHOD lockmethod, LOCKTAG *locktag,
SHMQueueDelete(&holder->lockLink);
SHMQueueDelete(&holder->procLink);
holder = (HOLDER *) hash_search(holderTable,
- (Pointer) holder,
+ (void *) holder,
HASH_REMOVE, &found);
if (!holder || !found)
elog(NOTICE, "LockAcquire: remove holder, table corrupted");
@@ -1019,7 +1021,8 @@ LockRelease(LOCKMETHOD lockmethod, LOCKTAG *locktag,
* Find a lock with this tag
*/
Assert(lockMethodTable->lockHash->hash == tag_hash);
- lock = (LOCK *) hash_search(lockMethodTable->lockHash, (Pointer) locktag,
+ lock = (LOCK *) hash_search(lockMethodTable->lockHash,
+ (void *) locktag,
HASH_FIND, &found);
/*
@@ -1051,7 +1054,8 @@ LockRelease(LOCKMETHOD lockmethod, LOCKTAG *locktag,
TransactionIdStore(xid, &holdertag.xid);
holderTable = lockMethodTable->holderHash;
- holder = (HOLDER *) hash_search(holderTable, (Pointer) &holdertag,
+ holder = (HOLDER *) hash_search(holderTable,
+ (void *) &holdertag,
HASH_FIND_SAVE, &found);
if (!holder || !found)
{
@@ -1124,7 +1128,7 @@ LockRelease(LOCKMETHOD lockmethod, LOCKTAG *locktag,
*/
Assert(lockMethodTable->lockHash->hash == tag_hash);
lock = (LOCK *) hash_search(lockMethodTable->lockHash,
- (Pointer) &(lock->tag),
+ (void *) &(lock->tag),
HASH_REMOVE,
&found);
if (!lock || !found)
@@ -1153,7 +1157,8 @@ LockRelease(LOCKMETHOD lockmethod, LOCKTAG *locktag,
HOLDER_PRINT("LockRelease: deleting", holder);
SHMQueueDelete(&holder->lockLink);
SHMQueueDelete(&holder->procLink);
- holder = (HOLDER *) hash_search(holderTable, (Pointer) &holder,
+ holder = (HOLDER *) hash_search(holderTable,
+ (void *) &holder,
HASH_REMOVE_SAVED, &found);
if (!holder || !found)
{
@@ -1306,7 +1311,7 @@ LockReleaseAll(LOCKMETHOD lockmethod, PROC *proc,
* remove the holder entry from the hashtable
*/
holder = (HOLDER *) hash_search(lockMethodTable->holderHash,
- (Pointer) holder,
+ (void *) holder,
HASH_REMOVE,
&found);
if (!holder || !found)
@@ -1326,7 +1331,7 @@ LockReleaseAll(LOCKMETHOD lockmethod, PROC *proc,
LOCK_PRINT("LockReleaseAll: deleting", lock, 0);
Assert(lockMethodTable->lockHash->hash == tag_hash);
lock = (LOCK *) hash_search(lockMethodTable->lockHash,
- (Pointer) &(lock->tag),
+ (void *) &(lock->tag),
HASH_REMOVE, &found);
if (!lock || !found)
{
@@ -1364,14 +1369,10 @@ LockShmemSize(int maxBackends)
* lockMethodTable->ctl */
/* lockHash table */
- size += hash_estimate_size(max_table_size,
- SHMEM_LOCKTAB_KEYSIZE,
- SHMEM_LOCKTAB_DATASIZE);
+ size += hash_estimate_size(max_table_size, sizeof(LOCK));
/* holderHash table */
- size += hash_estimate_size(max_table_size,
- SHMEM_HOLDERTAB_KEYSIZE,
- SHMEM_HOLDERTAB_DATASIZE);
+ size += hash_estimate_size(max_table_size, sizeof(HOLDER));
/*
* Since the lockHash entry count above is only an estimate, add 10%
diff --git a/src/backend/storage/smgr/mm.c b/src/backend/storage/smgr/mm.c
index 43da08b19c8..c6d084dada5 100644
--- a/src/backend/storage/smgr/mm.c
+++ b/src/backend/storage/smgr/mm.c
@@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/smgr/Attic/mm.c,v 1.25 2001/09/29 04:02:25 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/smgr/Attic/mm.c,v 1.26 2001/10/01 05:36:15 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -103,12 +103,12 @@ mminit()
}
info.keysize = sizeof(MMCacheTag);
- info.datasize = sizeof(MMHashEntry) - sizeof(MMCacheTag);
+ info.entrysize = sizeof(MMHashEntry);
info.hash = tag_hash;
- MMCacheHT = (HTAB *) ShmemInitHash("Main memory store HT",
- MMNBUFFERS, MMNBUFFERS,
- &info, (HASH_ELEM | HASH_FUNCTION));
+ MMCacheHT = ShmemInitHash("Main memory store HT",
+ MMNBUFFERS, MMNBUFFERS,
+ &info, (HASH_ELEM | HASH_FUNCTION));
if (MMCacheHT == (HTAB *) NULL)
{
@@ -117,12 +117,12 @@ mminit()
}
info.keysize = sizeof(MMRelTag);
- info.datasize = sizeof(MMRelHashEntry) - sizeof(MMRelTag);
+ info.entrysize = sizeof(MMRelHashEntry);
info.hash = tag_hash;
- MMRelCacheHT = (HTAB *) ShmemInitHash("Main memory rel HT",
- MMNRELATIONS, MMNRELATIONS,
- &info, (HASH_ELEM | HASH_FUNCTION));
+ MMRelCacheHT = ShmemInitHash("Main memory rel HT",
+ MMNRELATIONS, MMNRELATIONS,
+ &info, (HASH_ELEM | HASH_FUNCTION));
if (MMRelCacheHT == (HTAB *) NULL)
{
@@ -180,7 +180,8 @@ mmcreate(Relation reln)
tag.mmrt_dbid = MyDatabaseId;
entry = (MMRelHashEntry *) hash_search(MMRelCacheHT,
- (char *) &tag, HASH_ENTER, &found);
+ (void *) &tag,
+ HASH_ENTER, &found);
if (entry == (MMRelHashEntry *) NULL)
{
@@ -224,7 +225,7 @@ mmunlink(RelFileNode rnode)
&& MMBlockTags[i].mmct_relid == rnode.relNode)
{
entry = (MMHashEntry *) hash_search(MMCacheHT,
- (char *) &MMBlockTags[i],
+ (void *) &MMBlockTags[i],
HASH_REMOVE, &found);
if (entry == (MMHashEntry *) NULL || !found)
{
@@ -239,7 +240,8 @@ mmunlink(RelFileNode rnode)
rtag.mmrt_dbid = rnode.tblNode;
rtag.mmrt_relid = rnode.relNode;
- rentry = (MMRelHashEntry *) hash_search(MMRelCacheHT, (char *) &rtag,
+ rentry = (MMRelHashEntry *) hash_search(MMRelCacheHT,
+ (void *) &rtag,
HASH_REMOVE, &found);
if (rentry == (MMRelHashEntry *) NULL || !found)
@@ -302,7 +304,8 @@ mmextend(Relation reln, BlockNumber blocknum, char *buffer)
(*MMCurTop)++;
}
- rentry = (MMRelHashEntry *) hash_search(MMRelCacheHT, (char *) &rtag,
+ rentry = (MMRelHashEntry *) hash_search(MMRelCacheHT,
+ (void *) &rtag,
HASH_FIND, &found);
if (rentry == (MMRelHashEntry *) NULL || !found)
{
@@ -312,7 +315,8 @@ mmextend(Relation reln, BlockNumber blocknum, char *buffer)
tag.mmct_blkno = rentry->mmrhe_nblocks;
- entry = (MMHashEntry *) hash_search(MMCacheHT, (char *) &tag,
+ entry = (MMHashEntry *) hash_search(MMCacheHT,
+ (void *) &tag,
HASH_ENTER, &found);
if (entry == (MMHashEntry *) NULL || found)
{
@@ -381,7 +385,8 @@ mmread(Relation reln, BlockNumber blocknum, char *buffer)
tag.mmct_blkno = blocknum;
LWLockAcquire(MMCacheLock, LW_EXCLUSIVE);
- entry = (MMHashEntry *) hash_search(MMCacheHT, (char *) &tag,
+ entry = (MMHashEntry *) hash_search(MMCacheHT,
+ (void *) &tag,
HASH_FIND, &found);
if (entry == (MMHashEntry *) NULL)
@@ -428,7 +433,8 @@ mmwrite(Relation reln, BlockNumber blocknum, char *buffer)
tag.mmct_blkno = blocknum;
LWLockAcquire(MMCacheLock, LW_EXCLUSIVE);
- entry = (MMHashEntry *) hash_search(MMCacheHT, (char *) &tag,
+ entry = (MMHashEntry *) hash_search(MMCacheHT,
+ (void *) &tag,
HASH_FIND, &found);
if (entry == (MMHashEntry *) NULL)
@@ -502,7 +508,8 @@ mmnblocks(Relation reln)
LWLockAcquire(MMCacheLock, LW_EXCLUSIVE);
- rentry = (MMRelHashEntry *) hash_search(MMRelCacheHT, (char *) &rtag,
+ rentry = (MMRelHashEntry *) hash_search(MMRelCacheHT,
+ (void *) &rtag,
HASH_FIND, &found);
if (rentry == (MMRelHashEntry *) NULL)
@@ -558,16 +565,12 @@ MMShmemSize()
/*
* first compute space occupied by the (dbid,relid,blkno) hash table
*/
- size += hash_estimate_size(MMNBUFFERS,
- 0, /* MMHashEntry includes key */
- sizeof(MMHashEntry));
+ size += hash_estimate_size(MMNBUFFERS, sizeof(MMHashEntry));
/*
* now do the same for the rel hash table
*/
- size += hash_estimate_size(MMNRELATIONS,
- 0, /* MMRelHashEntry includes key */
- sizeof(MMRelHashEntry));
+ size += hash_estimate_size(MMNRELATIONS, sizeof(MMRelHashEntry));
/*
* finally, add in the memory block we use directly
diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c
index dc5f7c8495d..6ab9871648e 100644
--- a/src/backend/utils/adt/ri_triggers.c
+++ b/src/backend/utils/adt/ri_triggers.c
@@ -18,7 +18,7 @@
* Portions Copyright (c) 2000-2001, PostgreSQL Global Development Group
* Copyright 1999 Jan Wieck
*
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/ri_triggers.c,v 1.25 2001/05/31 17:32:33 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/ri_triggers.c,v 1.26 2001/10/01 05:36:16 tgl Exp $
*
* ----------
*/
@@ -2988,12 +2988,13 @@ ri_InitHashTables(void)
memset(&ctl, 0, sizeof(ctl));
ctl.keysize = sizeof(RI_QueryKey);
- ctl.datasize = sizeof(void *);
- ri_query_cache = hash_create(RI_INIT_QUERYHASHSIZE, &ctl, HASH_ELEM);
+ ctl.entrysize = sizeof(RI_QueryHashEntry);
+ ctl.hash = tag_hash;
+ ri_query_cache = hash_create(RI_INIT_QUERYHASHSIZE, &ctl,
+ HASH_ELEM | HASH_FUNCTION);
- memset(&ctl, 0, sizeof(ctl));
ctl.keysize = sizeof(Oid);
- ctl.datasize = sizeof(Oid) + sizeof(FmgrInfo);
+ ctl.entrysize = sizeof(RI_OpreqHashEntry);
ctl.hash = tag_hash;
ri_opreq_cache = hash_create(RI_INIT_OPREQHASHSIZE, &ctl,
HASH_ELEM | HASH_FUNCTION);
@@ -3023,7 +3024,8 @@ ri_FetchPreparedPlan(RI_QueryKey *key)
* Lookup for the key
*/
entry = (RI_QueryHashEntry *) hash_search(ri_query_cache,
- (char *) key, HASH_FIND, &found);
+ (void *) key,
+ HASH_FIND, &found);
if (entry == NULL)
elog(FATAL, "error in RI plan cache");
if (!found)
@@ -3054,7 +3056,8 @@ ri_HashPreparedPlan(RI_QueryKey *key, void *plan)
* Add the new plan.
*/
entry = (RI_QueryHashEntry *) hash_search(ri_query_cache,
- (char *) key, HASH_ENTER, &found);
+ (void *) key,
+ HASH_ENTER, &found);
if (entry == NULL)
elog(FATAL, "can't insert into RI plan cache");
entry->plan = plan;
@@ -3224,14 +3227,15 @@ ri_AttributesEqual(Oid typeid, Datum oldvalue, Datum newvalue)
/*
* On the first call initialize the hashtable
*/
- if (!ri_query_cache)
+ if (!ri_opreq_cache)
ri_InitHashTables();
/*
* Try to find the '=' operator for this type in our cache
*/
entry = (RI_OpreqHashEntry *) hash_search(ri_opreq_cache,
- (char *) &typeid, HASH_FIND, &found);
+ (void *) &typeid,
+ HASH_FIND, &found);
if (entry == NULL)
elog(FATAL, "error in RI operator cache");
@@ -3271,9 +3275,8 @@ ri_AttributesEqual(Oid typeid, Datum oldvalue, Datum newvalue)
MemoryContextSwitchTo(oldcontext);
entry = (RI_OpreqHashEntry *) hash_search(ri_opreq_cache,
- (char *) &typeid,
- HASH_ENTER,
- &found);
+ (void *) &typeid,
+ HASH_ENTER, &found);
if (entry == NULL)
elog(FATAL, "can't insert into RI operator cache");
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index c626cd6de8c..628e96842d8 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.143 2001/08/25 18:52:42 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.144 2001/10/01 05:36:16 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -132,7 +132,7 @@ typedef struct relnodecacheent
} RelNodeCacheEnt;
/*
- * macros to manipulate name cache and id cache
+ * macros to manipulate the lookup hashtables
*/
#define RelationCacheInsert(RELATION) \
do { \
@@ -149,7 +149,7 @@ do { \
/* used to give notice -- now just keep quiet */ ; \
namehentry->reldesc = RELATION; \
idhentry = (RelIdCacheEnt*)hash_search(RelationIdCache, \
- (char *)&(RELATION->rd_id), \
+ (void *) &(RELATION->rd_id), \
HASH_ENTER, \
&found); \
if (idhentry == NULL) \
@@ -158,7 +158,7 @@ do { \
/* used to give notice -- now just keep quiet */ ; \
idhentry->reldesc = RELATION; \
nodentry = (RelNodeCacheEnt*)hash_search(RelationNodeCache, \
- (char *)&(RELATION->rd_node), \
+ (void *) &(RELATION->rd_node), \
HASH_ENTER, \
&found); \
if (nodentry == NULL) \
@@ -172,7 +172,7 @@ do { \
do { \
RelNameCacheEnt *hentry; bool found; \
hentry = (RelNameCacheEnt*)hash_search(RelationNameCache, \
- (char *)NAME,HASH_FIND,&found); \
+ (void *) (NAME),HASH_FIND,&found); \
if (hentry == NULL) \
elog(FATAL, "error in CACHE"); \
if (found) \
@@ -186,7 +186,7 @@ do { \
RelIdCacheEnt *hentry; \
bool found; \
hentry = (RelIdCacheEnt*)hash_search(RelationIdCache, \
- (char *)&(ID),HASH_FIND, &found); \
+ (void *)&(ID),HASH_FIND, &found); \
if (hentry == NULL) \
elog(FATAL, "error in CACHE"); \
if (found) \
@@ -200,7 +200,7 @@ do { \
RelNodeCacheEnt *hentry; \
bool found; \
hentry = (RelNodeCacheEnt*)hash_search(RelationNodeCache, \
- (char *)&(NODE),HASH_FIND, &found); \
+ (void *)&(NODE),HASH_FIND, &found); \
if (hentry == NULL) \
elog(FATAL, "error in CACHE"); \
if (found) \
@@ -223,14 +223,14 @@ do { \
if (!found) \
elog(NOTICE, "trying to delete a reldesc that does not exist."); \
idhentry = (RelIdCacheEnt*)hash_search(RelationIdCache, \
- (char *)&(RELATION->rd_id), \
+ (void *)&(RELATION->rd_id), \
HASH_REMOVE, &found); \
if (idhentry == NULL) \
elog(FATAL, "can't delete from relation descriptor cache"); \
if (!found) \
elog(NOTICE, "trying to delete a reldesc that does not exist."); \
nodentry = (RelNodeCacheEnt*)hash_search(RelationNodeCache, \
- (char *)&(RELATION->rd_node), \
+ (void *)&(RELATION->rd_node), \
HASH_REMOVE, &found); \
if (nodentry == NULL) \
elog(FATAL, "can't delete from relation descriptor cache"); \
@@ -2092,17 +2092,19 @@ RelationCacheInitialize(void)
/*
* create global caches
*/
- MemSet(&ctl, 0, (int) sizeof(ctl));
+ MemSet(&ctl, 0, sizeof(ctl));
ctl.keysize = sizeof(NameData);
- ctl.datasize = sizeof(Relation);
+ ctl.entrysize = sizeof(RelNameCacheEnt);
RelationNameCache = hash_create(INITRELCACHESIZE, &ctl, HASH_ELEM);
ctl.keysize = sizeof(Oid);
+ ctl.entrysize = sizeof(RelIdCacheEnt);
ctl.hash = tag_hash;
RelationIdCache = hash_create(INITRELCACHESIZE, &ctl,
HASH_ELEM | HASH_FUNCTION);
ctl.keysize = sizeof(RelFileNode);
+ ctl.entrysize = sizeof(RelNodeCacheEnt);
ctl.hash = tag_hash;
RelationNodeCache = hash_create(INITRELCACHESIZE, &ctl,
HASH_ELEM | HASH_FUNCTION);
@@ -2182,17 +2184,19 @@ CreateDummyCaches(void)
oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
- MemSet(&ctl, 0, (int) sizeof(ctl));
+ MemSet(&ctl, 0, sizeof(ctl));
ctl.keysize = sizeof(NameData);
- ctl.datasize = sizeof(Relation);
+ ctl.entrysize = sizeof(RelNameCacheEnt);
RelationNameCache = hash_create(INITRELCACHESIZE, &ctl, HASH_ELEM);
ctl.keysize = sizeof(Oid);
+ ctl.entrysize = sizeof(RelIdCacheEnt);
ctl.hash = tag_hash;
RelationIdCache = hash_create(INITRELCACHESIZE, &ctl,
HASH_ELEM | HASH_FUNCTION);
ctl.keysize = sizeof(RelFileNode);
+ ctl.entrysize = sizeof(RelNodeCacheEnt);
ctl.hash = tag_hash;
RelationNodeCache = hash_create(INITRELCACHESIZE, &ctl,
HASH_ELEM | HASH_FUNCTION);
diff --git a/src/backend/utils/hash/dynahash.c b/src/backend/utils/hash/dynahash.c
index fd9b11ba98e..92e775bfe86 100644
--- a/src/backend/utils/hash/dynahash.c
+++ b/src/backend/utils/hash/dynahash.c
@@ -1,14 +1,15 @@
/*-------------------------------------------------------------------------
*
* dynahash.c
- * dynamic hashing
+ * dynamic hash tables
+ *
*
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/hash/dynahash.c,v 1.36 2001/06/22 19:16:23 wieck Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/hash/dynahash.c,v 1.37 2001/10/01 05:36:16 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -40,46 +41,40 @@
* Modified by sullivan@postgres.berkeley.edu April 1990
* changed ctl structure for shared memory
*/
-#include <sys/types.h>
#include "postgres.h"
+
+#include <sys/types.h>
+
#include "utils/dynahash.h"
#include "utils/hsearch.h"
#include "utils/memutils.h"
/*
- * Fast MOD arithmetic, assuming that y is a power of 2 !
+ * Key (also entry) part of a HASHELEMENT
*/
+#define ELEMENTKEY(helem) (((char *)(helem)) + MAXALIGN(sizeof(HASHELEMENT)))
+/*
+ * Fast MOD arithmetic, assuming that y is a power of 2 !
+ */
#define MOD(x,y) ((x) & ((y)-1))
/*
* Private function prototypes
*/
static void *DynaHashAlloc(Size size);
-static uint32 call_hash(HTAB *hashp, char *k);
-static SEG_OFFSET seg_alloc(HTAB *hashp);
-static int bucket_alloc(HTAB *hashp);
-static int dir_realloc(HTAB *hashp);
-static int expand_table(HTAB *hashp);
-static int hdefault(HTAB *hashp);
-static int init_htab(HTAB *hashp, int nelem);
+static uint32 call_hash(HTAB *hashp, void *k);
+static HASHSEGMENT seg_alloc(HTAB *hashp);
+static bool element_alloc(HTAB *hashp);
+static bool dir_realloc(HTAB *hashp);
+static bool expand_table(HTAB *hashp);
+static bool hdefault(HTAB *hashp);
+static bool init_htab(HTAB *hashp, long nelem);
-/* ----------------
+/*
* memory allocation routines
- *
- * for postgres: all hash elements have to be in
- * the global cache context. Otherwise the postgres
- * garbage collector is going to corrupt them. -wei
- *
- * ??? the "cache" memory context is intended to store only
- * system cache information. The user of the hashing
- * routines should specify which context to use or we
- * should create a separate memory context for these
- * hash routines. For now I have modified this code to
- * do the latter -cim 1/19/91
- * ----------------
*/
static MemoryContext DynaHashCxt = NULL;
static MemoryContext CurrentDynaHashCxt = NULL;
@@ -95,39 +90,22 @@ DynaHashAlloc(Size size)
#define MEM_FREE pfree
-/*
- * pointer access macros. Shared memory implementation cannot
- * store pointers in the hash table data structures because
- * pointer values will be different in different address spaces.
- * these macros convert offsets to pointers and pointers to offsets.
- * Shared memory need not be contiguous, but all addresses must be
- * calculated relative to some offset (segbase).
- */
-
-#define GET_SEG(hp,seg_num)\
- (SEGMENT) (((unsigned long) (hp)->segbase) + (hp)->dir[seg_num])
-
-#define GET_BUCKET(hp,bucket_offs)\
- (ELEMENT *) (((unsigned long) (hp)->segbase) + bucket_offs)
-
-#define MAKE_HASHOFFSET(hp,ptr)\
- ( ((unsigned long) ptr) - ((unsigned long) (hp)->segbase) )
-
#if HASH_STATISTICS
static long hash_accesses,
hash_collisions,
hash_expansions;
-
#endif
+
/************************** CREATE ROUTINES **********************/
HTAB *
-hash_create(int nelem, HASHCTL *info, int flags)
+hash_create(long nelem, HASHCTL *info, int flags)
{
- HHDR *hctl;
HTAB *hashp;
+ HASHHDR *hctl;
+ /* First time through, create a memory context for hash tables */
if (!DynaHashCxt)
DynaHashCxt = AllocSetContextCreate(TopMemoryContext,
"DynaHash",
@@ -135,62 +113,57 @@ hash_create(int nelem, HASHCTL *info, int flags)
ALLOCSET_DEFAULT_INITSIZE,
ALLOCSET_DEFAULT_MAXSIZE);
+ /* Select allocation context for this hash table */
if (flags & HASH_CONTEXT)
CurrentDynaHashCxt = info->hcxt;
else
CurrentDynaHashCxt = DynaHashCxt;
+ /* Initialize the hash header */
hashp = (HTAB *) MEM_ALLOC(sizeof(HTAB));
+ if (!hashp)
+ return NULL;
MemSet(hashp, 0, sizeof(HTAB));
if (flags & HASH_FUNCTION)
hashp->hash = info->hash;
else
- {
- /* default */
- hashp->hash = string_hash;
- }
+ hashp->hash = string_hash; /* default hash function */
if (flags & HASH_SHARED_MEM)
{
-
/*
* ctl structure is preallocated for shared memory tables. Note
* that HASH_DIRSIZE had better be set as well.
*/
-
- hashp->hctl = (HHDR *) info->hctl;
- hashp->segbase = (char *) info->segbase;
+ hashp->hctl = info->hctl;
+ hashp->dir = info->dir;
hashp->alloc = info->alloc;
- hashp->dir = (SEG_OFFSET *) info->dir;
hashp->hcxt = NULL;
/* hash table already exists, we're just attaching to it */
if (flags & HASH_ATTACH)
return hashp;
-
}
else
{
/* setup hash table defaults */
-
hashp->hctl = NULL;
- hashp->alloc = MEM_ALLOC;
hashp->dir = NULL;
- hashp->segbase = NULL;
+ hashp->alloc = MEM_ALLOC;
hashp->hcxt = DynaHashCxt;
-
}
if (!hashp->hctl)
{
- hashp->hctl = (HHDR *) hashp->alloc(sizeof(HHDR));
+ hashp->hctl = (HASHHDR *) hashp->alloc(sizeof(HASHHDR));
if (!hashp->hctl)
- return 0;
+ return NULL;
}
if (!hdefault(hashp))
- return 0;
+ return NULL;
+
hctl = hashp->hctl;
#ifdef HASH_STATISTICS
hctl->accesses = hctl->collisions = 0;
@@ -222,24 +195,26 @@ hash_create(int nelem, HASHCTL *info, int flags)
if (flags & HASH_ELEM)
{
hctl->keysize = info->keysize;
- hctl->datasize = info->datasize;
+ hctl->entrysize = info->entrysize;
}
+
if (flags & HASH_ALLOC)
hashp->alloc = info->alloc;
else
{
if (flags & HASH_CONTEXT)
{
+ /* hash table structures live in child of given context */
CurrentDynaHashCxt = AllocSetContextCreate(info->hcxt,
"DynaHashTable",
ALLOCSET_DEFAULT_MINSIZE,
ALLOCSET_DEFAULT_INITSIZE,
ALLOCSET_DEFAULT_MAXSIZE);
-
hashp->hcxt = CurrentDynaHashCxt;
}
else
{
+ /* hash table structures live in child of DynaHashCxt */
CurrentDynaHashCxt = AllocSetContextCreate(DynaHashCxt,
"DynaHashTable",
ALLOCSET_DEFAULT_MINSIZE,
@@ -249,57 +224,54 @@ hash_create(int nelem, HASHCTL *info, int flags)
}
}
- if (init_htab(hashp, nelem))
+ if (!init_htab(hashp, nelem))
{
hash_destroy(hashp);
- return 0;
+ return NULL;
}
return hashp;
}
/*
- * Set default HHDR parameters.
+ * Set default HASHHDR parameters.
*/
-static int
+static bool
hdefault(HTAB *hashp)
{
- HHDR *hctl;
+ HASHHDR *hctl = hashp->hctl;
- MemSet(hashp->hctl, 0, sizeof(HHDR));
+ MemSet(hctl, 0, sizeof(HASHHDR));
- hctl = hashp->hctl;
hctl->ssize = DEF_SEGSIZE;
hctl->sshift = DEF_SEGSIZE_SHIFT;
hctl->dsize = DEF_DIRSIZE;
hctl->ffactor = DEF_FFACTOR;
- hctl->nkeys = 0;
+ hctl->nentries = 0;
hctl->nsegs = 0;
/* I added these MS. */
- /* default memory allocation for hash buckets */
+ /* rather pointless defaults for key & entry size */
hctl->keysize = sizeof(char *);
- hctl->datasize = sizeof(char *);
+ hctl->entrysize = 2 * sizeof(char *);
/* table has no fixed maximum size */
hctl->max_dsize = NO_MAX_DSIZE;
/* garbage collection for HASH_REMOVE */
- hctl->freeBucketIndex = INVALID_INDEX;
+ hctl->freeList = NULL;
- return 1;
+ return true;
}
-static int
-init_htab(HTAB *hashp, int nelem)
+static bool
+init_htab(HTAB *hashp, long nelem)
{
- SEG_OFFSET *segp;
+ HASHHDR *hctl = hashp->hctl;
+ HASHSEGMENT *segp;
int nbuckets;
int nsegs;
- HHDR *hctl;
-
- hctl = hashp->hctl;
/*
* Divide number of elements by the fill factor to determine a desired
@@ -329,29 +301,29 @@ init_htab(HTAB *hashp, int nelem)
if (!(hashp->dir))
hctl->dsize = nsegs;
else
- return -1;
+ return false;
}
/* Allocate a directory */
if (!(hashp->dir))
{
CurrentDynaHashCxt = hashp->hcxt;
- hashp->dir = (SEG_OFFSET *)
- hashp->alloc(hctl->dsize * sizeof(SEG_OFFSET));
+ hashp->dir = (HASHSEGMENT *)
+ hashp->alloc(hctl->dsize * sizeof(HASHSEGMENT));
if (!hashp->dir)
- return -1;
+ return false;
}
/* Allocate initial segments */
for (segp = hashp->dir; hctl->nsegs < nsegs; hctl->nsegs++, segp++)
{
*segp = seg_alloc(hashp);
- if (*segp == (SEG_OFFSET) 0)
- return -1;
+ if (*segp == NULL)
+ return false;
}
#if HASH_DEBUG
- fprintf(stderr, "%s\n%s%x\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%x\n%s%x\n%s%d\n%s%d\n",
+ fprintf(stderr, "%s\n%s%p\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%x\n%s%x\n%s%d\n%s%d\n",
"init_htab:",
"TABLE POINTER ", hashp,
"DIRECTORY SIZE ", hctl->dsize,
@@ -362,9 +334,9 @@ init_htab(HTAB *hashp, int nelem)
"HIGH MASK ", hctl->high_mask,
"LOW MASK ", hctl->low_mask,
"NSEGS ", hctl->nsegs,
- "NKEYS ", hctl->nkeys);
+ "NENTRIES ", hctl->nentries);
#endif
- return 0;
+ return true;
}
/*
@@ -375,14 +347,14 @@ init_htab(HTAB *hashp, int nelem)
* NB: assumes that all hash structure parameters have default values!
*/
long
-hash_estimate_size(long num_entries, long keysize, long datasize)
+hash_estimate_size(long num_entries, long entrysize)
{
long size = 0;
long nBuckets,
nSegments,
nDirEntries,
- nRecordAllocs,
- recordSize;
+ nElementAllocs,
+ elementSize;
/* estimate number of buckets wanted */
nBuckets = 1L << my_log2((num_entries - 1) / DEF_FFACTOR + 1);
@@ -394,16 +366,15 @@ hash_estimate_size(long num_entries, long keysize, long datasize)
nDirEntries <<= 1; /* dir_alloc doubles dsize at each call */
/* fixed control info */
- size += MAXALIGN(sizeof(HHDR)); /* but not HTAB, per above */
+ size += MAXALIGN(sizeof(HASHHDR)); /* but not HTAB, per above */
/* directory */
- size += MAXALIGN(nDirEntries * sizeof(SEG_OFFSET));
+ size += MAXALIGN(nDirEntries * sizeof(HASHSEGMENT));
/* segments */
- size += nSegments * MAXALIGN(DEF_SEGSIZE * sizeof(BUCKET_INDEX));
- /* records --- allocated in groups of BUCKET_ALLOC_INCR */
- recordSize = sizeof(BUCKET_INDEX) + keysize + datasize;
- recordSize = MAXALIGN(recordSize);
- nRecordAllocs = (num_entries - 1) / BUCKET_ALLOC_INCR + 1;
- size += nRecordAllocs * BUCKET_ALLOC_INCR * recordSize;
+ size += nSegments * MAXALIGN(DEF_SEGSIZE * sizeof(HASHBUCKET));
+ /* elements --- allocated in groups of HASHELEMENT_ALLOC_INCR */
+ elementSize = MAXALIGN(sizeof(HASHELEMENT)) + MAXALIGN(entrysize);
+ nElementAllocs = (num_entries - 1) / HASHELEMENT_ALLOC_INCR + 1;
+ size += nElementAllocs * HASHELEMENT_ALLOC_INCR * elementSize;
return size;
}
@@ -439,40 +410,11 @@ hash_select_dirsize(long num_entries)
/********************** DESTROY ROUTINES ************************/
-/*
- * XXX this sure looks thoroughly broken to me --- tgl 2/99.
- * It's freeing every entry individually --- but they weren't
- * allocated individually, see bucket_alloc!! Why doesn't it crash?
- * ANSWER: it probably does crash, but is never invoked in normal
- * operations...
- *
- * Thomas is right, it does crash. Therefore I changed the code
- * to use a separate memory context which is a child of the DynaHashCxt
- * by default. And the HASHCTL structure got extended with a hcxt
- * field, where someone can specify an explicit context (giving new
- * flag HASH_CONTEXT) and forget about hash_destroy() completely.
- * The shmem operations aren't changed, but in shmem mode a destroy
- * doesn't work anyway. Jan Wieck 03/2001.
- */
-
void
hash_destroy(HTAB *hashp)
{
if (hashp != NULL)
{
-#if 0
- SEG_OFFSET segNum;
- SEGMENT segp;
- int nsegs = hashp->hctl->nsegs;
- int j;
- BUCKET_INDEX *elp,
- p,
- q;
- ELEMENT *curr;
-#endif
-
- /* cannot destroy a shared memory hash table */
- Assert(!hashp->segbase);
/* allocation method must be one we know how to free, too */
Assert(hashp->alloc == MEM_ALLOC);
/* so this hashtable must have it's own context */
@@ -481,40 +423,18 @@ hash_destroy(HTAB *hashp)
hash_stats("destroy", hashp);
/*
- * Free buckets, dir etc. by destroying the hash tables
+ * Free buckets, dir etc. by destroying the hash table's
* memory context.
*/
MemoryContextDelete(hashp->hcxt);
-#if 0
- /*
- * Dead code - replaced by MemoryContextDelete() above
- */
- for (segNum = 0; nsegs > 0; nsegs--, segNum++)
- {
-
- segp = GET_SEG(hashp, segNum);
- for (j = 0, elp = segp; j < hashp->hctl->ssize; j++, elp++)
- {
- for (p = *elp; p != INVALID_INDEX; p = q)
- {
- curr = GET_BUCKET(hashp, p);
- q = curr->next;
- MEM_FREE((char *) curr);
- }
- }
- MEM_FREE((char *) segp);
- }
- MEM_FREE((char *) hashp->dir);
-#endif
-
/*
* Free the HTAB and control structure, which are allocated
* in the parent context (DynaHashCxt or the context given
- * by the caller of hash_create().
+ * by the caller of hash_create()).
*/
- MEM_FREE((char *) hashp->hctl);
- MEM_FREE((char *) hashp);
+ MEM_FREE(hashp->hctl);
+ MEM_FREE(hashp);
}
}
@@ -526,8 +446,8 @@ hash_stats(char *where, HTAB *hashp)
fprintf(stderr, "%s: this HTAB -- accesses %ld collisions %ld\n",
where, hashp->hctl->accesses, hashp->hctl->collisions);
- fprintf(stderr, "hash_stats: keys %ld keysize %ld maxp %d segmentcount %d\n",
- hashp->hctl->nkeys, hashp->hctl->keysize,
+ fprintf(stderr, "hash_stats: entries %ld keysize %ld maxp %d segmentcount %d\n",
+ hashp->hctl->nentries, hashp->hctl->keysize,
hashp->hctl->max_bucket, hashp->hctl->nsegs);
fprintf(stderr, "%s: total accesses %ld total collisions %ld\n",
where, hash_accesses, hash_collisions);
@@ -541,9 +461,9 @@ hash_stats(char *where, HTAB *hashp)
/*******************************SEARCH ROUTINES *****************************/
static uint32
-call_hash(HTAB *hashp, char *k)
+call_hash(HTAB *hashp, void *k)
{
- HHDR *hctl = hashp->hctl;
+ HASHHDR *hctl = hashp->hctl;
long hash_val,
bucket;
@@ -553,7 +473,7 @@ call_hash(HTAB *hashp, char *k)
if (bucket > hctl->max_bucket)
bucket = bucket & hctl->low_mask;
- return bucket;
+ return (uint32) bucket;
}
/*
@@ -566,31 +486,34 @@ call_hash(HTAB *hashp, char *k)
* foundPtr is TRUE if we found an element in the table
* (FALSE if we entered one).
*/
-long *
+void *
hash_search(HTAB *hashp,
- char *keyPtr,
+ void *keyPtr,
HASHACTION action, /* HASH_FIND / HASH_ENTER / HASH_REMOVE
* HASH_FIND_SAVE / HASH_REMOVE_SAVED */
bool *foundPtr)
{
+ HASHHDR *hctl;
uint32 bucket;
long segment_num;
long segment_ndx;
- SEGMENT segp;
- ELEMENT *curr;
- HHDR *hctl;
- BUCKET_INDEX currIndex;
- BUCKET_INDEX *prevIndexPtr;
- char *destAddr;
+ HASHSEGMENT segp;
+ HASHBUCKET currBucket;
+ HASHBUCKET *prevBucketPtr;
+
static struct State
{
- ELEMENT *currElem;
- BUCKET_INDEX currIndex;
- BUCKET_INDEX *prevIndex;
+ HASHBUCKET currBucket;
+ HASHBUCKET *prevBucketPtr;
} saveState;
- Assert((hashp && keyPtr));
- Assert((action == HASH_FIND) || (action == HASH_REMOVE) || (action == HASH_ENTER) || (action == HASH_FIND_SAVE) || (action == HASH_REMOVE_SAVED));
+ Assert(hashp);
+ Assert(keyPtr);
+ Assert((action == HASH_FIND) ||
+ (action == HASH_REMOVE) ||
+ (action == HASH_ENTER) ||
+ (action == HASH_FIND_SAVE) ||
+ (action == HASH_REMOVE_SAVED));
hctl = hashp->hctl;
@@ -598,16 +521,16 @@ hash_search(HTAB *hashp,
hash_accesses++;
hashp->hctl->accesses++;
#endif
+
if (action == HASH_REMOVE_SAVED)
{
- curr = saveState.currElem;
- currIndex = saveState.currIndex;
- prevIndexPtr = saveState.prevIndex;
+ currBucket = saveState.currBucket;
+ prevBucketPtr = saveState.prevBucketPtr;
/*
* Try to catch subsequent errors
*/
- Assert(saveState.currElem && !(saveState.currElem = 0));
+ Assert(currBucket && !(saveState.currBucket = NULL));
}
else
{
@@ -615,25 +538,22 @@ hash_search(HTAB *hashp,
segment_num = bucket >> hctl->sshift;
segment_ndx = MOD(bucket, hctl->ssize);
- segp = GET_SEG(hashp, segment_num);
+ segp = hashp->dir[segment_num];
Assert(segp);
- prevIndexPtr = &segp[segment_ndx];
- currIndex = *prevIndexPtr;
+ prevBucketPtr = &segp[segment_ndx];
+ currBucket = *prevBucketPtr;
/*
- * Follow collision chain
+ * Follow collision chain looking for matching key
*/
- for (curr = NULL; currIndex != INVALID_INDEX;)
+ while (currBucket != NULL)
{
- /* coerce bucket index into a pointer */
- curr = GET_BUCKET(hashp, currIndex);
-
- if (!memcmp((char *) &(curr->key), keyPtr, hctl->keysize))
+ if (memcmp(ELEMENTKEY(currBucket), keyPtr, hctl->keysize) == 0)
break;
- prevIndexPtr = &(curr->next);
- currIndex = *prevIndexPtr;
+ prevBucketPtr = &(currBucket->link);
+ currBucket = *prevBucketPtr;
#if HASH_STATISTICS
hash_collisions++;
hashp->hctl->collisions++;
@@ -645,48 +565,52 @@ hash_search(HTAB *hashp,
* if we found an entry or if we weren't trying to insert, we're done
* now.
*/
- *foundPtr = (bool) (currIndex != INVALID_INDEX);
+ *foundPtr = (bool) (currBucket != NULL);
+
switch (action)
{
case HASH_ENTER:
- if (currIndex != INVALID_INDEX)
- return &(curr->key);
+ if (currBucket != NULL)
+ return (void *) ELEMENTKEY(currBucket);
break;
+
case HASH_REMOVE:
case HASH_REMOVE_SAVED:
- if (currIndex != INVALID_INDEX)
+ if (currBucket != NULL)
{
- Assert(hctl->nkeys > 0);
- hctl->nkeys--;
+ Assert(hctl->nentries > 0);
+ hctl->nentries--;
/* remove record from hash bucket's chain. */
- *prevIndexPtr = curr->next;
+ *prevBucketPtr = currBucket->link;
/* add the record to the freelist for this table. */
- curr->next = hctl->freeBucketIndex;
- hctl->freeBucketIndex = currIndex;
+ currBucket->link = hctl->freeList;
+ hctl->freeList = currBucket;
/*
* better hope the caller is synchronizing access to this
* element, because someone else is going to reuse it the
* next time something is added to the table
*/
- return &(curr->key);
+ return (void *) ELEMENTKEY(currBucket);
}
- return (long *) TRUE;
+ return (void *) TRUE;
+
case HASH_FIND:
- if (currIndex != INVALID_INDEX)
- return &(curr->key);
- return (long *) TRUE;
+ if (currBucket != NULL)
+ return (void *) ELEMENTKEY(currBucket);
+ return (void *) TRUE;
+
case HASH_FIND_SAVE:
- if (currIndex != INVALID_INDEX)
+ if (currBucket != NULL)
{
- saveState.currElem = curr;
- saveState.prevIndex = prevIndexPtr;
- saveState.currIndex = currIndex;
- return &(curr->key);
+ saveState.currBucket = currBucket;
+ saveState.prevBucketPtr = prevBucketPtr;
+ return (void *) ELEMENTKEY(currBucket);
}
- return (long *) TRUE;
+ return (void *) TRUE;
+
default:
/* can't get here */
return NULL;
@@ -696,39 +620,36 @@ hash_search(HTAB *hashp,
* If we got here, then we didn't find the element and we have to
* insert it into the hash table
*/
- Assert(currIndex == INVALID_INDEX);
+ Assert(currBucket == NULL);
/* get the next free bucket */
- currIndex = hctl->freeBucketIndex;
- if (currIndex == INVALID_INDEX)
+ currBucket = hctl->freeList;
+ if (currBucket == NULL)
{
/* no free elements. allocate another chunk of buckets */
- if (!bucket_alloc(hashp))
+ if (!element_alloc(hashp))
return NULL;
- currIndex = hctl->freeBucketIndex;
+ currBucket = hctl->freeList;
}
- Assert(currIndex != INVALID_INDEX);
+ Assert(currBucket != NULL);
- curr = GET_BUCKET(hashp, currIndex);
- hctl->freeBucketIndex = curr->next;
+ hctl->freeList = currBucket->link;
/* link into chain */
- *prevIndexPtr = currIndex;
+ *prevBucketPtr = currBucket;
+ currBucket->link = NULL;
/* copy key into record */
- destAddr = (char *) &(curr->key);
- memmove(destAddr, keyPtr, hctl->keysize);
- curr->next = INVALID_INDEX;
+ memcpy(ELEMENTKEY(currBucket), keyPtr, hctl->keysize);
/*
* let the caller initialize the data field after hash_search returns.
*/
- /* memmove(destAddr,keyPtr,hctl->keysize+hctl->datasize); */
/*
* Check if it is time to split the segment
*/
- if (++hctl->nkeys / (hctl->max_bucket + 1) > hctl->ffactor)
+ if (++hctl->nentries / (hctl->max_bucket + 1) > hctl->ffactor)
{
/*
@@ -737,14 +658,15 @@ hash_search(HTAB *hashp,
*/
expand_table(hashp);
}
- return &(curr->key);
+
+ return (void *) ELEMENTKEY(currBucket);
}
/*
* hash_seq_init/_search
* Sequentially search through hash table and return
* all the elements one by one, return NULL on error and
- * return (long *) TRUE in the end.
+ * return (void *) TRUE in the end.
*
* NOTE: caller may delete the returned element before continuing the scan.
* However, deleting any other element while the scan is in progress is
@@ -757,31 +679,31 @@ hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp)
{
status->hashp = hashp;
status->curBucket = 0;
- status->curIndex = INVALID_INDEX;
+ status->curEntry = NULL;
}
-long *
+void *
hash_seq_search(HASH_SEQ_STATUS *status)
{
HTAB *hashp = status->hashp;
- HHDR *hctl = hashp->hctl;
+ HASHHDR *hctl = hashp->hctl;
while (status->curBucket <= hctl->max_bucket)
{
long segment_num;
long segment_ndx;
- SEGMENT segp;
+ HASHSEGMENT segp;
- if (status->curIndex != INVALID_INDEX)
+ if (status->curEntry != NULL)
{
/* Continuing scan of curBucket... */
- ELEMENT *curElem;
+ HASHELEMENT *curElem;
- curElem = GET_BUCKET(hashp, status->curIndex);
- status->curIndex = curElem->next;
- if (status->curIndex == INVALID_INDEX) /* end of this bucket */
+ curElem = status->curEntry;
+ status->curEntry = curElem->link;
+ if (status->curEntry == NULL) /* end of this bucket */
++status->curBucket;
- return &(curElem->key);
+ return (void *) ELEMENTKEY(curElem);
}
/*
@@ -793,10 +715,10 @@ hash_seq_search(HASH_SEQ_STATUS *status)
/*
* first find the right segment in the table directory.
*/
- segp = GET_SEG(hashp, segment_num);
+ segp = hashp->dir[segment_num];
if (segp == NULL)
/* this is probably an error */
- return (long *) NULL;
+ return NULL;
/*
* now find the right index into the segment for the first item in
@@ -806,13 +728,13 @@ hash_seq_search(HASH_SEQ_STATUS *status)
* directory of valid stuff. if there are elements in the bucket
* chains that point to the freelist we're in big trouble.
*/
- status->curIndex = segp[segment_ndx];
+ status->curEntry = segp[segment_ndx];
- if (status->curIndex == INVALID_INDEX) /* empty bucket */
+ if (status->curEntry == NULL) /* empty bucket */
++status->curBucket;
}
- return (long *) TRUE; /* out of buckets */
+ return (void *) TRUE; /* out of buckets */
}
@@ -821,11 +743,11 @@ hash_seq_search(HASH_SEQ_STATUS *status)
/*
* Expand the table by adding one more hash bucket.
*/
-static int
+static bool
expand_table(HTAB *hashp)
{
- HHDR *hctl;
- SEGMENT old_seg,
+ HASHHDR *hctl = hashp->hctl;
+ HASHSEGMENT old_seg,
new_seg;
long old_bucket,
new_bucket;
@@ -833,18 +755,15 @@ expand_table(HTAB *hashp)
new_segndx;
long old_segnum,
old_segndx;
- ELEMENT *chain;
- BUCKET_INDEX *old,
- *newbi;
- BUCKET_INDEX chainIndex,
- nextIndex;
+ HASHBUCKET *oldlink,
+ *newlink;
+ HASHBUCKET currElement,
+ nextElement;
#ifdef HASH_STATISTICS
hash_expansions++;
#endif
- hctl = hashp->hctl;
-
new_bucket = hctl->max_bucket + 1;
new_segnum = new_bucket >> hctl->sshift;
new_segndx = MOD(new_bucket, hctl->ssize);
@@ -854,9 +773,9 @@ expand_table(HTAB *hashp)
/* Allocate new segment if necessary -- could fail if dir full */
if (new_segnum >= hctl->dsize)
if (!dir_realloc(hashp))
- return 0;
+ return false;
if (!(hashp->dir[new_segnum] = seg_alloc(hashp)))
- return 0;
+ return false;
hctl->nsegs++;
}
@@ -890,137 +809,118 @@ expand_table(HTAB *hashp)
old_segnum = old_bucket >> hctl->sshift;
old_segndx = MOD(old_bucket, hctl->ssize);
- old_seg = GET_SEG(hashp, old_segnum);
- new_seg = GET_SEG(hashp, new_segnum);
+ old_seg = hashp->dir[old_segnum];
+ new_seg = hashp->dir[new_segnum];
- old = &old_seg[old_segndx];
- newbi = &new_seg[new_segndx];
- for (chainIndex = *old;
- chainIndex != INVALID_INDEX;
- chainIndex = nextIndex)
+ oldlink = &old_seg[old_segndx];
+ newlink = &new_seg[new_segndx];
+
+ for (currElement = *oldlink;
+ currElement != NULL;
+ currElement = nextElement)
{
- chain = GET_BUCKET(hashp, chainIndex);
- nextIndex = chain->next;
- if ((long) call_hash(hashp, (char *) &(chain->key)) == old_bucket)
+ nextElement = currElement->link;
+ if ((long) call_hash(hashp, (void *) ELEMENTKEY(currElement))
+ == old_bucket)
{
- *old = chainIndex;
- old = &chain->next;
+ *oldlink = currElement;
+ oldlink = &currElement->link;
}
else
{
- *newbi = chainIndex;
- newbi = &chain->next;
+ *newlink = currElement;
+ newlink = &currElement->link;
}
}
/* don't forget to terminate the rebuilt hash chains... */
- *old = INVALID_INDEX;
- *newbi = INVALID_INDEX;
- return 1;
+ *oldlink = NULL;
+ *newlink = NULL;
+
+ return true;
}
-static int
+static bool
dir_realloc(HTAB *hashp)
{
- char *p;
- char *old_p;
+ HASHSEGMENT *p;
+ HASHSEGMENT *old_p;
long new_dsize;
long old_dirsize;
long new_dirsize;
if (hashp->hctl->max_dsize != NO_MAX_DSIZE)
- return 0;
+ return false;
/* Reallocate directory */
new_dsize = hashp->hctl->dsize << 1;
- old_dirsize = hashp->hctl->dsize * sizeof(SEG_OFFSET);
- new_dirsize = new_dsize * sizeof(SEG_OFFSET);
+ old_dirsize = hashp->hctl->dsize * sizeof(HASHSEGMENT);
+ new_dirsize = new_dsize * sizeof(HASHSEGMENT);
+ old_p = hashp->dir;
CurrentDynaHashCxt = hashp->hcxt;
- old_p = (char *) hashp->dir;
- p = (char *) hashp->alloc((Size) new_dirsize);
+ p = (HASHSEGMENT *) hashp->alloc((Size) new_dirsize);
if (p != NULL)
{
- memmove(p, old_p, old_dirsize);
- MemSet(p + old_dirsize, 0, new_dirsize - old_dirsize);
+ memcpy(p, old_p, old_dirsize);
+ MemSet(((char *) p) + old_dirsize, 0, new_dirsize - old_dirsize);
MEM_FREE((char *) old_p);
- hashp->dir = (SEG_OFFSET *) p;
+ hashp->dir = p;
hashp->hctl->dsize = new_dsize;
- return 1;
+ return true;
}
- return 0;
+
+ return false;
}
-static SEG_OFFSET
+static HASHSEGMENT
seg_alloc(HTAB *hashp)
{
- SEGMENT segp;
- SEG_OFFSET segOffset;
+ HASHSEGMENT segp;
CurrentDynaHashCxt = hashp->hcxt;
- segp = (SEGMENT) hashp->alloc(sizeof(BUCKET_INDEX) * hashp->hctl->ssize);
+ segp = (HASHSEGMENT) hashp->alloc(sizeof(HASHBUCKET) * hashp->hctl->ssize);
if (!segp)
- return 0;
+ return NULL;
- MemSet((char *) segp, 0,
- (long) sizeof(BUCKET_INDEX) * hashp->hctl->ssize);
+ MemSet(segp, 0, sizeof(HASHBUCKET) * hashp->hctl->ssize);
- segOffset = MAKE_HASHOFFSET(hashp, segp);
- return segOffset;
+ return segp;
}
/*
- * allocate some new buckets and link them into the free list
+ * allocate some new elements and link them into the free list
*/
-static int
-bucket_alloc(HTAB *hashp)
+static bool
+element_alloc(HTAB *hashp)
{
+ HASHHDR *hctl = hashp->hctl;
+ Size elementSize;
+ HASHELEMENT *tmpElement;
int i;
- ELEMENT *tmpBucket;
- long bucketSize;
- BUCKET_INDEX tmpIndex,
- lastIndex;
-
- /* Each bucket has a BUCKET_INDEX header plus user data. */
- bucketSize = sizeof(BUCKET_INDEX) + hashp->hctl->keysize + hashp->hctl->datasize;
- /* make sure its aligned correctly */
- bucketSize = MAXALIGN(bucketSize);
+ /* Each element has a HASHELEMENT header plus user data. */
+ elementSize = MAXALIGN(sizeof(HASHELEMENT)) + MAXALIGN(hctl->entrysize);
CurrentDynaHashCxt = hashp->hcxt;
- tmpBucket = (ELEMENT *) hashp->alloc(BUCKET_ALLOC_INCR * bucketSize);
-
- if (!tmpBucket)
- return 0;
+ tmpElement = (HASHELEMENT *)
+ hashp->alloc(HASHELEMENT_ALLOC_INCR * elementSize);
- /* tmpIndex is the shmem offset into the first bucket of the array */
- tmpIndex = MAKE_HASHOFFSET(hashp, tmpBucket);
+ if (!tmpElement)
+ return false;
- /* set the freebucket list to point to the first bucket */
- lastIndex = hashp->hctl->freeBucketIndex;
- hashp->hctl->freeBucketIndex = tmpIndex;
-
- /*
- * initialize each bucket to point to the one behind it. NOTE: loop
- * sets last bucket incorrectly; we fix below.
- */
- for (i = 0; i < BUCKET_ALLOC_INCR; i++)
+ /* link all the new entries into the freelist */
+ for (i = 0; i < HASHELEMENT_ALLOC_INCR; i++)
{
- tmpBucket = GET_BUCKET(hashp, tmpIndex);
- tmpIndex += bucketSize;
- tmpBucket->next = tmpIndex;
+ tmpElement->link = hctl->freeList;
+ hctl->freeList = tmpElement;
+ tmpElement = (HASHELEMENT *) (((char *) tmpElement) + elementSize);
}
- /*
- * the last bucket points to the old freelist head (which is probably
- * invalid or we wouldn't be here)
- */
- tmpBucket->next = lastIndex;
-
- return 1;
+ return true;
}
/* calculate ceil(log base 2) of num */
diff --git a/src/backend/utils/hash/hashfn.c b/src/backend/utils/hash/hashfn.c
index 889837b528d..958deee804f 100644
--- a/src/backend/utils/hash/hashfn.c
+++ b/src/backend/utils/hash/hashfn.c
@@ -1,6 +1,7 @@
/*-------------------------------------------------------------------------
*
* hashfn.c
+ * Hash functions for use in dynahash.c hashtables
*
*
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
@@ -8,7 +9,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/hash/hashfn.c,v 1.13 2001/01/24 19:43:15 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/hash/hashfn.c,v 1.14 2001/10/01 05:36:16 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -17,155 +18,100 @@
#include "utils/hsearch.h"
/*
- * Assume that we've already split the bucket to which this
- * key hashes, calculate that bucket, and check that in fact
- * we did already split it.
+ * string_hash: hash function for keys that are null-terminated strings.
+ *
+ * NOTE: since dynahash.c backs this up with a fixed-length memcmp(),
+ * the key must actually be zero-padded to the specified maximum length
+ * to work correctly. However, if it is known that nothing after the
+ * first zero byte is interesting, this is the right hash function to use.
+ *
+ * NOTE: this is the default hash function if none is specified.
*/
long
-string_hash(char *key, int keysize)
+string_hash(void *key, int keysize)
{
- int h;
unsigned char *k = (unsigned char *) key;
+ long h = 0;
- h = 0;
-
- /*
- * Convert string to integer
- */
while (*k)
- h = h * PRIME1 ^ (*k++ - ' ');
+ h = (h * PRIME1) ^ (*k++);
+
h %= PRIME2;
return h;
}
-
+/*
+ * tag_hash: hash function for fixed-size tag values
+ *
+ * NB: we assume that the supplied key is aligned at least on an 'int'
+ * boundary, if its size is >= sizeof(int).
+ */
long
-tag_hash(int *key, int keysize)
+tag_hash(void *key, int keysize)
{
+ int *k = (int *) key;
long h = 0;
/*
- * Convert tag to integer; Use four byte chunks in a "jump table" to
- * go a little faster. Currently the maximum keysize is 16 (mar 17
- * 1992) I have put in cases for up to 24. Bigger than this will
- * resort to the old behavior of the for loop. (see the default case).
+ * Use four byte chunks in a "jump table" to go a little faster.
+ *
+ * Currently the maximum keysize is 16 (mar 17 1992). I have put in
+ * cases for up to 32. Bigger than this will resort to a for loop
+ * (see the default case).
*/
switch (keysize)
{
+ case 8 * sizeof(int):
+ h = (h * PRIME1) ^ (*k++);
+ /* fall through */
+
+ case 7 * sizeof(int):
+ h = (h * PRIME1) ^ (*k++);
+ /* fall through */
+
case 6 * sizeof(int):
- h = h * PRIME1 ^ (*key);
- key++;
+ h = (h * PRIME1) ^ (*k++);
/* fall through */
case 5 * sizeof(int):
- h = h * PRIME1 ^ (*key);
- key++;
+ h = (h * PRIME1) ^ (*k++);
/* fall through */
case 4 * sizeof(int):
- h = h * PRIME1 ^ (*key);
- key++;
+ h = (h * PRIME1) ^ (*k++);
/* fall through */
case 3 * sizeof(int):
- h = h * PRIME1 ^ (*key);
- key++;
+ h = (h * PRIME1) ^ (*k++);
/* fall through */
case 2 * sizeof(int):
- h = h * PRIME1 ^ (*key);
- key++;
+ h = (h * PRIME1) ^ (*k++);
/* fall through */
case sizeof(int):
- h = h * PRIME1 ^ (*key);
- key++;
+ h = (h * PRIME1) ^ (*k++);
break;
default:
- for (; keysize >= (int) sizeof(int); keysize -= sizeof(int), key++)
- h = h * PRIME1 ^ (*key);
-
- /*
- * now let's grab the last few bytes of the tag if the tag has
- * (size % 4) != 0 (which it sometimes will on a sun3).
- */
- if (keysize)
+ /* Do an int at a time */
+ for (; keysize >= (int) sizeof(int); keysize -= sizeof(int))
+ h = (h * PRIME1) ^ (*k++);
+
+ /* Cope with any partial-int leftover bytes */
+ if (keysize > 0)
{
- char *keytmp = (char *) key;
-
- switch (keysize)
- {
- case 3:
- h = h * PRIME1 ^ (*keytmp);
- keytmp++;
- /* fall through */
- case 2:
- h = h * PRIME1 ^ (*keytmp);
- keytmp++;
- /* fall through */
- case 1:
- h = h * PRIME1 ^ (*keytmp);
- break;
- }
+ unsigned char *keybyte = (unsigned char *) k;
+
+ do
+ h = (h * PRIME1) ^ (*keybyte++);
+ while (--keysize > 0);
}
break;
}
h %= PRIME2;
- return h;
-}
-
-/*
- * This is INCREDIBLY ugly, but fast.
- * We break the string up into 8 byte units. On the first time
- * through the loop we get the "leftover bytes" (strlen % 8).
- * On every other iteration, we perform 8 HASHC's so we handle
- * all 8 bytes. Essentially, this saves us 7 cmp & branch
- * instructions. If this routine is heavily used enough, it's
- * worth the ugly coding
- */
-#ifdef NOT_USED
-long
-disk_hash(char *key)
-{
- int n = 0;
- char *str = key;
- int len = strlen(key);
- int loop;
-#define HASHC n = *str++ + 65599 * n
-
- if (len > 0)
- {
- loop = (len + 8 - 1) >> 3;
-
- switch (len & (8 - 1))
- {
- case 0:
- do
- { /* All fall throughs */
- HASHC;
- case 7:
- HASHC;
- case 6:
- HASHC;
- case 5:
- HASHC;
- case 4:
- HASHC;
- case 3:
- HASHC;
- case 2:
- HASHC;
- case 1:
- HASHC;
- } while (--loop);
- }
-
- }
- return n;
+ return h;
}
-
-#endif
diff --git a/src/backend/utils/mmgr/portalmem.c b/src/backend/utils/mmgr/portalmem.c
index a5534dc1cde..7e1aac19363 100644
--- a/src/backend/utils/mmgr/portalmem.c
+++ b/src/backend/utils/mmgr/portalmem.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/mmgr/portalmem.c,v 1.41 2001/03/22 04:00:08 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/mmgr/portalmem.c,v 1.42 2001/10/01 05:36:16 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -123,7 +123,7 @@ EnablePortalManager(void)
ALLOCSET_DEFAULT_MAXSIZE);
ctl.keysize = MAX_PORTALNAME_LEN;
- ctl.datasize = sizeof(Portal);
+ ctl.entrysize = sizeof(PortalHashEnt);
/*
* use PORTALS_PER_USER, defined in utils/portal.h as a guess of how
diff --git a/src/include/storage/buf_internals.h b/src/include/storage/buf_internals.h
index f85a93c258a..aa468905bff 100644
--- a/src/include/storage/buf_internals.h
+++ b/src/include/storage/buf_internals.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: buf_internals.h,v 1.50 2001/09/29 04:02:26 tgl Exp $
+ * $Id: buf_internals.h,v 1.51 2001/10/01 05:36:17 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -115,6 +115,13 @@ typedef struct sbufdesc
#define BL_IO_IN_PROGRESS (1 << 0) /* unimplemented */
#define BL_PIN_COUNT_LOCK (1 << 1)
+/* entry for buffer hashtable */
+typedef struct
+{
+ BufferTag key;
+ Buffer id;
+} BufferLookupEnt;
+
/*
* mao tracing buffer allocation
*/
diff --git a/src/include/storage/lock.h b/src/include/storage/lock.h
index f61f085e191..7ff9fab32ee 100644
--- a/src/include/storage/lock.h
+++ b/src/include/storage/lock.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: lock.h,v 1.55 2001/09/30 00:45:48 momjian Exp $
+ * $Id: lock.h,v 1.56 2001/10/01 05:36:17 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -169,9 +169,6 @@ typedef struct LOCK
int nGranted; /* total of granted[] array */
} LOCK;
-#define SHMEM_LOCKTAB_KEYSIZE sizeof(LOCKTAG)
-#define SHMEM_LOCKTAB_DATASIZE (sizeof(LOCK) - SHMEM_LOCKTAB_KEYSIZE)
-
#define LOCK_LOCKMETHOD(lock) ((lock).tag.lockmethod)
@@ -222,9 +219,6 @@ typedef struct HOLDER
SHM_QUEUE procLink; /* list link for process's list of holders */
} HOLDER;
-#define SHMEM_HOLDERTAB_KEYSIZE sizeof(HOLDERTAG)
-#define SHMEM_HOLDERTAB_DATASIZE (sizeof(HOLDER) - SHMEM_HOLDERTAB_KEYSIZE)
-
#define HOLDER_LOCKMETHOD(holder) \
(((LOCK *) MAKE_PTR((holder).tag.lock))->tag.lockmethod)
diff --git a/src/include/storage/shmem.h b/src/include/storage/shmem.h
index 1043beb6348..a7ca140382d 100644
--- a/src/include/storage/shmem.h
+++ b/src/include/storage/shmem.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: shmem.h,v 1.31 2001/09/29 04:02:27 tgl Exp $
+ * $Id: shmem.h,v 1.32 2001/10/01 05:36:17 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -73,9 +73,7 @@ extern void *ShmemInitStruct(char *name, Size size, bool *foundPtr);
/* size constants for the shmem index table */
/* max size of data structure string name */
-#define SHMEM_INDEX_KEYSIZE (50)
- /* data in shmem index table hash bucket */
-#define SHMEM_INDEX_DATASIZE (sizeof(ShmemIndexEnt) - SHMEM_INDEX_KEYSIZE)
+#define SHMEM_INDEX_KEYSIZE (48)
/* maximum size of the shmem index table */
#define SHMEM_INDEX_SIZE (100)
diff --git a/src/include/utils/hsearch.h b/src/include/utils/hsearch.h
index 2f9d99e0374..5b65e3ee23e 100644
--- a/src/include/utils/hsearch.h
+++ b/src/include/utils/hsearch.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: hsearch.h,v 1.20 2001/06/22 19:16:24 wieck Exp $
+ * $Id: hsearch.h,v 1.21 2001/10/01 05:36:17 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -31,31 +31,32 @@
* tables, the initial directory size can be left at the default.
*/
#define DEF_SEGSIZE 256
-#define DEF_SEGSIZE_SHIFT 8/* must be log2(DEF_SEGSIZE) */
+#define DEF_SEGSIZE_SHIFT 8 /* must be log2(DEF_SEGSIZE) */
#define DEF_DIRSIZE 256
-#define DEF_FFACTOR 1/* default fill factor */
+#define DEF_FFACTOR 1 /* default fill factor */
#define PRIME1 37 /* for the hash function */
#define PRIME2 1048583
/*
- * Hash bucket is actually bigger than this. Key field can have
- * variable length and a variable length data field follows it.
+ * HASHELEMENT is the private part of a hashtable entry. The caller's data
+ * follows the HASHELEMENT structure (on a MAXALIGN'd boundary). The hash key
+ * is expected to be at the start of the caller's hash entry structure.
*/
-typedef struct element
+typedef struct HASHELEMENT
{
- unsigned long next; /* secret from user */
- long key;
-} ELEMENT;
+ struct HASHELEMENT *link; /* link to next entry in same bucket */
+} HASHELEMENT;
-typedef unsigned long BUCKET_INDEX;
+/* A hash bucket is a linked list of HASHELEMENTs */
+typedef HASHELEMENT *HASHBUCKET;
-/* segment is an array of bucket pointers */
-typedef BUCKET_INDEX *SEGMENT;
-typedef unsigned long SEG_OFFSET;
+/* A hash segment is an array of bucket headers */
+typedef HASHBUCKET *HASHSEGMENT;
-typedef struct hashhdr
+/* Header structure for a hash table --- contains all changeable info */
+typedef struct HASHHDR
{
long dsize; /* Directory Size */
long ssize; /* Segment Size --- must be power of 2 */
@@ -64,65 +65,66 @@ typedef struct hashhdr
long high_mask; /* Mask to modulo into entire table */
long low_mask; /* Mask to modulo into lower half of table */
long ffactor; /* Fill factor */
- long nkeys; /* Number of keys in hash table */
+ long nentries; /* Number of entries in hash table */
long nsegs; /* Number of allocated segments */
long keysize; /* hash key length in bytes */
- long datasize; /* elem data length in bytes */
+ long entrysize; /* total user element size in bytes */
long max_dsize; /* 'dsize' limit if directory is fixed
* size */
- BUCKET_INDEX freeBucketIndex; /* index of first free bucket */
+ HASHELEMENT *freeList; /* linked list of free elements */
#ifdef HASH_STATISTICS
long accesses;
long collisions;
#endif
-} HHDR;
+} HASHHDR;
-typedef struct htab
+/*
+ * Top control structure for a hashtable --- need not be shared, since
+ * no fields change at runtime
+ */
+typedef struct HTAB
{
- HHDR *hctl; /* shared control information */
- long (*hash) (); /* Hash Function */
- char *segbase; /* segment base address for calculating
- * pointer values */
- SEG_OFFSET *dir; /* 'directory' of segm starts */
+ HASHHDR *hctl; /* shared control information */
+ long (*hash) (void *key, int keysize); /* Hash Function */
+ HASHSEGMENT *dir; /* directory of segment starts */
void *(*alloc) (Size);/* memory allocator */
MemoryContext hcxt; /* memory context if default allocator used */
} HTAB;
-typedef struct hashctl
+/* Parameter data structure for hash_create */
+/* Only those fields indicated by hash_flags need be set */
+typedef struct HASHCTL
{
long ssize; /* Segment Size */
- long dsize; /* Dirsize Size */
+ long dsize; /* (initial) Directory Size */
long ffactor; /* Fill factor */
- long (*hash) (); /* Hash Function */
+ long (*hash) (void *key, int keysize); /* Hash Function */
long keysize; /* hash key length in bytes */
- long datasize; /* elem data length in bytes */
+ long entrysize; /* total user element size in bytes */
long max_dsize; /* limit to dsize if directory size is
* limited */
- long *segbase; /* base for calculating bucket + seg ptrs */
void *(*alloc) (Size);/* memory allocation function */
- long *dir; /* directory if allocated already */
- long *hctl; /* location of header information in shd
- * mem */
- MemoryContext hcxt; /* memory context to use for all allocations */
+ HASHSEGMENT *dir; /* directory of segment starts */
+ HASHHDR *hctl; /* location of header in shared mem */
+ MemoryContext hcxt; /* memory context to use for allocations */
} HASHCTL;
-/* Flags to indicate action for hctl */
+/* Flags to indicate which parameters are supplied */
#define HASH_SEGMENT 0x002 /* Setting segment size */
#define HASH_DIRSIZE 0x004 /* Setting directory size */
#define HASH_FFACTOR 0x008 /* Setting fill factor */
#define HASH_FUNCTION 0x010 /* Set user defined hash function */
-#define HASH_ELEM 0x020 /* Setting key/data size */
+#define HASH_ELEM 0x020 /* Setting key/entry size */
#define HASH_SHARED_MEM 0x040 /* Setting shared mem const */
#define HASH_ATTACH 0x080 /* Do not initialize hctl */
#define HASH_ALLOC 0x100 /* Setting memory allocator */
#define HASH_CONTEXT 0x200 /* Setting explicit memory context */
-/* seg_alloc assumes that INVALID_INDEX is 0 */
-#define INVALID_INDEX (0)
+/* max_dsize value to indicate expansible directory */
#define NO_MAX_DSIZE (-1)
-/* number of hash buckets allocated at once */
-#define BUCKET_ALLOC_INCR (30)
+/* number of hash elements allocated at once */
+#define HASHELEMENT_ALLOC_INCR (32)
/* hash_search operations */
typedef enum
@@ -138,27 +140,27 @@ typedef enum
typedef struct
{
HTAB *hashp;
- long curBucket;
- BUCKET_INDEX curIndex;
+ long curBucket; /* index of current bucket */
+ HASHELEMENT *curEntry; /* current entry in bucket */
} HASH_SEQ_STATUS;
/*
- * prototypes from functions in dynahash.c
+ * prototypes for functions in dynahash.c
*/
-extern HTAB *hash_create(int nelem, HASHCTL *info, int flags);
+extern HTAB *hash_create(long nelem, HASHCTL *info, int flags);
extern void hash_destroy(HTAB *hashp);
extern void hash_stats(char *where, HTAB *hashp);
-extern long *hash_search(HTAB *hashp, char *keyPtr, HASHACTION action,
+extern void *hash_search(HTAB *hashp, void *keyPtr, HASHACTION action,
bool *foundPtr);
extern void hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp);
-extern long *hash_seq_search(HASH_SEQ_STATUS *status);
-extern long hash_estimate_size(long num_entries, long keysize, long datasize);
+extern void *hash_seq_search(HASH_SEQ_STATUS *status);
+extern long hash_estimate_size(long num_entries, long entrysize);
extern long hash_select_dirsize(long num_entries);
/*
- * prototypes from functions in hashfn.c
+ * prototypes for functions in hashfn.c
*/
-extern long string_hash(char *key, int keysize);
-extern long tag_hash(int *key, int keysize);
+extern long string_hash(void *key, int keysize);
+extern long tag_hash(void *key, int keysize);
#endif /* HSEARCH_H */