Commit 8a52b893 authored by Tom Lane's avatar Tom Lane

Further cleanup of dynahash.c API, in pursuit of portability and

readability.  Bizarre '(long *) TRUE' return convention is gone,
in favor of just raising an error internally in dynahash.c when
we detect hashtable corruption.  HashTableWalk is gone, in favor
of using hash_seq_search directly, since it had no hope of working
with non-LONGALIGNable datatypes.  Simplify some other code that was
made undesirably grotty by promixity to HashTableWalk.
parent 34331802
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -15,9 +15,9 @@ ...@@ -15,9 +15,9 @@
#include "access/htup.h" #include "access/htup.h"
#include "access/xlogutils.h" #include "access/xlogutils.h"
#include "catalog/pg_database.h" #include "catalog/pg_database.h"
#include "lib/hasht.h"
#include "storage/bufpage.h" #include "storage/bufpage.h"
#include "storage/smgr.h" #include "storage/smgr.h"
#include "utils/hsearch.h"
#include "utils/relcache.h" #include "utils/relcache.h"
...@@ -233,27 +233,22 @@ _xl_init_rel_cache(void) ...@@ -233,27 +233,22 @@ _xl_init_rel_cache(void)
ctl.entrysize = sizeof(XLogRelCacheEntry); ctl.entrysize = sizeof(XLogRelCacheEntry);
ctl.hash = tag_hash; ctl.hash = tag_hash;
_xlrelcache = hash_create(_XLOG_RELCACHESIZE, &ctl, _xlrelcache = hash_create("XLOG relcache", _XLOG_RELCACHESIZE,
HASH_ELEM | HASH_FUNCTION); &ctl, HASH_ELEM | HASH_FUNCTION);
} }
static void 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; Form_pg_class tpgc = rdesc->reldata.rd_rel;
XLogRelCacheEntry *hentry;
rdesc->lessRecently->moreRecently = rdesc->moreRecently; rdesc->lessRecently->moreRecently = rdesc->moreRecently;
rdesc->moreRecently->lessRecently = rdesc->lessRecently; rdesc->moreRecently->lessRecently = rdesc->lessRecently;
hentry = (XLogRelCacheEntry *) hash_search(_xlrelcache, hentry = (XLogRelCacheEntry *) hash_search(_xlrelcache,
(void *) &(rdesc->reldata.rd_node), HASH_REMOVE, &found); (void *) &(rdesc->reldata.rd_node), HASH_REMOVE, NULL);
if (hentry == 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"); elog(STOP, "_xl_remove_hash_entry: file was not found in cache");
if (rdesc->reldata.rd_fd >= 0) if (rdesc->reldata.rd_fd >= 0)
...@@ -281,7 +276,7 @@ _xl_new_reldesc(void) ...@@ -281,7 +276,7 @@ _xl_new_reldesc(void)
/* reuse */ /* reuse */
res = _xlrelarr[0].moreRecently; res = _xlrelarr[0].moreRecently;
_xl_remove_hash_entry(&res, 0); _xl_remove_hash_entry(res);
_xlast--; _xlast--;
return (res); return (res);
...@@ -298,13 +293,21 @@ XLogInitRelationCache(void) ...@@ -298,13 +293,21 @@ XLogInitRelationCache(void)
void void
XLogCloseRelationCache(void) XLogCloseRelationCache(void)
{ {
HASH_SEQ_STATUS status;
XLogRelCacheEntry *hentry;
DestroyDummyCaches(); DestroyDummyCaches();
if (!_xlrelarr) if (!_xlrelarr)
return; 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); hash_destroy(_xlrelcache);
free(_xlrelarr); free(_xlrelarr);
...@@ -321,12 +324,9 @@ XLogOpenRelation(bool redo, RmgrId rmid, RelFileNode rnode) ...@@ -321,12 +324,9 @@ XLogOpenRelation(bool redo, RmgrId rmid, RelFileNode rnode)
bool found; bool found;
hentry = (XLogRelCacheEntry *) hentry = (XLogRelCacheEntry *)
hash_search(_xlrelcache, (void *) &rnode, HASH_FIND, &found); hash_search(_xlrelcache, (void *) &rnode, HASH_FIND, NULL);
if (hentry == NULL) if (hentry)
elog(STOP, "XLogOpenRelation: error in cache");
if (found)
{ {
res = hentry->rdesc; res = hentry->rdesc;
...@@ -348,7 +348,7 @@ XLogOpenRelation(bool redo, RmgrId rmid, RelFileNode rnode) ...@@ -348,7 +348,7 @@ XLogOpenRelation(bool redo, RmgrId rmid, RelFileNode rnode)
hash_search(_xlrelcache, (void *) &rnode, HASH_ENTER, &found); hash_search(_xlrelcache, (void *) &rnode, HASH_ENTER, &found);
if (hentry == NULL) if (hentry == NULL)
elog(STOP, "XLogOpenRelation: can't insert into cache"); elog(STOP, "XLogOpenRelation: out of memory for cache");
if (found) if (found)
elog(STOP, "XLogOpenRelation: file found on insert into cache"); elog(STOP, "XLogOpenRelation: file found on insert into cache");
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
* The PerformAddAttribute() code, like most of the relation * The PerformAddAttribute() code, like most of the relation
...@@ -259,7 +259,7 @@ PerformPortalClose(char *name, CommandDest dest) ...@@ -259,7 +259,7 @@ PerformPortalClose(char *name, CommandDest dest)
/* /*
* Note: PortalCleanup is called as a side-effect * Note: PortalCleanup is called as a side-effect
*/ */
PortalDrop(&portal); PortalDrop(portal);
} }
/* ---------------- /* ----------------
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -783,12 +783,10 @@ SPI_cursor_move(Portal portal, bool forward, int count) ...@@ -783,12 +783,10 @@ SPI_cursor_move(Portal portal, bool forward, int count)
void void
SPI_cursor_close(Portal portal) SPI_cursor_close(Portal portal)
{ {
Portal my_portal = portal; if (!PortalIsValid(portal))
if (!PortalIsValid(my_portal))
elog(ERROR, "invalid portal in SPI cursor operation"); elog(ERROR, "invalid portal in SPI cursor operation");
PortalDrop(&my_portal); PortalDrop(portal);
} }
/* =================== private functions =================== */ /* =================== private functions =================== */
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
# Makefile for lib (miscellaneous stuff) # Makefile for lib (miscellaneous stuff)
# #
# IDENTIFICATION # 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 $
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
...@@ -12,7 +12,7 @@ subdir = src/backend/lib ...@@ -12,7 +12,7 @@ subdir = src/backend/lib
top_builddir = ../../.. top_builddir = ../../..
include $(top_builddir)/src/Makefile.global 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 all: SUBSYS.o
......
/*-------------------------------------------------------------------------
*
* 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);
}
}
This diff is collapsed.
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -62,21 +62,15 @@ BufferDesc * ...@@ -62,21 +62,15 @@ BufferDesc *
BufTableLookup(BufferTag *tagPtr) BufTableLookup(BufferTag *tagPtr)
{ {
BufferLookupEnt *result; BufferLookupEnt *result;
bool found;
if (tagPtr->blockNum == P_NEW) if (tagPtr->blockNum == P_NEW)
return NULL; return NULL;
result = (BufferLookupEnt *) result = (BufferLookupEnt *)
hash_search(SharedBufHash, (void *) tagPtr, HASH_FIND, &found); hash_search(SharedBufHash, (void *) tagPtr, HASH_FIND, NULL);
if (!result) if (!result)
{
elog(ERROR, "BufTableLookup: BufferLookup table corrupted");
return NULL;
}
if (!found)
return NULL; return NULL;
return &(BufferDescriptors[result->id]); return &(BufferDescriptors[result->id]);
} }
...@@ -87,7 +81,6 @@ bool ...@@ -87,7 +81,6 @@ bool
BufTableDelete(BufferDesc *buf) BufTableDelete(BufferDesc *buf)
{ {
BufferLookupEnt *result; BufferLookupEnt *result;
bool found;
/* /*
* buffer not initialized or has been removed from table already. * buffer not initialized or has been removed from table already.
...@@ -99,10 +92,11 @@ BufTableDelete(BufferDesc *buf) ...@@ -99,10 +92,11 @@ BufTableDelete(BufferDesc *buf)
buf->flags |= BM_DELETED; buf->flags |= BM_DELETED;
result = (BufferLookupEnt *) 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"); elog(ERROR, "BufTableDelete: BufferLookup table corrupted");
return FALSE; return FALSE;
} }
...@@ -134,14 +128,13 @@ BufTableInsert(BufferDesc *buf) ...@@ -134,14 +128,13 @@ BufTableInsert(BufferDesc *buf)
if (!result) if (!result)
{ {
Assert(0); elog(ERROR, "BufTableInsert: BufferLookup table out of memory");
elog(ERROR, "BufTableInsert: BufferLookup table corrupted");
return FALSE; return FALSE;
} }
/* found something else in the table ! */ /* found something else in the table ! */
if (found) if (found)
{ {
Assert(0);
elog(ERROR, "BufTableInsert: BufferLookup table corrupted"); elog(ERROR, "BufTableInsert: BufferLookup table corrupted");
return FALSE; return FALSE;
} }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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: * NOTES:
...@@ -490,16 +490,12 @@ static FSMRelation * ...@@ -490,16 +490,12 @@ static FSMRelation *
lookup_fsm_rel(RelFileNode *rel) lookup_fsm_rel(RelFileNode *rel)
{ {
FSMRelation *fsmrel; FSMRelation *fsmrel;
bool found;
fsmrel = (FSMRelation *) hash_search(FreeSpaceMap->relHash, fsmrel = (FSMRelation *) hash_search(FreeSpaceMap->relHash,
(void *) rel, (void *) rel,
HASH_FIND, HASH_FIND,
&found); NULL);
if (!fsmrel) if (!fsmrel)
elog(ERROR, "FreeSpaceMap hashtable corrupted");
if (!found)
return NULL; return NULL;
return fsmrel; return fsmrel;
...@@ -523,7 +519,7 @@ create_fsm_rel(RelFileNode *rel) ...@@ -523,7 +519,7 @@ create_fsm_rel(RelFileNode *rel)
HASH_ENTER, HASH_ENTER,
&found); &found);
if (!fsmrel) if (!fsmrel)
elog(ERROR, "FreeSpaceMap hashtable corrupted"); elog(ERROR, "FreeSpaceMap hashtable out of memory");
if (!found) if (!found)
{ {
...@@ -584,7 +580,6 @@ static void ...@@ -584,7 +580,6 @@ static void
delete_fsm_rel(FSMRelation *fsmrel) delete_fsm_rel(FSMRelation *fsmrel)
{ {
FSMRelation *result; FSMRelation *result;
bool found;
free_chunk_chain(fsmrel->relChunks); free_chunk_chain(fsmrel->relChunks);
unlink_fsm_rel(fsmrel); unlink_fsm_rel(fsmrel);
...@@ -592,8 +587,8 @@ delete_fsm_rel(FSMRelation *fsmrel) ...@@ -592,8 +587,8 @@ delete_fsm_rel(FSMRelation *fsmrel)
result = (FSMRelation *) hash_search(FreeSpaceMap->relHash, result = (FSMRelation *) hash_search(FreeSpaceMap->relHash,
(void *) &(fsmrel->key), (void *) &(fsmrel->key),
HASH_REMOVE, HASH_REMOVE,
&found); NULL);
if (!result || !found) if (!result)
elog(ERROR, "FreeSpaceMap hashtable corrupted"); elog(ERROR, "FreeSpaceMap hashtable corrupted");
} }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -210,7 +210,7 @@ InitShmemIndex(void) ...@@ -210,7 +210,7 @@ InitShmemIndex(void)
result = (ShmemIndexEnt *) result = (ShmemIndexEnt *)
hash_search(ShmemIndex, (void *) &item, HASH_ENTER, &found); hash_search(ShmemIndex, (void *) &item, HASH_ENTER, &found);
if (!result) if (!result)
elog(FATAL, "InitShmemIndex: corrupted shmem index"); elog(FATAL, "InitShmemIndex: Shmem Index out of memory");
Assert(ShmemBootstrap && !found); Assert(ShmemBootstrap && !found);
...@@ -234,7 +234,7 @@ InitShmemIndex(void) ...@@ -234,7 +234,7 @@ InitShmemIndex(void)
* table at once. * table at once.
*/ */
HTAB * 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 init_size, /* initial table size */
long max_size, /* max size of the table */ long max_size, /* max size of the table */
HASHCTL *infoP, /* info about key and bucket size */ HASHCTL *infoP, /* info about key and bucket size */
...@@ -277,7 +277,7 @@ ShmemInitHash(char *name, /* table string name for shmem index */ ...@@ -277,7 +277,7 @@ ShmemInitHash(char *name, /* table string name for shmem index */
infoP->hctl = (HASHHDR *) location; infoP->hctl = (HASHHDR *) location;
infoP->dir = (HASHSEGMENT *) (((char *) location) + sizeof(HASHHDR)); infoP->dir = (HASHSEGMENT *) (((char *) location) + sizeof(HASHHDR));
return hash_create(init_size, infoP, hash_flags); return hash_create(name, init_size, infoP, hash_flags);
} }
/* /*
...@@ -295,7 +295,7 @@ ShmemInitHash(char *name, /* table string name for shmem index */ ...@@ -295,7 +295,7 @@ ShmemInitHash(char *name, /* table string name for shmem index */
* initialized). * initialized).
*/ */
void * void *
ShmemInitStruct(char *name, Size size, bool *foundPtr) ShmemInitStruct(const char *name, Size size, bool *foundPtr)
{ {
ShmemIndexEnt *result, ShmemIndexEnt *result,
item; item;
...@@ -328,7 +328,7 @@ ShmemInitStruct(char *name, Size size, bool *foundPtr) ...@@ -328,7 +328,7 @@ ShmemInitStruct(char *name, Size size, bool *foundPtr)
if (!result) if (!result)
{ {
LWLockRelease(ShmemIndexLock); LWLockRelease(ShmemIndexLock);
elog(ERROR, "ShmemInitStruct: Shmem Index corrupted"); elog(ERROR, "ShmemInitStruct: Shmem Index out of memory");
return NULL; return NULL;
} }
...@@ -357,12 +357,12 @@ ShmemInitStruct(char *name, Size size, bool *foundPtr) ...@@ -357,12 +357,12 @@ ShmemInitStruct(char *name, Size size, bool *foundPtr)
{ {
/* out of memory */ /* out of memory */
Assert(ShmemIndex); Assert(ShmemIndex);
hash_search(ShmemIndex, (void *) &item, HASH_REMOVE, foundPtr); hash_search(ShmemIndex, (void *) &item, HASH_REMOVE, NULL);
LWLockRelease(ShmemIndexLock); LWLockRelease(ShmemIndexLock);
*foundPtr = FALSE;
elog(NOTICE, "ShmemInitStruct: cannot allocate '%s'", elog(NOTICE, "ShmemInitStruct: cannot allocate '%s'",
name); name);
*foundPtr = FALSE;
return NULL; return NULL;
} }
result->size = size; result->size = size;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
* Outside modules can create a lock table and acquire/release * Outside modules can create a lock table and acquire/release
...@@ -491,7 +491,8 @@ LockAcquire(LOCKMETHOD lockmethod, LOCKTAG *locktag, ...@@ -491,7 +491,8 @@ LockAcquire(LOCKMETHOD lockmethod, LOCKTAG *locktag,
if (!lock) if (!lock)
{ {
LWLockRelease(masterLock); LWLockRelease(masterLock);
elog(FATAL, "LockAcquire: lock table %d is corrupted", lockmethod); elog(ERROR, "LockAcquire: lock table %d is out of memory",
lockmethod);
return FALSE; return FALSE;
} }
...@@ -537,7 +538,7 @@ LockAcquire(LOCKMETHOD lockmethod, LOCKTAG *locktag, ...@@ -537,7 +538,7 @@ LockAcquire(LOCKMETHOD lockmethod, LOCKTAG *locktag,
if (!holder) if (!holder)
{ {
LWLockRelease(masterLock); LWLockRelease(masterLock);
elog(FATAL, "LockAcquire: holder table corrupted"); elog(ERROR, "LockAcquire: holder table out of memory");
return FALSE; return FALSE;
} }
...@@ -658,8 +659,8 @@ LockAcquire(LOCKMETHOD lockmethod, LOCKTAG *locktag, ...@@ -658,8 +659,8 @@ LockAcquire(LOCKMETHOD lockmethod, LOCKTAG *locktag,
SHMQueueDelete(&holder->procLink); SHMQueueDelete(&holder->procLink);
holder = (HOLDER *) hash_search(holderTable, holder = (HOLDER *) hash_search(holderTable,
(void *) holder, (void *) holder,
HASH_REMOVE, &found); HASH_REMOVE, NULL);
if (!holder || !found) if (!holder)
elog(NOTICE, "LockAcquire: remove holder, table corrupted"); elog(NOTICE, "LockAcquire: remove holder, table corrupted");
} }
else else
...@@ -991,7 +992,6 @@ LockRelease(LOCKMETHOD lockmethod, LOCKTAG *locktag, ...@@ -991,7 +992,6 @@ LockRelease(LOCKMETHOD lockmethod, LOCKTAG *locktag,
{ {
LOCK *lock; LOCK *lock;
LWLockId masterLock; LWLockId masterLock;
bool found;
LOCKMETHODTABLE *lockMethodTable; LOCKMETHODTABLE *lockMethodTable;
HOLDER *holder; HOLDER *holder;
HOLDERTAG holdertag; HOLDERTAG holdertag;
...@@ -1023,20 +1023,13 @@ LockRelease(LOCKMETHOD lockmethod, LOCKTAG *locktag, ...@@ -1023,20 +1023,13 @@ LockRelease(LOCKMETHOD lockmethod, LOCKTAG *locktag,
Assert(lockMethodTable->lockHash->hash == tag_hash); Assert(lockMethodTable->lockHash->hash == tag_hash);
lock = (LOCK *) hash_search(lockMethodTable->lockHash, lock = (LOCK *) hash_search(lockMethodTable->lockHash,
(void *) locktag, (void *) locktag,
HASH_FIND, &found); HASH_FIND, NULL);
/* /*
* let the caller print its own error message, too. Do not * let the caller print its own error message, too. Do not
* elog(ERROR). * elog(ERROR).
*/ */
if (!lock) if (!lock)
{
LWLockRelease(masterLock);
elog(NOTICE, "LockRelease: locktable corrupted");
return FALSE;
}
if (!found)
{ {
LWLockRelease(masterLock); LWLockRelease(masterLock);
elog(NOTICE, "LockRelease: no such lock"); elog(NOTICE, "LockRelease: no such lock");
...@@ -1056,12 +1049,12 @@ LockRelease(LOCKMETHOD lockmethod, LOCKTAG *locktag, ...@@ -1056,12 +1049,12 @@ LockRelease(LOCKMETHOD lockmethod, LOCKTAG *locktag,
holderTable = lockMethodTable->holderHash; holderTable = lockMethodTable->holderHash;
holder = (HOLDER *) hash_search(holderTable, holder = (HOLDER *) hash_search(holderTable,
(void *) &holdertag, (void *) &holdertag,
HASH_FIND_SAVE, &found); HASH_FIND_SAVE, NULL);
if (!holder || !found) if (!holder)
{ {
LWLockRelease(masterLock); LWLockRelease(masterLock);
#ifdef USER_LOCKS #ifdef USER_LOCKS
if (!found && lockmethod == USER_LOCKMETHOD) if (lockmethod == USER_LOCKMETHOD)
elog(NOTICE, "LockRelease: no lock with this tag"); elog(NOTICE, "LockRelease: no lock with this tag");
else else
#endif #endif
...@@ -1130,8 +1123,8 @@ LockRelease(LOCKMETHOD lockmethod, LOCKTAG *locktag, ...@@ -1130,8 +1123,8 @@ LockRelease(LOCKMETHOD lockmethod, LOCKTAG *locktag,
lock = (LOCK *) hash_search(lockMethodTable->lockHash, lock = (LOCK *) hash_search(lockMethodTable->lockHash,
(void *) &(lock->tag), (void *) &(lock->tag),
HASH_REMOVE, HASH_REMOVE,
&found); NULL);
if (!lock || !found) if (!lock)
{ {
LWLockRelease(masterLock); LWLockRelease(masterLock);
elog(NOTICE, "LockRelease: remove lock, table corrupted"); elog(NOTICE, "LockRelease: remove lock, table corrupted");
...@@ -1159,8 +1152,8 @@ LockRelease(LOCKMETHOD lockmethod, LOCKTAG *locktag, ...@@ -1159,8 +1152,8 @@ LockRelease(LOCKMETHOD lockmethod, LOCKTAG *locktag,
SHMQueueDelete(&holder->procLink); SHMQueueDelete(&holder->procLink);
holder = (HOLDER *) hash_search(holderTable, holder = (HOLDER *) hash_search(holderTable,
(void *) &holder, (void *) &holder,
HASH_REMOVE_SAVED, &found); HASH_REMOVE_SAVED, NULL);
if (!holder || !found) if (!holder)
{ {
LWLockRelease(masterLock); LWLockRelease(masterLock);
elog(NOTICE, "LockRelease: remove holder, table corrupted"); elog(NOTICE, "LockRelease: remove holder, table corrupted");
...@@ -1201,7 +1194,6 @@ LockReleaseAll(LOCKMETHOD lockmethod, PROC *proc, ...@@ -1201,7 +1194,6 @@ LockReleaseAll(LOCKMETHOD lockmethod, PROC *proc,
int i, int i,
numLockModes; numLockModes;
LOCK *lock; LOCK *lock;
bool found;
#ifdef LOCK_DEBUG #ifdef LOCK_DEBUG
if (lockmethod == USER_LOCKMETHOD ? Trace_userlocks : Trace_locks) if (lockmethod == USER_LOCKMETHOD ? Trace_userlocks : Trace_locks)
...@@ -1313,8 +1305,8 @@ LockReleaseAll(LOCKMETHOD lockmethod, PROC *proc, ...@@ -1313,8 +1305,8 @@ LockReleaseAll(LOCKMETHOD lockmethod, PROC *proc,
holder = (HOLDER *) hash_search(lockMethodTable->holderHash, holder = (HOLDER *) hash_search(lockMethodTable->holderHash,
(void *) holder, (void *) holder,
HASH_REMOVE, HASH_REMOVE,
&found); NULL);
if (!holder || !found) if (!holder)
{ {
LWLockRelease(masterLock); LWLockRelease(masterLock);
elog(NOTICE, "LockReleaseAll: holder table corrupted"); elog(NOTICE, "LockReleaseAll: holder table corrupted");
...@@ -1323,7 +1315,6 @@ LockReleaseAll(LOCKMETHOD lockmethod, PROC *proc, ...@@ -1323,7 +1315,6 @@ LockReleaseAll(LOCKMETHOD lockmethod, PROC *proc,
if (lock->nRequested == 0) if (lock->nRequested == 0)
{ {
/* /*
* We've just released the last lock, so garbage-collect the * We've just released the last lock, so garbage-collect the
* lock object. * lock object.
...@@ -1332,8 +1323,8 @@ LockReleaseAll(LOCKMETHOD lockmethod, PROC *proc, ...@@ -1332,8 +1323,8 @@ LockReleaseAll(LOCKMETHOD lockmethod, PROC *proc,
Assert(lockMethodTable->lockHash->hash == tag_hash); Assert(lockMethodTable->lockHash->hash == tag_hash);
lock = (LOCK *) hash_search(lockMethodTable->lockHash, lock = (LOCK *) hash_search(lockMethodTable->lockHash,
(void *) &(lock->tag), (void *) &(lock->tag),
HASH_REMOVE, &found); HASH_REMOVE, NULL);
if (!lock || !found) if (!lock)
{ {
LWLockRelease(masterLock); LWLockRelease(masterLock);
elog(NOTICE, "LockReleaseAll: cannot remove lock from HTAB"); elog(NOTICE, "LockReleaseAll: cannot remove lock from HTAB");
...@@ -1438,7 +1429,7 @@ void ...@@ -1438,7 +1429,7 @@ void
DumpAllLocks(void) DumpAllLocks(void)
{ {
PROC *proc; PROC *proc;
HOLDER *holder = NULL; HOLDER *holder;
LOCK *lock; LOCK *lock;
int lockmethod = DEFAULT_LOCKMETHOD; int lockmethod = DEFAULT_LOCKMETHOD;
LOCKMETHODTABLE *lockMethodTable; LOCKMETHODTABLE *lockMethodTable;
...@@ -1460,8 +1451,7 @@ DumpAllLocks(void) ...@@ -1460,8 +1451,7 @@ DumpAllLocks(void)
LOCK_PRINT("DumpAllLocks: waiting on", proc->waitLock, 0); LOCK_PRINT("DumpAllLocks: waiting on", proc->waitLock, 0);
hash_seq_init(&status, holderTable); hash_seq_init(&status, holderTable);
while ((holder = (HOLDER *) hash_seq_search(&status)) && while ((holder = (HOLDER *) hash_seq_search(&status)) != NULL)
(holder != (HOLDER *) TRUE))
{ {
HOLDER_PRINT("DumpAllLocks", holder); HOLDER_PRINT("DumpAllLocks", holder);
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* *
* *
* IDENTIFICATION * 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 $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -186,7 +186,7 @@ mmcreate(Relation reln) ...@@ -186,7 +186,7 @@ mmcreate(Relation reln)
if (entry == (MMRelHashEntry *) NULL) if (entry == (MMRelHashEntry *) NULL)
{ {
LWLockRelease(MMCacheLock); 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) if (found)
...@@ -214,7 +214,6 @@ mmunlink(RelFileNode rnode) ...@@ -214,7 +214,6 @@ mmunlink(RelFileNode rnode)
int i; int i;
MMHashEntry *entry; MMHashEntry *entry;
MMRelHashEntry *rentry; MMRelHashEntry *rentry;
bool found;
MMRelTag rtag; MMRelTag rtag;
LWLockAcquire(MMCacheLock, LW_EXCLUSIVE); LWLockAcquire(MMCacheLock, LW_EXCLUSIVE);
...@@ -226,8 +225,8 @@ mmunlink(RelFileNode rnode) ...@@ -226,8 +225,8 @@ mmunlink(RelFileNode rnode)
{ {
entry = (MMHashEntry *) hash_search(MMCacheHT, entry = (MMHashEntry *) hash_search(MMCacheHT,
(void *) &MMBlockTags[i], (void *) &MMBlockTags[i],
HASH_REMOVE, &found); HASH_REMOVE, NULL);
if (entry == (MMHashEntry *) NULL || !found) if (entry == (MMHashEntry *) NULL)
{ {
LWLockRelease(MMCacheLock); LWLockRelease(MMCacheLock);
elog(FATAL, "mmunlink: cache hash table corrupted"); elog(FATAL, "mmunlink: cache hash table corrupted");
...@@ -242,9 +241,9 @@ mmunlink(RelFileNode rnode) ...@@ -242,9 +241,9 @@ mmunlink(RelFileNode rnode)
rentry = (MMRelHashEntry *) hash_search(MMRelCacheHT, rentry = (MMRelHashEntry *) hash_search(MMRelCacheHT,
(void *) &rtag, (void *) &rtag,
HASH_REMOVE, &found); HASH_REMOVE, NULL);
if (rentry == (MMRelHashEntry *) NULL || !found) if (rentry == (MMRelHashEntry *) NULL)
{ {
LWLockRelease(MMCacheLock); LWLockRelease(MMCacheLock);
elog(FATAL, "mmunlink: rel cache hash table corrupted"); elog(FATAL, "mmunlink: rel cache hash table corrupted");
...@@ -306,8 +305,8 @@ mmextend(Relation reln, BlockNumber blocknum, char *buffer) ...@@ -306,8 +305,8 @@ mmextend(Relation reln, BlockNumber blocknum, char *buffer)
rentry = (MMRelHashEntry *) hash_search(MMRelCacheHT, rentry = (MMRelHashEntry *) hash_search(MMRelCacheHT,
(void *) &rtag, (void *) &rtag,
HASH_FIND, &found); HASH_FIND, NULL);
if (rentry == (MMRelHashEntry *) NULL || !found) if (rentry == (MMRelHashEntry *) NULL)
{ {
LWLockRelease(MMCacheLock); LWLockRelease(MMCacheLock);
elog(FATAL, "mmextend: rel cache hash table corrupt"); elog(FATAL, "mmextend: rel cache hash table corrupt");
...@@ -372,7 +371,6 @@ int ...@@ -372,7 +371,6 @@ int
mmread(Relation reln, BlockNumber blocknum, char *buffer) mmread(Relation reln, BlockNumber blocknum, char *buffer)
{ {
MMHashEntry *entry; MMHashEntry *entry;
bool found;
int offset; int offset;
MMCacheTag tag; MMCacheTag tag;
...@@ -387,15 +385,9 @@ mmread(Relation reln, BlockNumber blocknum, char *buffer) ...@@ -387,15 +385,9 @@ mmread(Relation reln, BlockNumber blocknum, char *buffer)
LWLockAcquire(MMCacheLock, LW_EXCLUSIVE); LWLockAcquire(MMCacheLock, LW_EXCLUSIVE);
entry = (MMHashEntry *) hash_search(MMCacheHT, entry = (MMHashEntry *) hash_search(MMCacheHT,
(void *) &tag, (void *) &tag,
HASH_FIND, &found); HASH_FIND, NULL);
if (entry == (MMHashEntry *) 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 */ /* reading nonexistent pages is defined to fill them with zeroes */
LWLockRelease(MMCacheLock); LWLockRelease(MMCacheLock);
...@@ -420,7 +412,6 @@ int ...@@ -420,7 +412,6 @@ int
mmwrite(Relation reln, BlockNumber blocknum, char *buffer) mmwrite(Relation reln, BlockNumber blocknum, char *buffer)
{ {
MMHashEntry *entry; MMHashEntry *entry;
bool found;
int offset; int offset;
MMCacheTag tag; MMCacheTag tag;
...@@ -435,15 +426,9 @@ mmwrite(Relation reln, BlockNumber blocknum, char *buffer) ...@@ -435,15 +426,9 @@ mmwrite(Relation reln, BlockNumber blocknum, char *buffer)
LWLockAcquire(MMCacheLock, LW_EXCLUSIVE); LWLockAcquire(MMCacheLock, LW_EXCLUSIVE);
entry = (MMHashEntry *) hash_search(MMCacheHT, entry = (MMHashEntry *) hash_search(MMCacheHT,
(void *) &tag, (void *) &tag,
HASH_FIND, &found); HASH_FIND, NULL);
if (entry == (MMHashEntry *) NULL) if (entry == (MMHashEntry *) NULL)
{
LWLockRelease(MMCacheLock);
elog(FATAL, "mmread: hash table corrupt");
}
if (!found)
{ {
LWLockRelease(MMCacheLock); LWLockRelease(MMCacheLock);
elog(FATAL, "mmwrite: hash table missing requested page"); elog(FATAL, "mmwrite: hash table missing requested page");
...@@ -496,7 +481,6 @@ mmnblocks(Relation reln) ...@@ -496,7 +481,6 @@ mmnblocks(Relation reln)
{ {
MMRelTag rtag; MMRelTag rtag;
MMRelHashEntry *rentry; MMRelHashEntry *rentry;
bool found;
BlockNumber nblocks; BlockNumber nblocks;
if (reln->rd_rel->relisshared) if (reln->rd_rel->relisshared)
...@@ -510,15 +494,9 @@ mmnblocks(Relation reln) ...@@ -510,15 +494,9 @@ mmnblocks(Relation reln)
rentry = (MMRelHashEntry *) hash_search(MMRelCacheHT, rentry = (MMRelHashEntry *) hash_search(MMRelCacheHT,
(void *) &rtag, (void *) &rtag,
HASH_FIND, &found); HASH_FIND, NULL);
if (rentry == (MMRelHashEntry *) NULL)
{
LWLockRelease(MMCacheLock);
elog(FATAL, "mmnblocks: rel cache hash table corrupt");
}
if (found) if (rentry)
nblocks = rentry->mmrhe_nblocks; nblocks = rentry->mmrhe_nblocks;
else else
nblocks = InvalidBlockNumber; nblocks = InvalidBlockNumber;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -147,7 +147,7 @@ PreparePortal(char *portalName) ...@@ -147,7 +147,7 @@ PreparePortal(char *portalName)
*/ */
elog(NOTICE, "Closing pre-existing portal \"%s\"", elog(NOTICE, "Closing pre-existing portal \"%s\"",
portalName); portalName);
PortalDrop(&portal); PortalDrop(portal);
} }
/* /*
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
* Portions Copyright (c) 2000-2001, PostgreSQL Global Development Group * Portions Copyright (c) 2000-2001, PostgreSQL Global Development Group
* Copyright 1999 Jan Wieck * 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 $
* *
* ---------- * ----------
*/ */
...@@ -2990,14 +2990,14 @@ ri_InitHashTables(void) ...@@ -2990,14 +2990,14 @@ ri_InitHashTables(void)
ctl.keysize = sizeof(RI_QueryKey); ctl.keysize = sizeof(RI_QueryKey);
ctl.entrysize = sizeof(RI_QueryHashEntry); ctl.entrysize = sizeof(RI_QueryHashEntry);
ctl.hash = tag_hash; ctl.hash = tag_hash;
ri_query_cache = hash_create(RI_INIT_QUERYHASHSIZE, &ctl, ri_query_cache = hash_create("RI query cache", RI_INIT_QUERYHASHSIZE,
HASH_ELEM | HASH_FUNCTION); &ctl, HASH_ELEM | HASH_FUNCTION);
ctl.keysize = sizeof(Oid); ctl.keysize = sizeof(Oid);
ctl.entrysize = sizeof(RI_OpreqHashEntry); ctl.entrysize = sizeof(RI_OpreqHashEntry);
ctl.hash = tag_hash; ctl.hash = tag_hash;
ri_opreq_cache = hash_create(RI_INIT_OPREQHASHSIZE, &ctl, ri_opreq_cache = hash_create("RI OpReq cache", RI_INIT_OPREQHASHSIZE,
HASH_ELEM | HASH_FUNCTION); &ctl, HASH_ELEM | HASH_FUNCTION);
} }
...@@ -3012,7 +3012,6 @@ static void * ...@@ -3012,7 +3012,6 @@ static void *
ri_FetchPreparedPlan(RI_QueryKey *key) ri_FetchPreparedPlan(RI_QueryKey *key)
{ {
RI_QueryHashEntry *entry; RI_QueryHashEntry *entry;
bool found;
/* /*
* On the first call initialize the hashtable * On the first call initialize the hashtable
...@@ -3025,10 +3024,8 @@ ri_FetchPreparedPlan(RI_QueryKey *key) ...@@ -3025,10 +3024,8 @@ ri_FetchPreparedPlan(RI_QueryKey *key)
*/ */
entry = (RI_QueryHashEntry *) hash_search(ri_query_cache, entry = (RI_QueryHashEntry *) hash_search(ri_query_cache,
(void *) key, (void *) key,
HASH_FIND, &found); HASH_FIND, NULL);
if (entry == NULL) if (entry == NULL)
elog(FATAL, "error in RI plan cache");
if (!found)
return NULL; return NULL;
return entry->plan; return entry->plan;
} }
...@@ -3059,7 +3056,7 @@ ri_HashPreparedPlan(RI_QueryKey *key, void *plan) ...@@ -3059,7 +3056,7 @@ ri_HashPreparedPlan(RI_QueryKey *key, void *plan)
(void *) key, (void *) key,
HASH_ENTER, &found); HASH_ENTER, &found);
if (entry == NULL) 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->plan = plan;
} }
...@@ -3235,16 +3232,14 @@ ri_AttributesEqual(Oid typeid, Datum oldvalue, Datum newvalue) ...@@ -3235,16 +3232,14 @@ ri_AttributesEqual(Oid typeid, Datum oldvalue, Datum newvalue)
*/ */
entry = (RI_OpreqHashEntry *) hash_search(ri_opreq_cache, entry = (RI_OpreqHashEntry *) hash_search(ri_opreq_cache,
(void *) &typeid, (void *) &typeid,
HASH_FIND, &found); HASH_FIND, NULL);
if (entry == NULL)
elog(FATAL, "error in RI operator cache");
/* /*
* If not found, lookup the OPERNAME system cache for it to get the * If not found, lookup the OPERNAME system cache for it to get the
* func OID, then do the function manager lookup, and remember that * func OID, then do the function manager lookup, and remember that
* info. * info.
*/ */
if (!found) if (!entry)
{ {
HeapTuple opr_tup; HeapTuple opr_tup;
Oid opr_proc; Oid opr_proc;
...@@ -3278,7 +3273,7 @@ ri_AttributesEqual(Oid typeid, Datum oldvalue, Datum newvalue) ...@@ -3278,7 +3273,7 @@ ri_AttributesEqual(Oid typeid, Datum oldvalue, Datum newvalue)
(void *) &typeid, (void *) &typeid,
HASH_ENTER, &found); HASH_ENTER, &found);
if (entry == NULL) if (entry == NULL)
elog(FATAL, "can't insert into RI operator cache"); elog(ERROR, "out of memory for RI operator cache");
entry->typeid = typeid; entry->typeid = typeid;
memcpy(&(entry->oprfmgrinfo), &finfo, sizeof(FmgrInfo)); memcpy(&(entry->oprfmgrinfo), &finfo, sizeof(FmgrInfo));
......
This diff is collapsed.
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * 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 $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -71,6 +71,7 @@ static bool dir_realloc(HTAB *hashp); ...@@ -71,6 +71,7 @@ static bool dir_realloc(HTAB *hashp);
static bool expand_table(HTAB *hashp); static bool expand_table(HTAB *hashp);
static bool hdefault(HTAB *hashp); static bool hdefault(HTAB *hashp);
static bool init_htab(HTAB *hashp, long nelem); static bool init_htab(HTAB *hashp, long nelem);
static void hash_corrupted(HTAB *hashp);
/* /*
...@@ -100,7 +101,7 @@ static long hash_accesses, ...@@ -100,7 +101,7 @@ static long hash_accesses,
/************************** CREATE ROUTINES **********************/ /************************** CREATE ROUTINES **********************/
HTAB * HTAB *
hash_create(long nelem, HASHCTL *info, int flags) hash_create(const char *tabname, long nelem, HASHCTL *info, int flags)
{ {
HTAB *hashp; HTAB *hashp;
HASHHDR *hctl; HASHHDR *hctl;
...@@ -125,6 +126,9 @@ hash_create(long nelem, HASHCTL *info, int flags) ...@@ -125,6 +126,9 @@ hash_create(long nelem, HASHCTL *info, int flags)
return NULL; return NULL;
MemSet(hashp, 0, sizeof(HTAB)); MemSet(hashp, 0, sizeof(HTAB));
hashp->tabname = (char *) MEM_ALLOC(strlen(tabname) + 1);
strcpy(hashp->tabname, tabname);
if (flags & HASH_FUNCTION) if (flags & HASH_FUNCTION)
hashp->hash = info->hash; hashp->hash = info->hash;
else else
...@@ -140,6 +144,7 @@ hash_create(long nelem, HASHCTL *info, int flags) ...@@ -140,6 +144,7 @@ hash_create(long nelem, HASHCTL *info, int flags)
hashp->dir = info->dir; hashp->dir = info->dir;
hashp->alloc = info->alloc; hashp->alloc = info->alloc;
hashp->hcxt = NULL; hashp->hcxt = NULL;
hashp->isshared = true;
/* hash table already exists, we're just attaching to it */ /* hash table already exists, we're just attaching to it */
if (flags & HASH_ATTACH) if (flags & HASH_ATTACH)
...@@ -152,6 +157,7 @@ hash_create(long nelem, HASHCTL *info, int flags) ...@@ -152,6 +157,7 @@ hash_create(long nelem, HASHCTL *info, int flags)
hashp->dir = NULL; hashp->dir = NULL;
hashp->alloc = MEM_ALLOC; hashp->alloc = MEM_ALLOC;
hashp->hcxt = DynaHashCxt; hashp->hcxt = DynaHashCxt;
hashp->isshared = false;
} }
if (!hashp->hctl) if (!hashp->hctl)
...@@ -434,12 +440,13 @@ hash_destroy(HTAB *hashp) ...@@ -434,12 +440,13 @@ hash_destroy(HTAB *hashp)
* by the caller of hash_create()). * by the caller of hash_create()).
*/ */
MEM_FREE(hashp->hctl); MEM_FREE(hashp->hctl);
MEM_FREE(hashp->tabname);
MEM_FREE(hashp); MEM_FREE(hashp);
} }
} }
void void
hash_stats(char *where, HTAB *hashp) hash_stats(const char *where, HTAB *hashp)
{ {
#if HASH_STATISTICS #if HASH_STATISTICS
...@@ -476,24 +483,37 @@ call_hash(HTAB *hashp, void *k) ...@@ -476,24 +483,37 @@ call_hash(HTAB *hashp, void *k)
return (uint32) bucket; return (uint32) bucket;
} }
/* /*----------
* hash_search -- look up key in table and perform action * 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 * The HASH_FIND_SAVE/HASH_REMOVE_SAVED interface is a hack to save one
* found/removed/entered if applicable, TRUE otherwise. * table lookup in a find/process/remove scenario. Note that no other
* foundPtr is TRUE if we found an element in the table * addition or removal in the table can safely happen in between.
* (FALSE if we entered one). *----------
*/ */
void * void *
hash_search(HTAB *hashp, hash_search(HTAB *hashp,
void *keyPtr, void *keyPtr,
HASHACTION action, /* HASH_FIND / HASH_ENTER / HASH_REMOVE HASHACTION action,
* HASH_FIND_SAVE / HASH_REMOVE_SAVED */
bool *foundPtr) bool *foundPtr)
{ {
HASHHDR *hctl; HASHHDR *hctl = hashp->hctl;
uint32 bucket; uint32 bucket;
long segment_num; long segment_num;
long segment_ndx; long segment_ndx;
...@@ -507,21 +527,14 @@ hash_search(HTAB *hashp, ...@@ -507,21 +527,14 @@ hash_search(HTAB *hashp,
HASHBUCKET *prevBucketPtr; HASHBUCKET *prevBucketPtr;
} saveState; } 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 #if HASH_STATISTICS
hash_accesses++; hash_accesses++;
hashp->hctl->accesses++; hctl->accesses++;
#endif #endif
/*
* Do the initial lookup (or recall result of prior lookup)
*/
if (action == HASH_REMOVE_SAVED) if (action == HASH_REMOVE_SAVED)
{ {
currBucket = saveState.currBucket; currBucket = saveState.currBucket;
...@@ -540,7 +553,8 @@ hash_search(HTAB *hashp, ...@@ -540,7 +553,8 @@ hash_search(HTAB *hashp,
segp = hashp->dir[segment_num]; segp = hashp->dir[segment_num];
Assert(segp); if (segp == NULL)
hash_corrupted(hashp);
prevBucketPtr = &segp[segment_ndx]; prevBucketPtr = &segp[segment_ndx];
currBucket = *prevBucketPtr; currBucket = *prevBucketPtr;
...@@ -556,23 +570,32 @@ hash_search(HTAB *hashp, ...@@ -556,23 +570,32 @@ hash_search(HTAB *hashp,
currBucket = *prevBucketPtr; currBucket = *prevBucketPtr;
#if HASH_STATISTICS #if HASH_STATISTICS
hash_collisions++; hash_collisions++;
hashp->hctl->collisions++; hctl->collisions++;
#endif #endif
} }
} }
/* if (foundPtr)
* if we found an entry or if we weren't trying to insert, we're done
* now.
*/
*foundPtr = (bool) (currBucket != NULL); *foundPtr = (bool) (currBucket != NULL);
/*
* OK, now what?
*/
switch (action) switch (action)
{ {
case HASH_ENTER: case HASH_FIND:
if (currBucket != NULL) if (currBucket != NULL)
return (void *) ELEMENTKEY(currBucket); 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:
case HASH_REMOVE_SAVED: case HASH_REMOVE_SAVED:
...@@ -595,63 +618,38 @@ hash_search(HTAB *hashp, ...@@ -595,63 +618,38 @@ hash_search(HTAB *hashp,
*/ */
return (void *) ELEMENTKEY(currBucket); return (void *) ELEMENTKEY(currBucket);
} }
return (void *) TRUE; return NULL;
case HASH_FIND:
if (currBucket != NULL)
return (void *) ELEMENTKEY(currBucket);
return (void *) TRUE;
case HASH_FIND_SAVE: case HASH_ENTER:
/* Return existing element if found, else create one */
if (currBucket != NULL) if (currBucket != NULL)
{
saveState.currBucket = currBucket;
saveState.prevBucketPtr = prevBucketPtr;
return (void *) ELEMENTKEY(currBucket); return (void *) ELEMENTKEY(currBucket);
}
return (void *) TRUE;
default: /* get the next free element */
/* 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; currBucket = hctl->freeList;
if (currBucket == NULL) if (currBucket == NULL)
{ {
/* no free elements. allocate another chunk of buckets */ /* no free elements. allocate another chunk of buckets */
if (!element_alloc(hashp)) if (!element_alloc(hashp))
return NULL; return NULL; /* out of memory */
currBucket = hctl->freeList; currBucket = hctl->freeList;
}
Assert(currBucket != NULL); Assert(currBucket != NULL);
}
hctl->freeList = currBucket->link; hctl->freeList = currBucket->link;
/* link into chain */ /* link into hashbucket chain */
*prevBucketPtr = currBucket; *prevBucketPtr = currBucket;
currBucket->link = NULL; currBucket->link = NULL;
/* copy key into record */ /* copy key into record */
memcpy(ELEMENTKEY(currBucket), keyPtr, hctl->keysize); memcpy(ELEMENTKEY(currBucket), keyPtr, hctl->keysize);
/* /* caller is expected to fill the data field on return */
* let the caller initialize the data field after hash_search returns.
*/
/* /* Check if it is time to split the segment */
* Check if it is time to split the segment
*/
if (++hctl->nentries / (hctl->max_bucket + 1) > hctl->ffactor) if (++hctl->nentries / (hctl->max_bucket + 1) > hctl->ffactor)
{ {
/* /*
* NOTE: failure to expand table is not a fatal error, it just * NOTE: failure to expand table is not a fatal error, it just
* means we have to run at higher fill factor than we wanted. * means we have to run at higher fill factor than we wanted.
...@@ -660,13 +658,17 @@ hash_search(HTAB *hashp, ...@@ -660,13 +658,17 @@ hash_search(HTAB *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 * hash_seq_init/_search
* Sequentially search through hash table and return * Sequentially search through hash table and return
* all the elements one by one, return NULL on error and * all the elements one by one, return NULL when no more.
* return (void *) TRUE in the end.
* *
* NOTE: caller may delete the returned element before continuing the scan. * NOTE: caller may delete the returned element before continuing the scan.
* However, deleting any other element while the scan is in progress is * However, deleting any other element while the scan is in progress is
...@@ -717,8 +719,7 @@ hash_seq_search(HASH_SEQ_STATUS *status) ...@@ -717,8 +719,7 @@ hash_seq_search(HASH_SEQ_STATUS *status)
*/ */
segp = hashp->dir[segment_num]; segp = hashp->dir[segment_num];
if (segp == NULL) if (segp == NULL)
/* this is probably an error */ hash_corrupted(hashp);
return NULL;
/* /*
* now find the right index into the segment for the first item in * now find the right index into the segment for the first item in
...@@ -734,7 +735,7 @@ hash_seq_search(HASH_SEQ_STATUS *status) ...@@ -734,7 +735,7 @@ hash_seq_search(HASH_SEQ_STATUS *status)
++status->curBucket; ++status->curBucket;
} }
return (void *) TRUE; /* out of buckets */ return NULL; /* out of buckets */
} }
...@@ -923,6 +924,20 @@ element_alloc(HTAB *hashp) ...@@ -923,6 +924,20 @@ element_alloc(HTAB *hashp)
return true; 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 */ /* calculate ceil(log base 2) of num */
int int
my_log2(long num) my_log2(long num)
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
#include "postgres.h" #include "postgres.h"
#include "lib/hasht.h" #include "utils/hsearch.h"
#include "utils/memutils.h" #include "utils/memutils.h"
#include "utils/portal.h" #include "utils/portal.h"
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
* ---------------- * ----------------
*/ */
#define MAX_PORTALNAME_LEN 64 /* XXX LONGALIGNable value */ #define MAX_PORTALNAME_LEN 64
typedef struct portalhashent typedef struct portalhashent
{ {
...@@ -54,15 +54,13 @@ static HTAB *PortalHashTable = NULL; ...@@ -54,15 +54,13 @@ static HTAB *PortalHashTable = NULL;
#define PortalHashTableLookup(NAME, PORTAL) \ #define PortalHashTableLookup(NAME, PORTAL) \
do { \ do { \
PortalHashEnt *hentry; bool found; char key[MAX_PORTALNAME_LEN]; \ PortalHashEnt *hentry; char key[MAX_PORTALNAME_LEN]; \
\ \
MemSet(key, 0, MAX_PORTALNAME_LEN); \ MemSet(key, 0, MAX_PORTALNAME_LEN); \
snprintf(key, MAX_PORTALNAME_LEN - 1, "%s", NAME); \ snprintf(key, MAX_PORTALNAME_LEN - 1, "%s", NAME); \
hentry = (PortalHashEnt*)hash_search(PortalHashTable, \ hentry = (PortalHashEnt*)hash_search(PortalHashTable, \
key, HASH_FIND, &found); \ key, HASH_FIND, NULL); \
if (hentry == NULL) \ if (hentry) \
elog(FATAL, "error in PortalHashTable"); \
if (found) \
PORTAL = hentry->portal; \ PORTAL = hentry->portal; \
else \ else \
PORTAL = NULL; \ PORTAL = NULL; \
...@@ -77,7 +75,7 @@ do { \ ...@@ -77,7 +75,7 @@ do { \
hentry = (PortalHashEnt*)hash_search(PortalHashTable, \ hentry = (PortalHashEnt*)hash_search(PortalHashTable, \
key, HASH_ENTER, &found); \ key, HASH_ENTER, &found); \
if (hentry == NULL) \ if (hentry == NULL) \
elog(FATAL, "error in PortalHashTable"); \ elog(ERROR, "out of memory in PortalHashTable"); \
if (found) \ if (found) \
elog(NOTICE, "trying to insert a portal name that exists."); \ elog(NOTICE, "trying to insert a portal name that exists."); \
hentry->portal = PORTAL; \ hentry->portal = PORTAL; \
...@@ -85,15 +83,13 @@ do { \ ...@@ -85,15 +83,13 @@ do { \
#define PortalHashTableDelete(PORTAL) \ #define PortalHashTableDelete(PORTAL) \
do { \ do { \
PortalHashEnt *hentry; bool found; char key[MAX_PORTALNAME_LEN]; \ PortalHashEnt *hentry; char key[MAX_PORTALNAME_LEN]; \
\ \
MemSet(key, 0, MAX_PORTALNAME_LEN); \ MemSet(key, 0, MAX_PORTALNAME_LEN); \
snprintf(key, MAX_PORTALNAME_LEN - 1, "%s", PORTAL->name); \ snprintf(key, MAX_PORTALNAME_LEN - 1, "%s", PORTAL->name); \
hentry = (PortalHashEnt*)hash_search(PortalHashTable, \ hentry = (PortalHashEnt*)hash_search(PortalHashTable, \
key, HASH_REMOVE, &found); \ key, HASH_REMOVE, NULL); \
if (hentry == NULL) \ if (hentry == NULL) \
elog(FATAL, "error in PortalHashTable"); \
if (!found) \
elog(NOTICE, "trying to delete portal name that does not exist."); \ elog(NOTICE, "trying to delete portal name that does not exist."); \
} while(0) } while(0)
...@@ -129,7 +125,8 @@ EnablePortalManager(void) ...@@ -129,7 +125,8 @@ EnablePortalManager(void)
* use PORTALS_PER_USER, defined in utils/portal.h as a guess of how * use PORTALS_PER_USER, defined in utils/portal.h as a guess of how
* many hash table entries to create, initially * 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);
} }
/* /*
...@@ -234,15 +231,10 @@ CreatePortal(char *name) ...@@ -234,15 +231,10 @@ CreatePortal(char *name)
* Exceptions: * Exceptions:
* BadState if called when disabled. * BadState if called when disabled.
* BadArg if portal is invalid. * 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 void
PortalDrop(Portal *portalP) PortalDrop(Portal portal)
{ {
Portal portal = *portalP;
AssertArg(PortalIsValid(portal)); AssertArg(PortalIsValid(portal));
/* remove portal from hash table */ /* remove portal from hash table */
...@@ -262,9 +254,23 @@ PortalDrop(Portal *portalP) ...@@ -262,9 +254,23 @@ PortalDrop(Portal *portalP)
/* /*
* Destroy all portals created in the current transaction (ie, all of them). * 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 void
AtEOXact_portals(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);
}
} }
/*-------------------------------------------------------------------------
*
* 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 */
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -66,9 +66,9 @@ extern void InitShmemAllocation(void *seghdr); ...@@ -66,9 +66,9 @@ extern void InitShmemAllocation(void *seghdr);
extern void *ShmemAlloc(Size size); extern void *ShmemAlloc(Size size);
extern bool ShmemIsValid(unsigned long addr); extern bool ShmemIsValid(unsigned long addr);
extern void InitShmemIndex(void); 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); 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 */ /* size constants for the shmem index table */
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
/* /*
* HASHELEMENT is the private part of a hashtable entry. The caller's data * 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 * 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 HASHELEMENT
{ {
...@@ -85,10 +85,12 @@ typedef struct HASHHDR ...@@ -85,10 +85,12 @@ typedef struct HASHHDR
typedef struct HTAB typedef struct HTAB
{ {
HASHHDR *hctl; /* shared control information */ HASHHDR *hctl; /* shared control information */
long (*hash) (void *key, int keysize); /* Hash Function */
HASHSEGMENT *dir; /* directory of segment starts */ HASHSEGMENT *dir; /* directory of segment starts */
long (*hash) (void *key, int keysize); /* Hash Function */
void *(*alloc) (Size);/* memory allocator */ void *(*alloc) (Size);/* memory allocator */
MemoryContext hcxt; /* memory context if default allocator used */ 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; } HTAB;
/* Parameter data structure for hash_create */ /* Parameter data structure for hash_create */
...@@ -147,9 +149,10 @@ typedef struct ...@@ -147,9 +149,10 @@ typedef struct
/* /*
* prototypes for functions in dynahash.c * 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_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, extern void *hash_search(HTAB *hashp, void *keyPtr, HASHACTION action,
bool *foundPtr); bool *foundPtr);
extern void hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp); extern void hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -61,7 +61,7 @@ typedef struct PortalData ...@@ -61,7 +61,7 @@ typedef struct PortalData
extern void EnablePortalManager(void); extern void EnablePortalManager(void);
extern void AtEOXact_portals(void); extern void AtEOXact_portals(void);
extern Portal CreatePortal(char *name); extern Portal CreatePortal(char *name);
extern void PortalDrop(Portal *portalP); extern void PortalDrop(Portal portal);
extern Portal GetPortalByName(char *name); extern Portal GetPortalByName(char *name);
extern void PortalSetQuery(Portal portal, QueryDesc *queryDesc, extern void PortalSetQuery(Portal portal, QueryDesc *queryDesc,
TupleDesc attinfo, EState *state, TupleDesc attinfo, EState *state,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment