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>
Mon, 13 Oct 2014 17:13:54 +0000 (13:13 -0400)
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 b37d0dd2c318f722628caef69c510b2ef99d9044..0b91ac10eefa02f875fc893a704bc481aa78aa1a 100644 (file)
@@ -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 (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));