From: Robert Haas Date: Wed, 25 Jul 2012 04:21:37 +0000 (-0400) Subject: Testing code and resulting bug fixes. X-Git-Url: http://waps.l3s.uni-hannover.de/gitweb/?a=commitdiff_plain;h=86fda24bfeb474524d547de423bfdb0527c1ae92;p=users%2Frhaas%2Fpostgres.git Testing code and resulting bug fixes. --- diff --git a/contrib/Makefile b/contrib/Makefile index d230451a12..1d53a2e257 100644 --- a/contrib/Makefile +++ b/contrib/Makefile @@ -20,6 +20,7 @@ SUBDIRS = \ earthdistance \ file_fdw \ fuzzystrmatch \ + hashtest \ hstore \ intagg \ intarray \ diff --git a/contrib/hashtest/Makefile b/contrib/hashtest/Makefile new file mode 100644 index 0000000000..3ee42f87d8 --- /dev/null +++ b/contrib/hashtest/Makefile @@ -0,0 +1,18 @@ +# contrib/hashtest/Makefile + +MODULE_big = hashtest +OBJS = hashtest.o + +EXTENSION = hashtest +DATA = hashtest--1.0.sql + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = contrib/hashtest +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/contrib/hashtest/hashtest--1.0.sql b/contrib/hashtest/hashtest--1.0.sql new file mode 100644 index 0000000000..4043dc1f5c --- /dev/null +++ b/contrib/hashtest/hashtest--1.0.sql @@ -0,0 +1,12 @@ +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION hashtest" to load this file. \quit + +CREATE FUNCTION test_dynahash() +RETURNS void +AS 'MODULE_PATHNAME', 'test_dynahash' +LANGUAGE C; + +CREATE FUNCTION test_chash() +RETURNS void +AS 'MODULE_PATHNAME', 'test_chash' +LANGUAGE C; diff --git a/contrib/hashtest/hashtest.c b/contrib/hashtest/hashtest.c new file mode 100644 index 0000000000..45aa75a2b7 --- /dev/null +++ b/contrib/hashtest/hashtest.c @@ -0,0 +1,81 @@ +/*------------------------------------------------------------------------- + * hashtest.c + *------------------------------------------------------------------------- + */ + +#include "postgres.h" + +#include "funcapi.h" +#include "miscadmin.h" +#include "storage/ipc.h" +#include "utils/chash.h" + +PG_MODULE_MAGIC; + +void _PG_init(void); +Datum test_dynahash(PG_FUNCTION_ARGS); +Datum test_chash(PG_FUNCTION_ARGS); +static void hashtest_shmem_startup(void); + +PG_FUNCTION_INFO_V1(test_dynahash); +PG_FUNCTION_INFO_V1(test_chash); + +typedef struct +{ + uint32 key; + uint32 val; +} hentry; + +static CHashDescriptor cdesc = { + "hashtest-chash", /* name */ + 0xd3c8eae3, /* id */ + 1048576, /* capacity */ + sizeof(hentry), /* element size */ + sizeof(uint32) /* key size */ +}; + +static shmem_startup_hook_type prev_shmem_startup_hook = NULL; +static CHashTable chash; + +void +_PG_init(void) +{ + if (!process_shared_preload_libraries_in_progress) + return; + prev_shmem_startup_hook = shmem_startup_hook; + shmem_startup_hook = hashtest_shmem_startup; + chash = CHashBootstrap(&cdesc); + RequestAddinShmemSpace(CHashEstimateSize(chash)); + RequestAddinShmemSpace(hash_estimate_size(cdesc.capacity, + cdesc.element_size)); +} + +static void +hashtest_shmem_startup(void) +{ + if (prev_shmem_startup_hook) + prev_shmem_startup_hook(); + chash = CHashInitialize(chash, &cdesc); +} + +Datum +test_dynahash(PG_FUNCTION_ARGS) +{ + PG_RETURN_VOID(); +} + +Datum +test_chash(PG_FUNCTION_ARGS) +{ + hentry e; + bool found; + + e.key = 1; + found = CHashSearch(chash, &e); + if (found) + elog(LOG, "found"); + else + elog(LOG, "not found"); + + PG_RETURN_VOID(); +} diff --git a/contrib/hashtest/hashtest.control b/contrib/hashtest/hashtest.control new file mode 100644 index 0000000000..b8e0f01346 --- /dev/null +++ b/contrib/hashtest/hashtest.control @@ -0,0 +1,4 @@ +comment = 'hash testing code' +default_version = '1.0' +module_pathname = '$libdir/hashtest' +relocatable = true diff --git a/src/backend/utils/hash/chash.c b/src/backend/utils/hash/chash.c index 8caf516f9b..ab8c759978 100644 --- a/src/backend/utils/hash/chash.c +++ b/src/backend/utils/hash/chash.c @@ -325,17 +325,17 @@ CHashInitialize(CHashTable table, CHashDescriptor *desc) for (i = 0; i < table->nbuckets; ++i) { table->bucket[i].head = InvalidCHashPtr; - SpinLockInit(&table->bucket[i].head); + SpinLockInit(&table->bucket[i].mutex); } for (i = 0; i < table->ngarbage; ++i) { table->garbage[i].head = InvalidCHashPtr; - SpinLockInit(&table->garbage[i].head); + SpinLockInit(&table->garbage[i].mutex); } for (i = 0; i < table->nfreelists; ++i) { table->freelist[i].head = InvalidCHashPtr; - SpinLockInit(&table->freelist[i].head); + SpinLockInit(&table->freelist[i].mutex); } /* Put all arena elements on the free lists. */ @@ -377,6 +377,7 @@ CHashSearch(CHashTable table, void *entry) CHashTableSuppressGC(table, bucket); /* Scan bucket. */ + elog(LOG, "table=%p table->bucket=%p", table, table->bucket); c = table->bucket[bucket].head; for (;;) { @@ -385,6 +386,8 @@ CHashSearch(CHashTable table, void *entry) /* If we've reached the end of the bucket chain, stop. */ if (c == InvalidCHashPtr) break; + elog(LOG, "table->nbuckets=%d table->bucket_mask=%d bucket=%d c=%d", + (int) table->nbuckets, table->bucket_mask, (int) bucket, (int) c); /* Compare current node by hashcode, then by memcmp. */ n = CHashTableGetNode(table, CHashPtrGetOffset(c));