Implement concurrent and collision tests for dynahash.
authorRobert Haas <[email protected]>
Wed, 1 Aug 2012 17:06:51 +0000 (17:06 +0000)
committerRobert Haas <[email protected]>
Wed, 1 Aug 2012 17:06:51 +0000 (17:06 +0000)
contrib/hashtest/hashtest--1.0.sql
contrib/hashtest/hashtest.c

index e1dddfcf9bff7bd4a45ab484b0ab24adb88a6f5a..c787532e739e0ee30771a864386ee173948e4d69 100644 (file)
@@ -45,3 +45,13 @@ CREATE FUNCTION dynahash_delete_test()
 RETURNS void
 AS 'MODULE_PATHNAME', 'dynahash_delete_test'
 LANGUAGE C;
+
+CREATE FUNCTION dynahash_concurrent_test()
+RETURNS void
+AS 'MODULE_PATHNAME', 'dynahash_concurrent_test'
+LANGUAGE C;
+
+CREATE FUNCTION dynahash_collision_test()
+RETURNS void
+AS 'MODULE_PATHNAME', 'dynahash_collision_test'
+LANGUAGE C;
index 25c6c3517c7aebbefc508d15d9a17a393e5b6f04..e1d8205398241e3bf8651aa9393f59190c230126 100644 (file)
@@ -23,6 +23,8 @@ Datum         chash_write_stats_to_log(PG_FUNCTION_ARGS);
 Datum          dynahash_insert_test(PG_FUNCTION_ARGS);
 Datum          dynahash_search_test(PG_FUNCTION_ARGS);
 Datum          dynahash_delete_test(PG_FUNCTION_ARGS);
+Datum          dynahash_concurrent_test(PG_FUNCTION_ARGS);
+Datum          dynahash_collision_test(PG_FUNCTION_ARGS);
 static void hashtest_shmem_startup(void);
 
 PG_FUNCTION_INFO_V1(chash_insert_test);
@@ -33,6 +35,8 @@ PG_FUNCTION_INFO_V1(chash_collision_test);
 PG_FUNCTION_INFO_V1(dynahash_insert_test);
 PG_FUNCTION_INFO_V1(dynahash_search_test);
 PG_FUNCTION_INFO_V1(dynahash_delete_test);
+PG_FUNCTION_INFO_V1(dynahash_concurrent_test);
+PG_FUNCTION_INFO_V1(dynahash_collision_test);
 
 typedef struct
 {
@@ -260,7 +264,7 @@ chash_collision_test(PG_FUNCTION_ARGS)
                ok = CHashSearch(chash, &e);
                if (!ok)
                        elog(LOG, "search %u: not found", i);
-               if (e.val != MyProcPid)
+               else if (e.val != MyProcPid)
                        elog(LOG, "search %u: expected %u found %u",
                                 i, (unsigned) MyProcPid, e.val);
                ok = CHashDelete(chash, &e);
@@ -440,3 +444,82 @@ dynahash_delete_test(PG_FUNCTION_ARGS)
 
        PG_RETURN_VOID();
 }
+
+Datum
+dynahash_concurrent_test(PG_FUNCTION_ARGS)
+{
+       uint32  i;
+       uint32  val;
+       uint32  seed = MyProcPid << 16;
+
+       for (i = 0; i < 10000; ++i)
+       {
+               bool ok;
+
+               ok = dynahash_insert(seed | i, MyProcPid);
+               if (!ok)
+                       elog(LOG, "insert %u: found", i);
+       }
+
+       for (i = 0; i < 10000; ++i)
+       {
+               bool ok;
+
+               ok = dynahash_search(seed | i, &val);
+               if (!ok)
+                       elog(LOG, "search %u: not found", i);
+               else if (val != MyProcPid)
+                       elog(LOG, "search %u: expected %u found %u", i, (unsigned) MyProcPid, val);
+       }
+
+       for (i = 0; i < 10000; ++i)
+       {
+               bool ok;
+
+               ok = dynahash_delete(seed | i);
+               if (!ok)
+                       elog(LOG, "delete %u: not found", i);
+       }
+
+       PG_RETURN_VOID();
+}
+
+Datum
+dynahash_collision_test(PG_FUNCTION_ARGS)
+{
+       uint32  i;
+       uint32  val;
+
+       /* Don't stack-allocate this. */
+       static bool mine[10000];
+
+       memset(mine, 0, 10000 * sizeof(bool));
+
+       for (i = 0; i < 10000; ++i)
+       {
+               bool ok;
+
+               ok = dynahash_insert(i, MyProcPid);
+               if (ok)
+                       mine[i] = true;
+       }
+
+       for (i = 0; i < 10000; ++i)
+       {
+               bool ok;
+
+               if (!mine[i])
+                       continue;
+               ok = dynahash_search(i, &val);
+               if (!ok)
+                       elog(LOG, "search %u: not found", i);
+               else if (val != MyProcPid)
+                       elog(LOG, "search %u: expected %u found %u",
+                                i, (unsigned) MyProcPid, val);
+               ok = dynahash_delete(i);
+               if (!ok)
+                       elog(LOG, "delete %u: not found", i);
+       }
+
+       PG_RETURN_VOID();
+}