* 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.19 2001/10/01 05:36:13 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/transam/xlogutils.c,v 1.20 2001/10/05 17:28:11 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "access/htup.h"
#include "access/xlogutils.h"
#include "catalog/pg_database.h"
-#include "lib/hasht.h"
#include "storage/bufpage.h"
#include "storage/smgr.h"
+#include "utils/hsearch.h"
#include "utils/relcache.h"
ctl.entrysize = sizeof(XLogRelCacheEntry);
ctl.hash = tag_hash;
- _xlrelcache = hash_create(_XLOG_RELCACHESIZE, &ctl,
- HASH_ELEM | HASH_FUNCTION);
+ _xlrelcache = hash_create("XLOG relcache", _XLOG_RELCACHESIZE,
+ &ctl, HASH_ELEM | HASH_FUNCTION);
}
static void
-_xl_remove_hash_entry(XLogRelDesc **edata, Datum dummy)
+_xl_remove_hash_entry(XLogRelDesc *rdesc)
{
- XLogRelCacheEntry *hentry;
- bool found;
- XLogRelDesc *rdesc = *edata;
Form_pg_class tpgc = rdesc->reldata.rd_rel;
+ XLogRelCacheEntry *hentry;
rdesc->lessRecently->moreRecently = rdesc->moreRecently;
rdesc->moreRecently->lessRecently = rdesc->lessRecently;
hentry = (XLogRelCacheEntry *) hash_search(_xlrelcache,
- (void *) &(rdesc->reldata.rd_node), HASH_REMOVE, &found);
-
+ (void *) &(rdesc->reldata.rd_node), HASH_REMOVE, NULL);
if (hentry == NULL)
- elog(STOP, "_xl_remove_hash_entry: can't delete from cache");
- if (!found)
elog(STOP, "_xl_remove_hash_entry: file was not found in cache");
if (rdesc->reldata.rd_fd >= 0)
/* reuse */
res = _xlrelarr[0].moreRecently;
- _xl_remove_hash_entry(&res, 0);
+ _xl_remove_hash_entry(res);
_xlast--;
return (res);
void
XLogCloseRelationCache(void)
{
+ HASH_SEQ_STATUS status;
+ XLogRelCacheEntry *hentry;
DestroyDummyCaches();
if (!_xlrelarr)
return;
- HashTableWalk(_xlrelcache, (HashtFunc) _xl_remove_hash_entry, 0);
+ hash_seq_init(&status, _xlrelcache);
+
+ while ((hentry = (XLogRelCacheEntry *) hash_seq_search(&status)) != NULL)
+ {
+ _xl_remove_hash_entry(hentry->rdesc);
+ }
+
hash_destroy(_xlrelcache);
free(_xlrelarr);
bool found;
hentry = (XLogRelCacheEntry *)
- hash_search(_xlrelcache, (void *) &rnode, HASH_FIND, &found);
-
- if (hentry == NULL)
- elog(STOP, "XLogOpenRelation: error in cache");
+ hash_search(_xlrelcache, (void *) &rnode, HASH_FIND, NULL);
- if (found)
+ if (hentry)
{
res = hentry->rdesc;
hash_search(_xlrelcache, (void *) &rnode, HASH_ENTER, &found);
if (hentry == NULL)
- elog(STOP, "XLogOpenRelation: can't insert into cache");
+ elog(STOP, "XLogOpenRelation: out of memory for cache");
if (found)
elog(STOP, "XLogOpenRelation: file found on insert into cache");
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.142 2001/09/07 21:57:53 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.143 2001/10/05 17:28:11 tgl Exp $
*
* NOTES
* The PerformAddAttribute() code, like most of the relation
/*
* Note: PortalCleanup is called as a side-effect
*/
- PortalDrop(&portal);
+ PortalDrop(portal);
}
/* ----------------
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/spi.c,v 1.57 2001/08/02 18:08:43 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/spi.c,v 1.58 2001/10/05 17:28:12 tgl Exp $
*
*-------------------------------------------------------------------------
*/
void
SPI_cursor_close(Portal portal)
{
- Portal my_portal = portal;
-
- if (!PortalIsValid(my_portal))
+ if (!PortalIsValid(portal))
elog(ERROR, "invalid portal in SPI cursor operation");
- PortalDrop(&my_portal);
+ PortalDrop(portal);
}
/* =================== private functions =================== */
# Makefile for lib (miscellaneous stuff)
#
# IDENTIFICATION
-# $Header: /cvsroot/pgsql/src/backend/lib/Makefile,v 1.15 2000/08/31 16:09:59 petere Exp $
+# $Header: /cvsroot/pgsql/src/backend/lib/Makefile,v 1.16 2001/10/05 17:28:12 tgl Exp $
#
#-------------------------------------------------------------------------
top_builddir = ../../..
include $(top_builddir)/src/Makefile.global
-OBJS = bit.o hasht.o lispsort.o stringinfo.o dllist.o
+OBJS = bit.o dllist.o lispsort.o stringinfo.o
all: SUBSYS.o
+++ /dev/null
-/*-------------------------------------------------------------------------
- *
- * hasht.c
- * hash table related functions that are not directly supported
- * by the hashing packages under utils/hash.
- *
- * 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/lib/Attic/hasht.c,v 1.15 2001/01/24 19:42:55 momjian Exp $
- *
- *-------------------------------------------------------------------------
- */
-#include "postgres.h"
-
-#include "lib/hasht.h"
-#include "utils/memutils.h"
-
-/* -----------------------------------
- * HashTableWalk
- *
- * call given function on every element in hashtable
- *
- * one extra argument (arg) may be supplied
- *
- * NOTE: it is allowed for the given function to delete the hashtable entry
- * it is passed. However, deleting any other element while the scan is
- * in progress is UNDEFINED (see hash_seq functions). Also, if elements are
- * added to the table while the scan is in progress, it is unspecified
- * whether they will be visited by the scan or not.
- * -----------------------------------
- */
-void
-HashTableWalk(HTAB *hashtable, HashtFunc function, Datum arg)
-{
- HASH_SEQ_STATUS status;
- long *hashent;
- void *data;
- int keysize;
-
- hash_seq_init(&status, hashtable);
- keysize = hashtable->hctl->keysize;
-
- while ((hashent = hash_seq_search(&status)) != (long *) TRUE)
- {
- if (hashent == NULL)
- elog(FATAL, "error in HashTableWalk");
-
- /*
- * XXX the corresponding hash table insertion does NOT LONGALIGN
- * -- make sure the keysize is ok
- */
- data = (void *) LONGALIGN((char *) hashent + keysize);
- (*function) (data, arg);
- }
-}
*
* Copyright (c) 2001, PostgreSQL Global Development Group
*
- * $Header: /cvsroot/pgsql/src/backend/postmaster/pgstat.c,v 1.9 2001/10/01 16:48:37 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/postmaster/pgstat.c,v 1.10 2001/10/05 17:28:12 tgl Exp $
* ----------
*/
#include "postgres.h"
int dbidalloc;
int dbidused;
HASH_SEQ_STATUS hstat;
- long *hentry;
PgStat_StatDBEntry *dbentry;
PgStat_StatTabEntry *tabentry;
HeapTuple reltup;
- bool found;
int nobjects = 0;
PgStat_MsgTabpurge msg;
int len;
*/
dbentry = (PgStat_StatDBEntry *)hash_search(pgStatDBHash,
(void *) &MyDatabaseId,
- HASH_FIND, &found);
- if (!found || dbentry == NULL)
+ HASH_FIND, NULL);
+ if (dbentry == NULL)
return -1;
if (dbentry->tables == NULL)
* Check for all tables if they still exist.
*/
hash_seq_init(&hstat, dbentry->tables);
- while((hentry = hash_seq_search(&hstat)) != (long *)TRUE)
+ while ((tabentry = (PgStat_StatTabEntry *) hash_seq_search(&hstat)) != NULL)
{
- if (hentry == NULL)
- return -1;
-
/*
* Check if this relation is still alive by
* looking up it's pg_class tuple in the
* system catalog cache.
*/
- tabentry = (PgStat_StatTabEntry *)hentry;
reltup = SearchSysCache(RELOID,
ObjectIdGetDatum(tabentry->tableid),
0, 0, 0);
* tell the collector to drop them as well.
*/
hash_seq_init(&hstat, pgStatDBHash);
- while((hentry = hash_seq_search(&hstat)) != (long *)TRUE)
+ while ((dbentry = (PgStat_StatDBEntry *) hash_seq_search(&hstat)) != NULL)
{
- Oid dbid;
-
- if (hentry == NULL)
- break;
-
- dbentry = (PgStat_StatDBEntry *)hentry;
- dbid = dbentry->databaseid;
+ Oid dbid = dbentry->databaseid;
for (i = 0; i < dbidused; i++)
{
pgstat_fetch_stat_dbentry(Oid dbid)
{
PgStat_StatDBEntry *dbentry;
- bool found;
/*
* If not done for this transaction, read the statistics collector
*/
dbentry = (PgStat_StatDBEntry *) hash_search(pgStatDBHash,
(void *) &dbid,
- HASH_FIND, &found);
- if (!found || dbentry == NULL)
+ HASH_FIND, NULL);
+ if (dbentry == NULL)
return NULL;
return dbentry;
{
PgStat_StatDBEntry *dbentry;
PgStat_StatTabEntry *tabentry;
- bool found;
/*
* If not done for this transaction, read the statistics collector
*/
dbentry = (PgStat_StatDBEntry *) hash_search(pgStatDBHash,
(void *) &MyDatabaseId,
- HASH_FIND, &found);
- if (!found || dbentry == NULL)
+ HASH_FIND, NULL);
+ if (dbentry == NULL)
return NULL;
/*
return NULL;
tabentry = (PgStat_StatTabEntry *) hash_search(dbentry->tables,
(void *) &relid,
- HASH_FIND, &found);
- if (!found || tabentry == NULL)
+ HASH_FIND, NULL);
+ if (tabentry == NULL)
return NULL;
return tabentry;
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);
+ pgStatBeDead = hash_create("Dead Backends", PGSTAT_BE_HASH_SIZE,
+ &hash_ctl, HASH_ELEM | HASH_FUNCTION);
if (pgStatBeDead == NULL)
{
fprintf(stderr,
*/
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");
- exit(1);
- }
- if (found)
+ HASH_FIND, NULL);
+ if (deadbe)
return 1;
/*
HASH_ENTER, &found);
if (dbentry == NULL)
{
- fprintf(stderr, "PGSTAT: DB hash table corrupted - abort\n");
+ fprintf(stderr, "PGSTAT: DB hash table out of memory - abort\n");
exit(1);
}
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);
+ dbentry->tables = hash_create("Per-database table",
+ PGSTAT_TAB_HASH_SIZE,
+ &hash_ctl,
+ HASH_ELEM | HASH_FUNCTION);
if (dbentry->tables == NULL)
{
fprintf(stderr, "PGSTAT: failed to initialize hash table for "
HASH_ENTER, &found);
if (deadbe == NULL)
{
- fprintf(stderr, "PGSTAT: dead backend hash table corrupted "
+ fprintf(stderr, "PGSTAT: dead backend hash table out of memory "
"- abort\n");
exit(1);
}
PgStat_StatTabEntry *tabentry;
PgStat_StatBeDead *deadbe;
FILE *fpout;
- long *hentry;
- bool found;
int i;
/*
* Walk through the database table.
*/
hash_seq_init(&hstat, pgStatDBHash);
- while ((hentry = hash_seq_search(&hstat)) != (long *)TRUE)
+ while ((dbentry = (PgStat_StatDBEntry *) hash_seq_search(&hstat)) != NULL)
{
- if (hentry == NULL)
- {
- fprintf(stderr, "PGSTAT: database hash table corrupted "
- "- abort\n");
- exit(1);
- }
- dbentry = (PgStat_StatDBEntry *)hentry;
-
/*
* If this database is marked destroyed, count down and do
* so if it reaches 0.
if (dbentry->tables != NULL)
hash_destroy(dbentry->tables);
- hentry = hash_search(pgStatDBHash,
- (void *) &(dbentry->databaseid),
- HASH_REMOVE, &found);
- if (hentry == NULL)
+ if (hash_search(pgStatDBHash,
+ (void *) &(dbentry->databaseid),
+ HASH_REMOVE, NULL) == NULL)
{
fprintf(stderr, "PGSTAT: database hash table corrupted "
"during cleanup - abort\n");
* Walk through the databases access stats per table.
*/
hash_seq_init(&tstat, dbentry->tables);
- while((hentry = hash_seq_search(&tstat)) != (long *)TRUE)
+ while ((tabentry = (PgStat_StatTabEntry *) hash_seq_search(&tstat)) != NULL)
{
- if (hentry == NULL)
- {
- fprintf(stderr, "PGSTAT: tables hash table for database "
- "%d corrupted - abort\n",
- dbentry->databaseid);
- exit(1);
- }
- tabentry = (PgStat_StatTabEntry *)hentry;
-
/*
* If table entry marked for destruction, same as above
* for the database entry.
{
if (--(tabentry->destroy) == 0)
{
- hentry = hash_search(dbentry->tables,
+ if (hash_search(dbentry->tables,
(void *) &(tabentry->tableid),
- HASH_REMOVE, &found);
- if (hentry == NULL)
+ HASH_REMOVE, NULL) == NULL)
{
fprintf(stderr, "PGSTAT: tables hash table for "
"database %d corrupted during "
* Clear out the dead backends table
*/
hash_seq_init(&hstat, pgStatBeDead);
- while ((hentry = hash_seq_search(&hstat)) != (long *)TRUE)
+ while ((deadbe = (PgStat_StatBeDead *) hash_seq_search(&hstat)) != NULL)
{
- if (hentry == NULL)
- {
- fprintf(stderr, "PGSTAT: dead backend hash table corrupted "
- "during cleanup - abort\n");
- exit(1);
- }
- deadbe = (PgStat_StatBeDead *)hentry;
-
/*
* Count down the destroy delay and remove entries where
* it reaches 0.
*/
if (--(deadbe->destroy) <= 0)
{
- hentry = hash_search(pgStatBeDead,
- (void *) &(deadbe->procpid),
- HASH_REMOVE, &found);
- if (hentry == NULL)
+ if (hash_search(pgStatBeDead,
+ (void *) &(deadbe->procpid),
+ HASH_REMOVE, NULL) == NULL)
{
fprintf(stderr, "PGSTAT: dead backend hash table corrupted "
"during cleanup - abort\n");
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,
+ *dbhash = hash_create("Databases hash", PGSTAT_DB_HASH_SIZE, &hash_ctl,
HASH_ELEM | HASH_FUNCTION | mcxt_flags);
if (pgStatDBHash == NULL)
{
{
if (pgStatRunningInCollector)
{
- fprintf(stderr, "PGSTAT: DB hash table corrupted\n");
+ fprintf(stderr, "PGSTAT: DB hash table out of memory\n");
exit(1);
}
else
{
fclose(fpin);
- elog(ERROR, "PGSTAT: DB hash table corrupted");
+ elog(ERROR, "PGSTAT: DB hash table out of memory");
}
}
if (found)
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,
+ dbentry->tables = hash_create("Per-database table",
+ PGSTAT_TAB_HASH_SIZE,
+ &hash_ctl,
HASH_ELEM | HASH_FUNCTION | mcxt_flags);
if (dbentry->tables == NULL)
{
{
if (pgStatRunningInCollector)
{
- fprintf(stderr, "PGSTAT: Tab hash table corrupted\n");
+ fprintf(stderr, "PGSTAT: Tab hash table out of memory\n");
exit(1);
}
else
{
fclose(fpin);
- elog(ERROR, "PGSTAT: Tab hash table corrupted");
+ elog(ERROR, "PGSTAT: Tab hash table out of memory");
}
}
*/
dbentry = (PgStat_StatDBEntry *)hash_search(*dbhash,
(void *) &((*betab)[havebackends].databaseid),
- HASH_FIND, &found);
- if (found)
+ HASH_FIND, NULL);
+ if (dbentry)
dbentry->n_backends++;
havebackends++;
*/
dbentry = (PgStat_StatDBEntry *) hash_search(pgStatDBHash,
(void *) &(msg->m_hdr.m_databaseid),
- HASH_FIND, &found);
- if (dbentry == NULL)
- {
- fprintf(stderr, "PGSTAT: database hash table corrupted - abort\n");
- exit(1);
- }
- if (!found)
+ HASH_FIND, NULL);
+ if (!dbentry)
return;
/*
HASH_ENTER, &found);
if (tabentry == NULL)
{
- fprintf(stderr, "PGSTAT: tables hash table corrupted for "
+ fprintf(stderr, "PGSTAT: tables hash table out of memory for "
"database %d - abort\n", dbentry->databaseid);
exit(1);
}
PgStat_StatDBEntry *dbentry;
PgStat_StatTabEntry *tabentry;
int i;
- bool found;
/*
* Make sure the backend is counted for.
*/
dbentry = (PgStat_StatDBEntry *) hash_search(pgStatDBHash,
(void *) &(msg->m_hdr.m_databaseid),
- HASH_FIND, &found);
- if (dbentry == NULL)
- {
- fprintf(stderr, "PGSTAT: database hash table corrupted - abort\n");
- exit(1);
- }
- if (!found)
+ HASH_FIND, NULL);
+ if (!dbentry)
return;
/*
{
tabentry = (PgStat_StatTabEntry *) hash_search(dbentry->tables,
(void *) &(msg->m_tableid[i]),
- HASH_FIND, &found);
- if (tabentry == NULL)
- {
- fprintf(stderr, "PGSTAT: tables hash table corrupted for "
- "database %d - abort\n", dbentry->databaseid);
- exit(1);
- }
-
- if (found)
+ HASH_FIND, NULL);
+ if (tabentry)
tabentry->destroy = PGSTAT_DESTROY_COUNT;
}
}
pgstat_recv_dropdb(PgStat_MsgDropdb *msg, int len)
{
PgStat_StatDBEntry *dbentry;
- bool found;
/*
* Make sure the backend is counted for.
*/
dbentry = (PgStat_StatDBEntry *) hash_search(pgStatDBHash,
(void *) &(msg->m_databaseid),
- HASH_FIND, &found);
- if (dbentry == NULL)
- {
- fprintf(stderr, "PGSTAT: database hash table corrupted - abort\n");
- exit(1);
- }
- if (!found)
+ HASH_FIND, NULL);
+ if (!dbentry)
return;
/*
{
HASHCTL hash_ctl;
PgStat_StatDBEntry *dbentry;
- bool found;
/*
* Make sure the backend is counted for.
*/
dbentry = (PgStat_StatDBEntry *) hash_search(pgStatDBHash,
(void *) &(msg->m_hdr.m_databaseid),
- HASH_FIND, &found);
- if (dbentry == NULL)
- {
- fprintf(stderr, "PGSTAT: database hash table corrupted - abort\n");
- exit(1);
- }
- if (!found)
+ HASH_FIND, NULL);
+ if (!dbentry)
return;
/*
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);
+ dbentry->tables = hash_create("Per-database table",
+ PGSTAT_TAB_HASH_SIZE,
+ &hash_ctl,
+ HASH_ELEM | HASH_FUNCTION);
if (dbentry->tables == NULL)
{
fprintf(stderr, "PGSTAT: failed to reinitialize hash table for "
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/buffer/buf_table.c,v 1.23 2001/10/01 05:36:13 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/buffer/buf_table.c,v 1.24 2001/10/05 17:28:12 tgl Exp $
*
*-------------------------------------------------------------------------
*/
BufTableLookup(BufferTag *tagPtr)
{
BufferLookupEnt *result;
- bool found;
if (tagPtr->blockNum == P_NEW)
return NULL;
result = (BufferLookupEnt *)
- hash_search(SharedBufHash, (void *) tagPtr, HASH_FIND, &found);
-
+ hash_search(SharedBufHash, (void *) tagPtr, HASH_FIND, NULL);
if (!result)
- {
- elog(ERROR, "BufTableLookup: BufferLookup table corrupted");
- return NULL;
- }
- if (!found)
return NULL;
+
return &(BufferDescriptors[result->id]);
}
BufTableDelete(BufferDesc *buf)
{
BufferLookupEnt *result;
- bool found;
/*
* buffer not initialized or has been removed from table already.
buf->flags |= BM_DELETED;
result = (BufferLookupEnt *)
- hash_search(SharedBufHash, (void *) &(buf->tag), HASH_REMOVE, &found);
+ hash_search(SharedBufHash, (void *) &(buf->tag), HASH_REMOVE, NULL);
- if (!(result && found))
+ if (!result)
{
+ /* shouldn't happen */
elog(ERROR, "BufTableDelete: BufferLookup table corrupted");
return FALSE;
}
if (!result)
{
- Assert(0);
- elog(ERROR, "BufTableInsert: BufferLookup table corrupted");
+ elog(ERROR, "BufTableInsert: BufferLookup table out of memory");
return FALSE;
}
+
/* found something else in the table ! */
if (found)
{
- Assert(0);
elog(ERROR, "BufTableInsert: BufferLookup table corrupted");
return FALSE;
}
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/freespace/freespace.c,v 1.6 2001/10/01 05:36:14 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/freespace/freespace.c,v 1.7 2001/10/05 17:28:12 tgl Exp $
*
*
* NOTES:
lookup_fsm_rel(RelFileNode *rel)
{
FSMRelation *fsmrel;
- bool found;
fsmrel = (FSMRelation *) hash_search(FreeSpaceMap->relHash,
(void *) rel,
HASH_FIND,
- &found);
+ NULL);
if (!fsmrel)
- elog(ERROR, "FreeSpaceMap hashtable corrupted");
-
- if (!found)
return NULL;
return fsmrel;
HASH_ENTER,
&found);
if (!fsmrel)
- elog(ERROR, "FreeSpaceMap hashtable corrupted");
+ elog(ERROR, "FreeSpaceMap hashtable out of memory");
if (!found)
{
delete_fsm_rel(FSMRelation *fsmrel)
{
FSMRelation *result;
- bool found;
free_chunk_chain(fsmrel->relChunks);
unlink_fsm_rel(fsmrel);
result = (FSMRelation *) hash_search(FreeSpaceMap->relHash,
(void *) &(fsmrel->key),
HASH_REMOVE,
- &found);
- if (!result || !found)
+ NULL);
+ if (!result)
elog(ERROR, "FreeSpaceMap hashtable corrupted");
}
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/ipc/shmem.c,v 1.60 2001/10/01 05:36:14 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/ipc/shmem.c,v 1.61 2001/10/05 17:28:12 tgl Exp $
*
*-------------------------------------------------------------------------
*/
result = (ShmemIndexEnt *)
hash_search(ShmemIndex, (void *) &item, HASH_ENTER, &found);
if (!result)
- elog(FATAL, "InitShmemIndex: corrupted shmem index");
+ elog(FATAL, "InitShmemIndex: Shmem Index out of memory");
Assert(ShmemBootstrap && !found);
* table at once.
*/
HTAB *
-ShmemInitHash(char *name, /* table string name for shmem index */
+ShmemInitHash(const char *name, /* table string name for shmem index */
long init_size, /* initial table size */
long max_size, /* max size of the table */
HASHCTL *infoP, /* info about key and bucket size */
infoP->hctl = (HASHHDR *) location;
infoP->dir = (HASHSEGMENT *) (((char *) location) + sizeof(HASHHDR));
- return hash_create(init_size, infoP, hash_flags);
+ return hash_create(name, init_size, infoP, hash_flags);
}
/*
* initialized).
*/
void *
-ShmemInitStruct(char *name, Size size, bool *foundPtr)
+ShmemInitStruct(const char *name, Size size, bool *foundPtr)
{
ShmemIndexEnt *result,
item;
if (!result)
{
LWLockRelease(ShmemIndexLock);
- elog(ERROR, "ShmemInitStruct: Shmem Index corrupted");
+ elog(ERROR, "ShmemInitStruct: Shmem Index out of memory");
return NULL;
}
{
/* out of memory */
Assert(ShmemIndex);
- hash_search(ShmemIndex, (void *) &item, HASH_REMOVE, foundPtr);
+ hash_search(ShmemIndex, (void *) &item, HASH_REMOVE, NULL);
LWLockRelease(ShmemIndexLock);
- *foundPtr = FALSE;
elog(NOTICE, "ShmemInitStruct: cannot allocate '%s'",
name);
+ *foundPtr = FALSE;
return NULL;
}
result->size = size;
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lock.c,v 1.99 2001/10/01 05:36:14 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lock.c,v 1.100 2001/10/05 17:28:12 tgl Exp $
*
* NOTES
* Outside modules can create a lock table and acquire/release
if (!lock)
{
LWLockRelease(masterLock);
- elog(FATAL, "LockAcquire: lock table %d is corrupted", lockmethod);
+ elog(ERROR, "LockAcquire: lock table %d is out of memory",
+ lockmethod);
return FALSE;
}
if (!holder)
{
LWLockRelease(masterLock);
- elog(FATAL, "LockAcquire: holder table corrupted");
+ elog(ERROR, "LockAcquire: holder table out of memory");
return FALSE;
}
SHMQueueDelete(&holder->procLink);
holder = (HOLDER *) hash_search(holderTable,
(void *) holder,
- HASH_REMOVE, &found);
- if (!holder || !found)
+ HASH_REMOVE, NULL);
+ if (!holder)
elog(NOTICE, "LockAcquire: remove holder, table corrupted");
}
else
{
LOCK *lock;
LWLockId masterLock;
- bool found;
LOCKMETHODTABLE *lockMethodTable;
HOLDER *holder;
HOLDERTAG holdertag;
Assert(lockMethodTable->lockHash->hash == tag_hash);
lock = (LOCK *) hash_search(lockMethodTable->lockHash,
(void *) locktag,
- HASH_FIND, &found);
+ HASH_FIND, NULL);
/*
* let the caller print its own error message, too. Do not
* elog(ERROR).
*/
if (!lock)
- {
- LWLockRelease(masterLock);
- elog(NOTICE, "LockRelease: locktable corrupted");
- return FALSE;
- }
-
- if (!found)
{
LWLockRelease(masterLock);
elog(NOTICE, "LockRelease: no such lock");
holderTable = lockMethodTable->holderHash;
holder = (HOLDER *) hash_search(holderTable,
(void *) &holdertag,
- HASH_FIND_SAVE, &found);
- if (!holder || !found)
+ HASH_FIND_SAVE, NULL);
+ if (!holder)
{
LWLockRelease(masterLock);
#ifdef USER_LOCKS
- if (!found && lockmethod == USER_LOCKMETHOD)
+ if (lockmethod == USER_LOCKMETHOD)
elog(NOTICE, "LockRelease: no lock with this tag");
else
#endif
lock = (LOCK *) hash_search(lockMethodTable->lockHash,
(void *) &(lock->tag),
HASH_REMOVE,
- &found);
- if (!lock || !found)
+ NULL);
+ if (!lock)
{
LWLockRelease(masterLock);
elog(NOTICE, "LockRelease: remove lock, table corrupted");
SHMQueueDelete(&holder->procLink);
holder = (HOLDER *) hash_search(holderTable,
(void *) &holder,
- HASH_REMOVE_SAVED, &found);
- if (!holder || !found)
+ HASH_REMOVE_SAVED, NULL);
+ if (!holder)
{
LWLockRelease(masterLock);
elog(NOTICE, "LockRelease: remove holder, table corrupted");
int i,
numLockModes;
LOCK *lock;
- bool found;
#ifdef LOCK_DEBUG
if (lockmethod == USER_LOCKMETHOD ? Trace_userlocks : Trace_locks)
holder = (HOLDER *) hash_search(lockMethodTable->holderHash,
(void *) holder,
HASH_REMOVE,
- &found);
- if (!holder || !found)
+ NULL);
+ if (!holder)
{
LWLockRelease(masterLock);
elog(NOTICE, "LockReleaseAll: holder table corrupted");
if (lock->nRequested == 0)
{
-
/*
* We've just released the last lock, so garbage-collect the
* lock object.
Assert(lockMethodTable->lockHash->hash == tag_hash);
lock = (LOCK *) hash_search(lockMethodTable->lockHash,
(void *) &(lock->tag),
- HASH_REMOVE, &found);
- if (!lock || !found)
+ HASH_REMOVE, NULL);
+ if (!lock)
{
LWLockRelease(masterLock);
elog(NOTICE, "LockReleaseAll: cannot remove lock from HTAB");
DumpAllLocks(void)
{
PROC *proc;
- HOLDER *holder = NULL;
+ HOLDER *holder;
LOCK *lock;
int lockmethod = DEFAULT_LOCKMETHOD;
LOCKMETHODTABLE *lockMethodTable;
LOCK_PRINT("DumpAllLocks: waiting on", proc->waitLock, 0);
hash_seq_init(&status, holderTable);
- while ((holder = (HOLDER *) hash_seq_search(&status)) &&
- (holder != (HOLDER *) TRUE))
+ while ((holder = (HOLDER *) hash_seq_search(&status)) != NULL)
{
HOLDER_PRINT("DumpAllLocks", holder);
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/smgr/Attic/mm.c,v 1.26 2001/10/01 05:36:15 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/smgr/Attic/mm.c,v 1.27 2001/10/05 17:28:12 tgl Exp $
*
*-------------------------------------------------------------------------
*/
if (entry == (MMRelHashEntry *) NULL)
{
LWLockRelease(MMCacheLock);
- elog(FATAL, "main memory storage mgr rel cache hash table corrupt");
+ elog(FATAL, "main memory storage mgr hash table out of memory");
}
if (found)
int i;
MMHashEntry *entry;
MMRelHashEntry *rentry;
- bool found;
MMRelTag rtag;
LWLockAcquire(MMCacheLock, LW_EXCLUSIVE);
{
entry = (MMHashEntry *) hash_search(MMCacheHT,
(void *) &MMBlockTags[i],
- HASH_REMOVE, &found);
- if (entry == (MMHashEntry *) NULL || !found)
+ HASH_REMOVE, NULL);
+ if (entry == (MMHashEntry *) NULL)
{
LWLockRelease(MMCacheLock);
elog(FATAL, "mmunlink: cache hash table corrupted");
rentry = (MMRelHashEntry *) hash_search(MMRelCacheHT,
(void *) &rtag,
- HASH_REMOVE, &found);
+ HASH_REMOVE, NULL);
- if (rentry == (MMRelHashEntry *) NULL || !found)
+ if (rentry == (MMRelHashEntry *) NULL)
{
LWLockRelease(MMCacheLock);
elog(FATAL, "mmunlink: rel cache hash table corrupted");
rentry = (MMRelHashEntry *) hash_search(MMRelCacheHT,
(void *) &rtag,
- HASH_FIND, &found);
- if (rentry == (MMRelHashEntry *) NULL || !found)
+ HASH_FIND, NULL);
+ if (rentry == (MMRelHashEntry *) NULL)
{
LWLockRelease(MMCacheLock);
elog(FATAL, "mmextend: rel cache hash table corrupt");
mmread(Relation reln, BlockNumber blocknum, char *buffer)
{
MMHashEntry *entry;
- bool found;
int offset;
MMCacheTag tag;
LWLockAcquire(MMCacheLock, LW_EXCLUSIVE);
entry = (MMHashEntry *) hash_search(MMCacheHT,
(void *) &tag,
- HASH_FIND, &found);
+ HASH_FIND, NULL);
if (entry == (MMHashEntry *) NULL)
- {
- LWLockRelease(MMCacheLock);
- elog(FATAL, "mmread: hash table corrupt");
- }
-
- if (!found)
{
/* reading nonexistent pages is defined to fill them with zeroes */
LWLockRelease(MMCacheLock);
mmwrite(Relation reln, BlockNumber blocknum, char *buffer)
{
MMHashEntry *entry;
- bool found;
int offset;
MMCacheTag tag;
LWLockAcquire(MMCacheLock, LW_EXCLUSIVE);
entry = (MMHashEntry *) hash_search(MMCacheHT,
(void *) &tag,
- HASH_FIND, &found);
+ HASH_FIND, NULL);
if (entry == (MMHashEntry *) NULL)
- {
- LWLockRelease(MMCacheLock);
- elog(FATAL, "mmread: hash table corrupt");
- }
-
- if (!found)
{
LWLockRelease(MMCacheLock);
elog(FATAL, "mmwrite: hash table missing requested page");
{
MMRelTag rtag;
MMRelHashEntry *rentry;
- bool found;
BlockNumber nblocks;
if (reln->rd_rel->relisshared)
rentry = (MMRelHashEntry *) hash_search(MMRelCacheHT,
(void *) &rtag,
- HASH_FIND, &found);
-
- if (rentry == (MMRelHashEntry *) NULL)
- {
- LWLockRelease(MMCacheLock);
- elog(FATAL, "mmnblocks: rel cache hash table corrupt");
- }
+ HASH_FIND, NULL);
- if (found)
+ if (rentry)
nblocks = rentry->mmrhe_nblocks;
else
nblocks = InvalidBlockNumber;
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/tcop/pquery.c,v 1.44 2001/03/22 06:16:17 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/tcop/pquery.c,v 1.45 2001/10/05 17:28:12 tgl Exp $
*
*-------------------------------------------------------------------------
*/
*/
elog(NOTICE, "Closing pre-existing portal \"%s\"",
portalName);
- PortalDrop(&portal);
+ PortalDrop(portal);
}
/*
* 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.26 2001/10/01 05:36:16 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/ri_triggers.c,v 1.27 2001/10/05 17:28:12 tgl Exp $
*
* ----------
*/
ctl.keysize = sizeof(RI_QueryKey);
ctl.entrysize = sizeof(RI_QueryHashEntry);
ctl.hash = tag_hash;
- ri_query_cache = hash_create(RI_INIT_QUERYHASHSIZE, &ctl,
- HASH_ELEM | HASH_FUNCTION);
+ ri_query_cache = hash_create("RI query cache", RI_INIT_QUERYHASHSIZE,
+ &ctl, HASH_ELEM | HASH_FUNCTION);
ctl.keysize = sizeof(Oid);
ctl.entrysize = sizeof(RI_OpreqHashEntry);
ctl.hash = tag_hash;
- ri_opreq_cache = hash_create(RI_INIT_OPREQHASHSIZE, &ctl,
- HASH_ELEM | HASH_FUNCTION);
+ ri_opreq_cache = hash_create("RI OpReq cache", RI_INIT_OPREQHASHSIZE,
+ &ctl, HASH_ELEM | HASH_FUNCTION);
}
ri_FetchPreparedPlan(RI_QueryKey *key)
{
RI_QueryHashEntry *entry;
- bool found;
/*
* On the first call initialize the hashtable
*/
entry = (RI_QueryHashEntry *) hash_search(ri_query_cache,
(void *) key,
- HASH_FIND, &found);
+ HASH_FIND, NULL);
if (entry == NULL)
- elog(FATAL, "error in RI plan cache");
- if (!found)
return NULL;
return entry->plan;
}
(void *) key,
HASH_ENTER, &found);
if (entry == NULL)
- elog(FATAL, "can't insert into RI plan cache");
+ elog(ERROR, "out of memory for RI plan cache");
entry->plan = plan;
}
*/
entry = (RI_OpreqHashEntry *) hash_search(ri_opreq_cache,
(void *) &typeid,
- HASH_FIND, &found);
- if (entry == NULL)
- elog(FATAL, "error in RI operator cache");
+ HASH_FIND, NULL);
/*
* If not found, lookup the OPERNAME system cache for it to get the
* func OID, then do the function manager lookup, and remember that
* info.
*/
- if (!found)
+ if (!entry)
{
HeapTuple opr_tup;
Oid opr_proc;
(void *) &typeid,
HASH_ENTER, &found);
if (entry == NULL)
- elog(FATAL, "can't insert into RI operator cache");
+ elog(ERROR, "out of memory for RI operator cache");
entry->typeid = typeid;
memcpy(&(entry->oprfmgrinfo), &finfo, sizeof(FmgrInfo));
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.144 2001/10/01 05:36:16 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.145 2001/10/05 17:28:12 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "catalog/pg_rewrite.h"
#include "catalog/pg_type.h"
#include "commands/trigger.h"
-#include "lib/hasht.h"
#include "miscadmin.h"
#include "storage/smgr.h"
#include "utils/builtins.h"
#include "utils/catcache.h"
#include "utils/fmgroids.h"
+#include "utils/hsearch.h"
#include "utils/memutils.h"
#include "utils/relcache.h"
#include "utils/temprel.h"
HASH_ENTER, \
&found); \
if (namehentry == NULL) \
- elog(FATAL, "can't insert into relation descriptor cache"); \
- if (found && !IsBootstrapProcessingMode()) \
- /* used to give notice -- now just keep quiet */ ; \
+ elog(ERROR, "out of memory for relation descriptor cache"); \
+ /* used to give notice if found -- now just keep quiet */ ; \
namehentry->reldesc = RELATION; \
idhentry = (RelIdCacheEnt*)hash_search(RelationIdCache, \
(void *) &(RELATION->rd_id), \
HASH_ENTER, \
&found); \
if (idhentry == NULL) \
- elog(FATAL, "can't insert into relation descriptor cache"); \
- if (found && !IsBootstrapProcessingMode()) \
- /* used to give notice -- now just keep quiet */ ; \
+ elog(ERROR, "out of memory for relation descriptor cache"); \
+ /* used to give notice if found -- now just keep quiet */ ; \
idhentry->reldesc = RELATION; \
nodentry = (RelNodeCacheEnt*)hash_search(RelationNodeCache, \
(void *) &(RELATION->rd_node), \
HASH_ENTER, \
&found); \
if (nodentry == NULL) \
- elog(FATAL, "can't insert into relation descriptor cache"); \
- if (found && !IsBootstrapProcessingMode()) \
- /* used to give notice -- now just keep quiet */ ; \
+ elog(ERROR, "out of memory for relation descriptor cache"); \
+ /* used to give notice if found -- now just keep quiet */ ; \
nodentry->reldesc = RELATION; \
} while(0)
#define RelationNameCacheLookup(NAME, RELATION) \
do { \
- RelNameCacheEnt *hentry; bool found; \
+ RelNameCacheEnt *hentry; \
hentry = (RelNameCacheEnt*)hash_search(RelationNameCache, \
- (void *) (NAME),HASH_FIND,&found); \
- if (hentry == NULL) \
- elog(FATAL, "error in CACHE"); \
- if (found) \
+ (void *) (NAME), HASH_FIND,NULL); \
+ if (hentry) \
RELATION = hentry->reldesc; \
else \
RELATION = NULL; \
#define RelationIdCacheLookup(ID, RELATION) \
do { \
RelIdCacheEnt *hentry; \
- bool found; \
hentry = (RelIdCacheEnt*)hash_search(RelationIdCache, \
- (void *)&(ID),HASH_FIND, &found); \
- if (hentry == NULL) \
- elog(FATAL, "error in CACHE"); \
- if (found) \
+ (void *)&(ID), HASH_FIND,NULL); \
+ if (hentry) \
RELATION = hentry->reldesc; \
else \
RELATION = NULL; \
#define RelationNodeCacheLookup(NODE, RELATION) \
do { \
RelNodeCacheEnt *hentry; \
- bool found; \
hentry = (RelNodeCacheEnt*)hash_search(RelationNodeCache, \
- (void *)&(NODE),HASH_FIND, &found); \
- if (hentry == NULL) \
- elog(FATAL, "error in CACHE"); \
- if (found) \
+ (void *)&(NODE), HASH_FIND,NULL); \
+ if (hentry) \
RELATION = hentry->reldesc; \
else \
RELATION = NULL; \
#define RelationCacheDelete(RELATION) \
do { \
RelNameCacheEnt *namehentry; RelIdCacheEnt *idhentry; \
- char *relname; RelNodeCacheEnt *nodentry; bool found; \
+ char *relname; RelNodeCacheEnt *nodentry; \
relname = RelationGetPhysicalRelationName(RELATION); \
namehentry = (RelNameCacheEnt*)hash_search(RelationNameCache, \
relname, \
- HASH_REMOVE, \
- &found); \
+ HASH_REMOVE, NULL); \
if (namehentry == NULL) \
- elog(FATAL, "can't delete from relation descriptor cache"); \
- if (!found) \
elog(NOTICE, "trying to delete a reldesc that does not exist."); \
idhentry = (RelIdCacheEnt*)hash_search(RelationIdCache, \
(void *)&(RELATION->rd_id), \
- HASH_REMOVE, &found); \
+ HASH_REMOVE, NULL); \
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, \
(void *)&(RELATION->rd_node), \
- HASH_REMOVE, &found); \
+ HASH_REMOVE, NULL); \
if (nodentry == NULL) \
- elog(FATAL, "can't delete from relation descriptor cache"); \
- if (!found) \
elog(NOTICE, "trying to delete a reldesc that does not exist."); \
} while(0)
#endif /* ENABLE_REINDEX_NAILED_RELATIONS */
static void RelationFlushRelation(Relation relation);
static Relation RelationNameCacheGetRelation(const char *relationName);
-static void RelationCacheInvalidateWalker(Relation *relationPtr, Datum listp);
-static void RelationCacheAbortWalker(Relation *relationPtr, Datum dummy);
static void init_irels(void);
static void write_irels(void);
*
* We do this in two phases: the first pass deletes deletable items, and
* the second one rebuilds the rebuildable items. This is essential for
- * safety, because HashTableWalk only copes with concurrent deletion of
+ * safety, because hash_seq_search only copes with concurrent deletion of
* the element it is currently visiting. If a second SI overflow were to
* occur while we are walking the table, resulting in recursive entry to
* this routine, we could crash because the inner invocation blows away
* the entry next to be visited by the outer scan. But this way is OK,
* because (a) during the first pass we won't process any more SI messages,
- * so HashTableWalk will complete safely; (b) during the second pass we
+ * so hash_seq_search will complete safely; (b) during the second pass we
* only hold onto pointers to nondeletable entries.
*/
void
RelationCacheInvalidate(void)
{
+ HASH_SEQ_STATUS status;
+ RelNameCacheEnt *namehentry;
+ Relation relation;
List *rebuildList = NIL;
List *l;
/* Phase 1 */
- HashTableWalk(RelationNameCache,
- (HashtFunc) RelationCacheInvalidateWalker,
- PointerGetDatum(&rebuildList));
+ hash_seq_init(&status, RelationNameCache);
- /* Phase 2: rebuild the items found to need rebuild in phase 1 */
- foreach(l, rebuildList)
+ while ((namehentry = (RelNameCacheEnt *) hash_seq_search(&status)) != NULL)
{
- Relation relation = (Relation) lfirst(l);
-
- RelationClearRelation(relation, true);
- }
- freeList(rebuildList);
-}
+ relation = namehentry->reldesc;
-static void
-RelationCacheInvalidateWalker(Relation *relationPtr, Datum listp)
-{
- Relation relation = *relationPtr;
- List **rebuildList = (List **) DatumGetPointer(listp);
-
- /* We can ignore xact-local relations, since they are never SI targets */
- if (relation->rd_myxactonly)
- return;
+ /* Ignore xact-local relations, since they are never SI targets */
+ if (relation->rd_myxactonly)
+ continue;
- if (RelationHasReferenceCountZero(relation))
- {
- /* Delete this entry immediately */
- RelationClearRelation(relation, false);
+ if (RelationHasReferenceCountZero(relation))
+ {
+ /* Delete this entry immediately */
+ RelationClearRelation(relation, false);
+ }
+ else
+ {
+ /* Add entry to list of stuff to rebuild in second pass */
+ rebuildList = lcons(relation, rebuildList);
+ }
}
- else
+
+ /* Phase 2: rebuild the items found to need rebuild in phase 1 */
+ foreach(l, rebuildList)
{
- /* Add entry to list of stuff to rebuild in second pass */
- *rebuildList = lcons(relation, *rebuildList);
+ relation = (Relation) lfirst(l);
+ RelationClearRelation(relation, true);
}
+ freeList(rebuildList);
}
/*
void
RelationCacheAbort(void)
{
- HashTableWalk(RelationNameCache,
- (HashtFunc) RelationCacheAbortWalker,
- 0);
-}
+ HASH_SEQ_STATUS status;
+ RelNameCacheEnt *namehentry;
-static void
-RelationCacheAbortWalker(Relation *relationPtr, Datum dummy)
-{
- Relation relation = *relationPtr;
+ hash_seq_init(&status, RelationNameCache);
- if (relation->rd_isnailed)
- RelationSetReferenceCount(relation, 1);
- else
- RelationSetReferenceCount(relation, 0);
+ while ((namehentry = (RelNameCacheEnt *) hash_seq_search(&status)) != NULL)
+ {
+ Relation relation = namehentry->reldesc;
+
+ if (relation->rd_isnailed)
+ RelationSetReferenceCount(relation, 1);
+ else
+ RelationSetReferenceCount(relation, 0);
+ }
}
/*
MemSet(&ctl, 0, sizeof(ctl));
ctl.keysize = sizeof(NameData);
ctl.entrysize = sizeof(RelNameCacheEnt);
- RelationNameCache = hash_create(INITRELCACHESIZE, &ctl, HASH_ELEM);
+ RelationNameCache = hash_create("Relcache by name", 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);
+ RelationIdCache = hash_create("Relcache by OID", 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);
+ RelationNodeCache = hash_create("Relcache by rnode", INITRELCACHESIZE,
+ &ctl, HASH_ELEM | HASH_FUNCTION);
/*
* initialize the cache with pre-made relation descriptors for some of
MemSet(&ctl, 0, sizeof(ctl));
ctl.keysize = sizeof(NameData);
ctl.entrysize = sizeof(RelNameCacheEnt);
- RelationNameCache = hash_create(INITRELCACHESIZE, &ctl, HASH_ELEM);
+ RelationNameCache = hash_create("Relcache by name", 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);
+ RelationIdCache = hash_create("Relcache by OID", 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);
+ RelationNodeCache = hash_create("Relcache by rnode", INITRELCACHESIZE,
+ &ctl, HASH_ELEM | HASH_FUNCTION);
+
MemoryContextSwitchTo(oldcxt);
}
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/hash/dynahash.c,v 1.37 2001/10/01 05:36:16 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/hash/dynahash.c,v 1.38 2001/10/05 17:28:13 tgl Exp $
*
*-------------------------------------------------------------------------
*/
static bool expand_table(HTAB *hashp);
static bool hdefault(HTAB *hashp);
static bool init_htab(HTAB *hashp, long nelem);
+static void hash_corrupted(HTAB *hashp);
/*
/************************** CREATE ROUTINES **********************/
HTAB *
-hash_create(long nelem, HASHCTL *info, int flags)
+hash_create(const char *tabname, long nelem, HASHCTL *info, int flags)
{
HTAB *hashp;
HASHHDR *hctl;
return NULL;
MemSet(hashp, 0, sizeof(HTAB));
+ hashp->tabname = (char *) MEM_ALLOC(strlen(tabname) + 1);
+ strcpy(hashp->tabname, tabname);
+
if (flags & HASH_FUNCTION)
hashp->hash = info->hash;
else
hashp->dir = info->dir;
hashp->alloc = info->alloc;
hashp->hcxt = NULL;
+ hashp->isshared = true;
/* hash table already exists, we're just attaching to it */
if (flags & HASH_ATTACH)
hashp->dir = NULL;
hashp->alloc = MEM_ALLOC;
hashp->hcxt = DynaHashCxt;
+ hashp->isshared = false;
}
if (!hashp->hctl)
* by the caller of hash_create()).
*/
MEM_FREE(hashp->hctl);
+ MEM_FREE(hashp->tabname);
MEM_FREE(hashp);
}
}
void
-hash_stats(char *where, HTAB *hashp)
+hash_stats(const char *where, HTAB *hashp)
{
#if HASH_STATISTICS
return (uint32) bucket;
}
-/*
+/*----------
* hash_search -- look up key in table and perform action
*
- * action is one of HASH_FIND/HASH_ENTER/HASH_REMOVE
+ * action is one of:
+ * HASH_FIND: look up key in table
+ * HASH_ENTER: look up key in table, creating entry if not present
+ * HASH_REMOVE: look up key in table, remove entry if present
+ * HASH_FIND_SAVE: look up key in table, also save in static var
+ * HASH_REMOVE_SAVED: remove entry saved by HASH_FIND_SAVE
+ *
+ * Return value is a pointer to the element found/entered/removed if any,
+ * or NULL if no match was found. (NB: in the case of the REMOVE actions,
+ * the result is a dangling pointer that shouldn't be dereferenced!)
+ * A NULL result for HASH_ENTER implies we ran out of memory.
+ *
+ * If foundPtr isn't NULL, then *foundPtr is set TRUE if we found an
+ * existing entry in the table, FALSE otherwise. This is needed in the
+ * HASH_ENTER case, but is redundant with the return value otherwise.
*
- * RETURNS: NULL if table is corrupted, a pointer to the element
- * found/removed/entered if applicable, TRUE otherwise.
- * foundPtr is TRUE if we found an element in the table
- * (FALSE if we entered one).
+ * The HASH_FIND_SAVE/HASH_REMOVE_SAVED interface is a hack to save one
+ * table lookup in a find/process/remove scenario. Note that no other
+ * addition or removal in the table can safely happen in between.
+ *----------
*/
void *
hash_search(HTAB *hashp,
void *keyPtr,
- HASHACTION action, /* HASH_FIND / HASH_ENTER / HASH_REMOVE
- * HASH_FIND_SAVE / HASH_REMOVE_SAVED */
+ HASHACTION action,
bool *foundPtr)
{
- HASHHDR *hctl;
+ HASHHDR *hctl = hashp->hctl;
uint32 bucket;
long segment_num;
long segment_ndx;
HASHBUCKET *prevBucketPtr;
} saveState;
- 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;
-
#if HASH_STATISTICS
hash_accesses++;
- hashp->hctl->accesses++;
+ hctl->accesses++;
#endif
+ /*
+ * Do the initial lookup (or recall result of prior lookup)
+ */
if (action == HASH_REMOVE_SAVED)
{
currBucket = saveState.currBucket;
segp = hashp->dir[segment_num];
- Assert(segp);
+ if (segp == NULL)
+ hash_corrupted(hashp);
prevBucketPtr = &segp[segment_ndx];
currBucket = *prevBucketPtr;
currBucket = *prevBucketPtr;
#if HASH_STATISTICS
hash_collisions++;
- hashp->hctl->collisions++;
+ hctl->collisions++;
#endif
}
}
+ if (foundPtr)
+ *foundPtr = (bool) (currBucket != NULL);
+
/*
- * if we found an entry or if we weren't trying to insert, we're done
- * now.
+ * OK, now what?
*/
- *foundPtr = (bool) (currBucket != NULL);
-
switch (action)
{
- case HASH_ENTER:
+ case HASH_FIND:
if (currBucket != NULL)
return (void *) ELEMENTKEY(currBucket);
- break;
+ return NULL;
+
+ case HASH_FIND_SAVE:
+ if (currBucket != NULL)
+ {
+ saveState.currBucket = currBucket;
+ saveState.prevBucketPtr = prevBucketPtr;
+ return (void *) ELEMENTKEY(currBucket);
+ }
+ return NULL;
case HASH_REMOVE:
case HASH_REMOVE_SAVED:
*/
return (void *) ELEMENTKEY(currBucket);
}
- return (void *) TRUE;
+ return NULL;
- case HASH_FIND:
+ case HASH_ENTER:
+ /* Return existing element if found, else create one */
if (currBucket != NULL)
return (void *) ELEMENTKEY(currBucket);
- return (void *) TRUE;
- case HASH_FIND_SAVE:
- if (currBucket != NULL)
+ /* get the next free element */
+ currBucket = hctl->freeList;
+ if (currBucket == NULL)
{
- saveState.currBucket = currBucket;
- saveState.prevBucketPtr = prevBucketPtr;
- return (void *) ELEMENTKEY(currBucket);
+ /* no free elements. allocate another chunk of buckets */
+ if (!element_alloc(hashp))
+ return NULL; /* out of memory */
+ currBucket = hctl->freeList;
+ Assert(currBucket != NULL);
}
- return (void *) TRUE;
-
- default:
- /* can't get here */
- return NULL;
- }
-
- /*
- * If we got here, then we didn't find the element and we have to
- * insert it into the hash table
- */
- Assert(currBucket == NULL);
- /* get the next free bucket */
- currBucket = hctl->freeList;
- if (currBucket == NULL)
- {
- /* no free elements. allocate another chunk of buckets */
- if (!element_alloc(hashp))
- return NULL;
- currBucket = hctl->freeList;
- }
- Assert(currBucket != NULL);
-
- hctl->freeList = currBucket->link;
+ hctl->freeList = currBucket->link;
- /* link into chain */
- *prevBucketPtr = currBucket;
- currBucket->link = NULL;
+ /* link into hashbucket chain */
+ *prevBucketPtr = currBucket;
+ currBucket->link = NULL;
- /* copy key into record */
- memcpy(ELEMENTKEY(currBucket), keyPtr, hctl->keysize);
+ /* copy key into record */
+ memcpy(ELEMENTKEY(currBucket), keyPtr, hctl->keysize);
- /*
- * let the caller initialize the data field after hash_search returns.
- */
+ /* caller is expected to fill the data field on return */
- /*
- * Check if it is time to split the segment
- */
- if (++hctl->nentries / (hctl->max_bucket + 1) > hctl->ffactor)
- {
+ /* Check if it is time to split the segment */
+ if (++hctl->nentries / (hctl->max_bucket + 1) > hctl->ffactor)
+ {
+ /*
+ * NOTE: failure to expand table is not a fatal error, it just
+ * means we have to run at higher fill factor than we wanted.
+ */
+ expand_table(hashp);
+ }
- /*
- * NOTE: failure to expand table is not a fatal error, it just
- * means we have to run at higher fill factor than we wanted.
- */
- expand_table(hashp);
+ return (void *) ELEMENTKEY(currBucket);
}
- return (void *) ELEMENTKEY(currBucket);
+ elog(ERROR, "hash_search: bogus action %d", (int) action);
+
+ return NULL; /* keep compiler quiet */
}
/*
* hash_seq_init/_search
* Sequentially search through hash table and return
- * all the elements one by one, return NULL on error and
- * return (void *) TRUE in the end.
+ * all the elements one by one, return NULL when no more.
*
* NOTE: caller may delete the returned element before continuing the scan.
* However, deleting any other element while the scan is in progress is
*/
segp = hashp->dir[segment_num];
if (segp == NULL)
- /* this is probably an error */
- return NULL;
+ hash_corrupted(hashp);
/*
* now find the right index into the segment for the first item in
++status->curBucket;
}
- return (void *) TRUE; /* out of buckets */
+ return NULL; /* out of buckets */
}
return true;
}
+/* complain when we have detected a corrupted hashtable */
+static void
+hash_corrupted(HTAB *hashp)
+{
+ /*
+ * If the corruption is in a shared hashtable, we'd better force a
+ * systemwide restart. Otherwise, just shut down this one backend.
+ */
+ if (hashp->isshared)
+ elog(STOP, "Hash table '%s' corrupted", hashp->tabname);
+ else
+ elog(FATAL, "Hash table '%s' corrupted", hashp->tabname);
+}
+
/* calculate ceil(log base 2) of num */
int
my_log2(long num)
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/mmgr/portalmem.c,v 1.42 2001/10/01 05:36:16 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/mmgr/portalmem.c,v 1.43 2001/10/05 17:28:13 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
-#include "lib/hasht.h"
+#include "utils/hsearch.h"
#include "utils/memutils.h"
#include "utils/portal.h"
* ----------------
*/
-#define MAX_PORTALNAME_LEN 64 /* XXX LONGALIGNable value */
+#define MAX_PORTALNAME_LEN 64
typedef struct portalhashent
{
#define PortalHashTableLookup(NAME, PORTAL) \
do { \
- PortalHashEnt *hentry; bool found; char key[MAX_PORTALNAME_LEN]; \
+ PortalHashEnt *hentry; char key[MAX_PORTALNAME_LEN]; \
\
MemSet(key, 0, MAX_PORTALNAME_LEN); \
snprintf(key, MAX_PORTALNAME_LEN - 1, "%s", NAME); \
hentry = (PortalHashEnt*)hash_search(PortalHashTable, \
- key, HASH_FIND, &found); \
- if (hentry == NULL) \
- elog(FATAL, "error in PortalHashTable"); \
- if (found) \
+ key, HASH_FIND, NULL); \
+ if (hentry) \
PORTAL = hentry->portal; \
else \
PORTAL = NULL; \
hentry = (PortalHashEnt*)hash_search(PortalHashTable, \
key, HASH_ENTER, &found); \
if (hentry == NULL) \
- elog(FATAL, "error in PortalHashTable"); \
+ elog(ERROR, "out of memory in PortalHashTable"); \
if (found) \
elog(NOTICE, "trying to insert a portal name that exists."); \
hentry->portal = PORTAL; \
#define PortalHashTableDelete(PORTAL) \
do { \
- PortalHashEnt *hentry; bool found; char key[MAX_PORTALNAME_LEN]; \
+ PortalHashEnt *hentry; char key[MAX_PORTALNAME_LEN]; \
\
MemSet(key, 0, MAX_PORTALNAME_LEN); \
snprintf(key, MAX_PORTALNAME_LEN - 1, "%s", PORTAL->name); \
hentry = (PortalHashEnt*)hash_search(PortalHashTable, \
- key, HASH_REMOVE, &found); \
+ key, HASH_REMOVE, NULL); \
if (hentry == NULL) \
- elog(FATAL, "error in PortalHashTable"); \
- if (!found) \
elog(NOTICE, "trying to delete portal name that does not exist."); \
} while(0)
* use PORTALS_PER_USER, defined in utils/portal.h as a guess of how
* many hash table entries to create, initially
*/
- PortalHashTable = hash_create(PORTALS_PER_USER * 3, &ctl, HASH_ELEM);
+ PortalHashTable = hash_create("Portal hash", PORTALS_PER_USER,
+ &ctl, HASH_ELEM);
}
/*
* Exceptions:
* BadState if called when disabled.
* BadArg if portal is invalid.
- *
- * Note peculiar calling convention: pass a pointer to a portal pointer.
- * This is mainly so that this routine can be used as a hashtable walker.
*/
void
-PortalDrop(Portal *portalP)
+PortalDrop(Portal portal)
{
- Portal portal = *portalP;
-
AssertArg(PortalIsValid(portal));
/* remove portal from hash table */
/*
* Destroy all portals created in the current transaction (ie, all of them).
+ *
+ * XXX This assumes that portals can be deleted in a random order, ie,
+ * no portal has a reference to any other (at least not one that will be
+ * exercised during deletion). I think this is okay at the moment, but
+ * we've had bugs of that ilk in the past. Keep a close eye on cursor
+ * references...
*/
void
AtEOXact_portals(void)
{
- HashTableWalk(PortalHashTable, (HashtFunc) PortalDrop, 0);
+ HASH_SEQ_STATUS status;
+ PortalHashEnt *hentry;
+
+ hash_seq_init(&status, PortalHashTable);
+
+ while ((hentry = (PortalHashEnt *) hash_seq_search(&status)) != NULL)
+ {
+ PortalDrop(hentry->portal);
+ }
}
+++ /dev/null
-/*-------------------------------------------------------------------------
- *
- * hasht.h
- * hash table related functions that are not directly supported
- * under utils/hash.
- *
- *
- * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- * $Id: hasht.h,v 1.12 2001/01/24 19:43:24 momjian Exp $
- *
- *-------------------------------------------------------------------------
- */
-#ifndef HASHT_H
-#define HASHT_H
-
-#include "utils/hsearch.h"
-
-typedef void (*HashtFunc) (void *hashitem, Datum arg);
-
-extern void HashTableWalk(HTAB *hashtable, HashtFunc function, Datum arg);
-
-#endif /* HASHT_H */
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: shmem.h,v 1.32 2001/10/01 05:36:17 tgl Exp $
+ * $Id: shmem.h,v 1.33 2001/10/05 17:28:13 tgl Exp $
*
*-------------------------------------------------------------------------
*/
extern void *ShmemAlloc(Size size);
extern bool ShmemIsValid(unsigned long addr);
extern void InitShmemIndex(void);
-extern HTAB *ShmemInitHash(char *name, long init_size, long max_size,
+extern HTAB *ShmemInitHash(const char *name, long init_size, long max_size,
HASHCTL *infoP, int hash_flags);
-extern void *ShmemInitStruct(char *name, Size size, bool *foundPtr);
+extern void *ShmemInitStruct(const char *name, Size size, bool *foundPtr);
/* size constants for the shmem index table */
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: hsearch.h,v 1.21 2001/10/01 05:36:17 tgl Exp $
+ * $Id: hsearch.h,v 1.22 2001/10/05 17:28:13 tgl Exp $
*
*-------------------------------------------------------------------------
*/
/*
* 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.
+ * is expected to be at the start of the caller's hash entry data structure.
*/
typedef struct HASHELEMENT
{
typedef struct HTAB
{
HASHHDR *hctl; /* shared control information */
- long (*hash) (void *key, int keysize); /* Hash Function */
HASHSEGMENT *dir; /* directory of segment starts */
+ long (*hash) (void *key, int keysize); /* Hash Function */
void *(*alloc) (Size);/* memory allocator */
MemoryContext hcxt; /* memory context if default allocator used */
+ char *tabname; /* table name (for error messages) */
+ bool isshared; /* true if table is in shared memory */
} HTAB;
/* Parameter data structure for hash_create */
/*
* prototypes for functions in dynahash.c
*/
-extern HTAB *hash_create(long nelem, HASHCTL *info, int flags);
+extern HTAB *hash_create(const char *tabname, long nelem,
+ HASHCTL *info, int flags);
extern void hash_destroy(HTAB *hashp);
-extern void hash_stats(char *where, HTAB *hashp);
+extern void hash_stats(const char *where, HTAB *hashp);
extern void *hash_search(HTAB *hashp, void *keyPtr, HASHACTION action,
bool *foundPtr);
extern void hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp);
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: portal.h,v 1.28 2001/05/21 14:22:18 wieck Exp $
+ * $Id: portal.h,v 1.29 2001/10/05 17:28:13 tgl Exp $
*
*-------------------------------------------------------------------------
*/
extern void EnablePortalManager(void);
extern void AtEOXact_portals(void);
extern Portal CreatePortal(char *name);
-extern void PortalDrop(Portal *portalP);
+extern void PortalDrop(Portal portal);
extern Portal GetPortalByName(char *name);
extern void PortalSetQuery(Portal portal, QueryDesc *queryDesc,
TupleDesc attinfo, EState *state,