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