Skip to content
Permalink
Browse files
8266637: CHT: Add insert_and_get method
Reviewed-by: tschatzl, rehn
  • Loading branch information
Ivan Walulya committed May 17, 2021
1 parent 7b736ec commit 2313a2187a949dd0c101b8f8fb5ffc31089d6817
@@ -308,10 +308,10 @@ class ConcurrentHashTable : public CHeapObj<F> {
VALUE* internal_get(Thread* thread, LOOKUP_FUNC& lookup_f,
bool* grow_hint = NULL);

// Plain insert.
template <typename LOOKUP_FUNC>
bool internal_insert(Thread* thread, LOOKUP_FUNC& lookup_f, const VALUE& value,
bool* grow_hint, bool* clean_hint);
// Insert and get current value.
template <typename LOOKUP_FUNC, typename FOUND_FUNC>
bool internal_insert_get(Thread* thread, LOOKUP_FUNC& lookup_f, const VALUE& value,
FOUND_FUNC& foundf, bool* grow_hint, bool* clean_hint);

// Returns true if an item matching LOOKUP_FUNC is removed.
// Calls DELETE_FUNC before destroying the node.
@@ -410,7 +410,18 @@ class ConcurrentHashTable : public CHeapObj<F> {
template <typename LOOKUP_FUNC>
bool insert(Thread* thread, LOOKUP_FUNC& lookup_f, const VALUE& value,
bool* grow_hint = NULL, bool* clean_hint = NULL) {
return internal_insert(thread, lookup_f, value, grow_hint, clean_hint);
struct NOP {
void operator()(...) const {}
} nop;
return internal_insert_get(thread, lookup_f, value, nop, grow_hint, clean_hint);
}

// Returns true if the item was inserted, duplicates are found with
// LOOKUP_FUNC then FOUND_FUNC is called.
template <typename LOOKUP_FUNC, typename FOUND_FUNC>
bool insert_get(Thread* thread, LOOKUP_FUNC& lookup_f, VALUE& value, FOUND_FUNC& foundf,
bool* grow_hint = NULL, bool* clean_hint = NULL) {
return internal_insert_get(thread, lookup_f, value, foundf, grow_hint, clean_hint);
}

// This does a fast unsafe insert and can thus only be used when there is no
@@ -880,10 +880,10 @@ inline typename CONFIG::Value* ConcurrentHashTable<CONFIG, F>::
}

template <typename CONFIG, MEMFLAGS F>
template <typename LOOKUP_FUNC>
template <typename LOOKUP_FUNC, typename FOUND_FUNC>
inline bool ConcurrentHashTable<CONFIG, F>::
internal_insert(Thread* thread, LOOKUP_FUNC& lookup_f, const VALUE& value,
bool* grow_hint, bool* clean_hint)
internal_insert_get(Thread* thread, LOOKUP_FUNC& lookup_f, const VALUE& value,
FOUND_FUNC& foundf, bool* grow_hint, bool* clean_hint)
{
bool ret = false;
bool clean = false;
@@ -902,6 +902,7 @@ inline bool ConcurrentHashTable<CONFIG, F>::
if (old == NULL) {
new_node->set_next(first_at_start);
if (bucket->cas_first(new_node, first_at_start)) {
foundf(new_node->value());
JFR_ONLY(_stats_rate.add();)
new_node = NULL;
ret = true;
@@ -911,6 +912,7 @@ inline bool ConcurrentHashTable<CONFIG, F>::
locked = bucket->is_locked();
} else {
// There is a duplicate.
foundf(old->value());
break; /* leave critical section */
}
} /* leave critical section */
@@ -147,6 +147,19 @@ static void cht_insert(Thread* thr) {
delete cht;
}

static void cht_insert_get(Thread* thr) {
uintptr_t val = 0x2;
SimpleTestLookup stl(val);
SimpleTestTable* cht = new SimpleTestTable();
ValueGet vg;
EXPECT_TRUE(cht->insert_get(thr, stl, val, vg)) << "Insert unique value failed.";
EXPECT_EQ(val, vg.get_value()) << "Getting an inserted value failed.";
ValueGet vg_dup;
EXPECT_FALSE(cht->insert_get(thr, stl, val, vg_dup)) << "Insert duplicate value succeeded.";
EXPECT_EQ(val, vg_dup.get_value()) << "Getting an existing value failed.";
delete cht;
}

static void cht_get_insert(Thread* thr) {
uintptr_t val = 0x2;
SimpleTestLookup stl(val);
@@ -449,6 +462,10 @@ TEST_VM(ConcurrentHashTable, basic_get_insert) {
nomt_test_doer(cht_get_insert);
}

TEST_VM(ConcurrentHashTable, basic_insert_get) {
nomt_test_doer(cht_insert_get);
}

TEST_VM(ConcurrentHashTable, basic_scope) {
nomt_test_doer(cht_scope);
}

0 comments on commit 2313a21

Please sign in to comment.