Another round of cleanups for dynahash.c (maybe it's finally clean of
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 1 Oct 2001 05:36:17 +0000 (05:36 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 1 Oct 2001 05:36:17 +0000 (05:36 +0000)
portability issues).  Caller-visible data structures are now allocated
on MAXALIGN boundaries, allowing safe use of datatypes wider than 'long'.
Rejigger hash_create API so that caller specifies size of key and
total size of entry, not size of key and size of rest of entry.
This simplifies life considerably since each number is just a sizeof(),
and padding issues etc. are taken care of automatically.

17 files changed:
src/backend/access/transam/xlogutils.c
src/backend/postmaster/pgstat.c
src/backend/storage/buffer/buf_init.c
src/backend/storage/buffer/buf_table.c
src/backend/storage/freespace/freespace.c
src/backend/storage/ipc/shmem.c
src/backend/storage/lmgr/lock.c
src/backend/storage/smgr/mm.c
src/backend/utils/adt/ri_triggers.c
src/backend/utils/cache/relcache.c
src/backend/utils/hash/dynahash.c
src/backend/utils/hash/hashfn.c
src/backend/utils/mmgr/portalmem.c
src/include/storage/buf_internals.h
src/include/storage/lock.h
src/include/storage/shmem.h
src/include/utils/hsearch.h

index 4cae914cf41fb0c8c76087805a77f5deb1e2e484..8bd55026d42e76fa34f0fa52609741c85987598a 100644 (file)
@@ -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");
index 298e3470d9680c1c3ea137d8c2cf779a7b3a8fc5..6c8ed373a873053705e31c51f9fe85690c4f5984 100644 (file)
@@ -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);
index 45a2e4aa160a85efe37432cb8477c1c59f0629b1..322c45b03194528cc0f8d1c21e7cbbb9c4987640 100644 (file)
@@ -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);
index 671b13efa0f036193d1068e82190208a00e3dd10..85b747b442f8f08bb5acbb9bc366a37e40e392b3 100644 (file)
@@ -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 $
  *
  *-------------------------------------------------------------------------
  */
 
 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)
        {
index b20e8086157eb063cf0dced844c8de0b0f37d022..f8fefee8a09d97f6d1169984c02847e4ffa4d19e 100644 (file)
@@ -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)
index 0ad168680a193bd7bc5068763731d242455f7e60..024db5bd5334dbfe41f1df79f0161f0577d2117f 100644 (file)
@@ -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;
 
index 34f3c66e617ec7db22664481ac064062111a1262..84204411faccbed630da2759f4974f6f700e705d 100644 (file)
@@ -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%
index 43da08b19c8d1e40eed46a74067f247cde7e756e..c6d084dada58159a478e8cbad3481569acf65518 100644 (file)
@@ -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
index dc5f7c8495d44a6dfe9903a47b7039a609f0c910..6ab9871648e1be6f39f86f9885dd0cd1019a2c6d 100644 (file)
@@ -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");
 
index c626cd6de8ccd3ff9f2266f03affe50a5045e6aa..628e96842d851313c01b8e0d534ac491c2464f6e 100644 (file)
@@ -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);
index fd9b11ba98e52be57c435482f2585c1be1fbbca9..92e775bfe86e334e894e3d868bde088adf70d678 100644 (file)
@@ -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 $
  *
  *-------------------------------------------------------------------------
  */
  * 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 */
index 889837b528d7610b9e4ee1e2c29473bc10eee285..958deee804f8133b28bec6fbb5a45b436016a2ae 100644 (file)
@@ -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 $
  *
  *-------------------------------------------------------------------------
  */
 #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
index a5534dc1cded1233521e2e3307e0d84e2c8cf68a..7e1aac193632f3a9017a612a9794657f9610414e 100644 (file)
@@ -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
index f85a93c258ae5a0d4098ba1cd819a804fd3792e0..aa468905bff76f54466a0058f057e8e93da55690 100644 (file)
@@ -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
  */
index f61f085e191631a739a1e62f62037a6993842b68..7ff9fab32eeca9a9be9df3da987f24623a4b32f5 100644 (file)
@@ -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)
 
index 1043beb63489f1a7c146eb289b30bec49c9e596b..a7ca140382dfea02970500af54c411d6973e7b67 100644 (file)
@@ -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)
 
index 2f9d99e037447d2c257a9e84a45d8a3e98840580..5b65e3ee23e5eca1691369edbda5631a3600d7ab 100644 (file)
@@ -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 $
  *
  *-------------------------------------------------------------------------
  */
  * 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 */