Testing code and resulting bug fixes.
authorRobert Haas <rhaas@postgresql.org>
Wed, 25 Jul 2012 04:21:37 +0000 (00:21 -0400)
committerRobert Haas <rhaas@postgresql.org>
Tue, 27 Jan 2015 02:24:21 +0000 (02:24 +0000)
contrib/Makefile
contrib/hashtest/Makefile [new file with mode: 0644]
contrib/hashtest/hashtest--1.0.sql [new file with mode: 0644]
contrib/hashtest/hashtest.c [new file with mode: 0644]
contrib/hashtest/hashtest.control [new file with mode: 0644]
src/backend/utils/hash/chash.c

index 195d4472c573ae233b271c4df7e8a7922b925f2e..141ef0afb0d8ac82d3fd5d49568bb9922fa17559 100644 (file)
@@ -19,6 +19,7 @@ SUBDIRS = \
                earthdistance   \
                file_fdw        \
                fuzzystrmatch   \
+               hashtest        \
                hstore          \
                intagg          \
                intarray        \
diff --git a/contrib/hashtest/Makefile b/contrib/hashtest/Makefile
new file mode 100644 (file)
index 0000000..3ee42f8
--- /dev/null
@@ -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 (file)
index 0000000..4043dc1
--- /dev/null
@@ -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 (file)
index 0000000..45aa75a
--- /dev/null
@@ -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 (file)
index 0000000..b8e0f01
--- /dev/null
@@ -0,0 +1,4 @@
+comment = 'hash testing code'
+default_version = '1.0'
+module_pathname = '$libdir/hashtest'
+relocatable = true
index 8caf516f9b9d67ebc6109dac2e2ef0967a62a769..ab8c759978eabae304547ae488b3163198a43020 100644 (file)
@@ -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));