From 4b5198d6a1ee5244d5895753a1ea56fc27d28a90 Mon Sep 17 00:00:00 2001 From: Robert Haas Date: Fri, 27 Jul 2012 00:22:47 -0400 Subject: [PATCH] Test code for deletes, and associated bug fixes. --- contrib/hashtest/hashtest.c | 64 ++++++++++++++++++++++++++++++---- src/backend/utils/hash/chash.c | 4 +-- 2 files changed, 60 insertions(+), 8 deletions(-) diff --git a/contrib/hashtest/hashtest.c b/contrib/hashtest/hashtest.c index d9e5771d8b..7b29a8e3bc 100644 --- a/contrib/hashtest/hashtest.c +++ b/contrib/hashtest/hashtest.c @@ -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(); } diff --git a/src/backend/utils/hash/chash.c b/src/backend/utils/hash/chash.c index d9067a5892..c7b970dab4 100644 --- a/src/backend/utils/hash/chash.c +++ b/src/backend/utils/hash/chash.c @@ -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. */ -- 2.39.5