Test code for deletes, and associated bug fixes.
authorRobert Haas <[email protected]>
Fri, 27 Jul 2012 04:22:47 +0000 (00:22 -0400)
committerRobert Haas <[email protected]>
Fri, 27 Jul 2012 04:22:47 +0000 (00:22 -0400)
contrib/hashtest/hashtest.c
src/backend/utils/hash/chash.c

index d9e5771d8b6b069a45949f81a65332bf7647325b..7b29a8e3bcc4c9cc546a53d42fd121246491dc0c 100644 (file)
@@ -99,7 +99,8 @@ test_chash(PG_FUNCTION_ARGS)
        hentry  e;
        instr_time t0,
                           t1,
-                          t2;
+                          t2,
+                          t3;
 
        INSTR_TIME_SET_CURRENT(t0);
 
@@ -132,12 +133,29 @@ test_chash(PG_FUNCTION_ARGS)
        }
 
        INSTR_TIME_SET_CURRENT(t2);
+
+       for (i = 0; i < 1000000; ++i)
+       {
+               bool ok;
+
+               e.key = i;
+               ok = CHashDelete(chash, &e);
+               if (!ok)
+                       elog(LOG, "delete %u: not found", i);
+               ok = CHashDelete(chash, &e);
+               if (ok)
+                       elog(LOG, "delete %u: found twice", i);
+       }
+
+       INSTR_TIME_SET_CURRENT(t3);
+       INSTR_TIME_SUBTRACT(t3, t2);
        INSTR_TIME_SUBTRACT(t2, t1);
        INSTR_TIME_SUBTRACT(t1, t0);
 
-       elog(LOG, "inserts: %lu us; searches: %lu us",
+       elog(LOG, "inserts: %lu us; searches: %lu us; deletes: %lu us",
                (unsigned long) INSTR_TIME_GET_MICROSEC(t1),
-               (unsigned long) INSTR_TIME_GET_MICROSEC(t2));
+               (unsigned long) INSTR_TIME_GET_MICROSEC(t2),
+               (unsigned long) INSTR_TIME_GET_MICROSEC(t3));
 
        PG_RETURN_VOID();
 }
@@ -181,13 +199,31 @@ dynahash_search(uint32 key, uint32 *val)
        return e != NULL;
 }
 
+static bool
+dynahash_delete(uint32 key)
+{
+       uint32  hashcode;
+       hentry *e;
+       LWLockId        lockid;
+
+       hashcode = get_hash_value(dynahash, (void *) &key);
+       lockid = dynahash_get_lock(hashcode);
+       LWLockAcquire(lockid, LW_SHARED);
+       e = hash_search_with_hash_value(dynahash, (void *) &key,
+                                                                       hashcode, HASH_REMOVE, NULL);
+       LWLockRelease(lockid);
+
+       return e != NULL;
+}
+
 Datum
 test_dynahash(PG_FUNCTION_ARGS)
 {
        uint32  i;
        instr_time t0,
                           t1,
-                          t2;
+                          t2,
+                          t3;
 
        INSTR_TIME_SET_CURRENT(t0);
 
@@ -218,12 +254,28 @@ test_dynahash(PG_FUNCTION_ARGS)
        }
 
        INSTR_TIME_SET_CURRENT(t2);
+
+       for (i = 0; i < 1000000; ++i)
+       {
+               bool    ok;
+
+               ok = dynahash_delete(i);
+               if (!ok)
+                       elog(LOG, "delete %u: not found", i);
+               ok = dynahash_delete(i);
+               if (ok)
+                       elog(LOG, "delete %u: found twice", i);
+       }
+
+       INSTR_TIME_SET_CURRENT(t3);
+       INSTR_TIME_SUBTRACT(t3, t2);
        INSTR_TIME_SUBTRACT(t2, t1);
        INSTR_TIME_SUBTRACT(t1, t0);
 
-       elog(LOG, "inserts: %lu us; searches: %lu us",
+       elog(LOG, "inserts: %lu us; searches: %lu us; deletes: %lu us",
                (unsigned long) INSTR_TIME_GET_MICROSEC(t1),
-               (unsigned long) INSTR_TIME_GET_MICROSEC(t2));
+               (unsigned long) INSTR_TIME_GET_MICROSEC(t2),
+               (unsigned long) INSTR_TIME_GET_MICROSEC(t3));
 
        PG_RETURN_VOID();
 }
index d9067a589225ee62cf6b7ac8857bbc3a522d7dd1..c7b970dab4a64e85a6861a380651c4fedf7ca07d 100644 (file)
@@ -513,7 +513,7 @@ CHashDelete(CHashTable table, void *entry)
                        /* Someone else deleted it before we did. */
                        scan.found = false;
                }
-               else if (__sync_bool_compare_and_swap(&scan.target_node,
+               else if (__sync_bool_compare_and_swap(&scan.target_node->next,
                                                                                          next,
                                                                                          CHashPtrMark(next)))
                {
@@ -825,7 +825,7 @@ CHashAllocate(CHashTable table)
                                {
                                        oldhead = *b;
                                        n->un.gcnext = oldhead;
-                               } while (__sync_bool_compare_and_swap(b, oldhead, fhead));
+                               } while (!__sync_bool_compare_and_swap(b, oldhead, fhead));
                        }
 
                        /* Return the element we saved for ourselves. */