提交 a21a54b2 编写于 作者: F fengkaiwen01 提交者: Jiangtao Hu

framework: rm function Remove

上级 e17ae6c7
......@@ -78,11 +78,6 @@ class AtomicHashMap {
table_[index].Insert(key, std::forward<V>(value));
}
bool Remove(K key) {
uint64_t index = key & mode_num_;
return table_[index].Remove(key);
}
private:
struct Entry {
Entry() {}
......@@ -97,18 +92,9 @@ class AtomicHashMap {
}
~Entry() { delete value_ptr.load(std::memory_order_acquire); }
void Release() {
if (ref_count.fetch_sub(1) == 1) {
delete value_ptr.load(std::memory_order_acquire);
delete this;
}
}
K key = 0;
std::atomic<V *> value_ptr = {nullptr};
std::atomic<Entry *> next = {nullptr};
// reference counter, avoid ABA problem
std::atomic<uint32_t> ref_count = {1};
};
class Bucket {
......@@ -123,24 +109,9 @@ class AtomicHashMap {
}
}
bool Marked(Entry *entry) { return reinterpret_cast<uintptr_t>(entry) & 1; }
Entry *Unmark(Entry *entry) {
return reinterpret_cast<Entry *>((reinterpret_cast<uintptr_t>(entry) >> 1)
<< 1);
}
Entry *Mark(Entry *entry) {
return reinterpret_cast<Entry *>(reinterpret_cast<uintptr_t>(entry) | 1);
}
bool Has(K key) {
Entry *m_target = head_->next.load(std::memory_order_acquire);
while (Entry *target = Unmark(m_target)) {
if (Marked(target->next.load(std::memory_order_acquire))) {
m_target = head_->next.load(std::memory_order_acquire);
continue;
}
while (Entry *target = m_target) {
if (target->key < key) {
m_target = target->next.load(std::memory_order_acquire);
continue;
......@@ -154,21 +125,12 @@ class AtomicHashMap {
bool Find(K key, Entry **prev_ptr, Entry **target_ptr) {
Entry *prev = head_;
Entry *m_target = head_->next.load(std::memory_order_acquire);
while (Entry *target = Unmark(m_target)) {
auto next = target->next.load(std::memory_order_acquire);
if (Marked(next) && Unmark(next)) {
prev = head_;
m_target = head_->next.load(std::memory_order_acquire);
continue;
}
while (Entry *target = m_target) {
if (target->key == key) {
target->ref_count++;
*prev_ptr = prev;
*target_ptr = target;
return true;
} else if (target->key > key) {
target->ref_count++;
*prev_ptr = prev;
*target_ptr = target;
return false;
......@@ -191,15 +153,11 @@ class AtomicHashMap {
if (Find(key, &prev, &target)) {
// key exists, update value
auto old_val_ptr = target->value_ptr.load(std::memory_order_acquire);
// value_ptr will be set to nullptr befor remove, so check first
while (old_val_ptr) {
if (target->value_ptr.compare_exchange_strong(
old_val_ptr, new_value, std::memory_order_acq_rel,
std::memory_order_relaxed)) {
target->Release();
delete new_entry;
return;
}
if (target->value_ptr.compare_exchange_strong(
old_val_ptr, new_value, std::memory_order_acq_rel,
std::memory_order_relaxed)) {
delete new_entry;
return;
}
continue;
} else {
......@@ -208,9 +166,6 @@ class AtomicHashMap {
std::memory_order_acq_rel,
std::memory_order_relaxed)) {
// Insert success
if (target) {
target->Release();
}
delete new_value;
return;
}
......@@ -228,15 +183,11 @@ class AtomicHashMap {
if (Find(key, &prev, &target)) {
// key exists, update value
auto old_val_ptr = target->value_ptr.load(std::memory_order_acquire);
// value_ptr will be set to nullptr befor remove, so check first
while (old_val_ptr) {
if (target->value_ptr.compare_exchange_strong(
old_val_ptr, new_value, std::memory_order_acq_rel,
std::memory_order_relaxed)) {
target->Release();
delete new_entry;
return;
}
if (target->value_ptr.compare_exchange_strong(
old_val_ptr, new_value, std::memory_order_acq_rel,
std::memory_order_relaxed)) {
delete new_entry;
return;
}
continue;
} else {
......@@ -245,9 +196,6 @@ class AtomicHashMap {
std::memory_order_acq_rel,
std::memory_order_relaxed)) {
// Insert success
if (target) {
target->Release();
}
delete new_value;
return;
}
......@@ -265,15 +213,11 @@ class AtomicHashMap {
if (Find(key, &prev, &target)) {
// key exists, update value
auto old_val_ptr = target->value_ptr.load(std::memory_order_acquire);
// value_ptr will be set to nullptr befor remove, so check first
while (old_val_ptr) {
if (target->value_ptr.compare_exchange_strong(
old_val_ptr, new_value, std::memory_order_acq_rel,
std::memory_order_relaxed)) {
target->Release();
delete new_entry;
return;
}
if (target->value_ptr.compare_exchange_strong(
old_val_ptr, new_value, std::memory_order_acq_rel,
std::memory_order_relaxed)) {
delete new_entry;
return;
}
continue;
} else {
......@@ -282,9 +226,6 @@ class AtomicHashMap {
std::memory_order_acq_rel,
std::memory_order_relaxed)) {
// Insert success
if (target) {
target->Release();
}
delete new_value;
return;
}
......@@ -293,46 +234,13 @@ class AtomicHashMap {
}
}
bool Remove(K key) {
Entry *prev = nullptr;
Entry *target = nullptr;
while (true) {
if (!Find(key, &prev, &target)) {
if (target) {
target->Release();
}
return false;
}
Entry *old_next = target->next.load(std::memory_order_acquire);
// mark befor remove
if (!target->next.compare_exchange_strong(old_next, Mark(old_next),
std::memory_order_acq_rel,
std::memory_order_relaxed)) {
target->Release();
continue;
}
target->value_ptr.store(nullptr, std::memory_order_release);
if (prev->next.compare_exchange_strong(
target, Unmark(target->next.load(std::memory_order_acquire)),
std::memory_order_acq_rel, std::memory_order_relaxed)) {
target->Release();
return true;
}
}
}
bool Get(K key, V **value) {
Entry *prev = nullptr;
Entry *target = nullptr;
if (Find(key, &prev, &target)) {
*value = target->value_ptr.load(std::memory_order_acquire);
target->Release();
return true;
}
if (target) {
target->Release();
}
return false;
}
......
......@@ -31,10 +31,6 @@ TEST(AtomicHashMapTest, int_int) {
EXPECT_TRUE(map.Has(i));
EXPECT_TRUE(map.Get(i, &value));
EXPECT_EQ(i, value);
EXPECT_TRUE(map.Remove(i));
EXPECT_FALSE(map.Has(i));
EXPECT_FALSE(map.Get(i, &value));
EXPECT_FALSE(map.Remove(i));
}
for (int i = 0; i < 1000; i++) {
......@@ -42,10 +38,6 @@ TEST(AtomicHashMapTest, int_int) {
EXPECT_TRUE(map.Has(1000 - i));
EXPECT_TRUE(map.Get(1000 - i, &value));
EXPECT_EQ(i, value);
EXPECT_TRUE(map.Remove(1000 - i));
EXPECT_FALSE(map.Has(1000 - i));
EXPECT_FALSE(map.Get(1000 - i, &value));
EXPECT_FALSE(map.Remove(1000 - i));
}
}
......@@ -57,10 +49,6 @@ TEST(AtomicHashMapTest, int_str) {
EXPECT_TRUE(map.Has(i));
EXPECT_TRUE(map.Get(i, &value));
EXPECT_EQ(std::to_string(i), value);
EXPECT_TRUE(map.Remove(i));
EXPECT_FALSE(map.Has(i));
EXPECT_FALSE(map.Get(i, &value));
EXPECT_FALSE(map.Remove(i));
}
map.Set(100);
EXPECT_TRUE(map.Get(100, &value));
......@@ -71,7 +59,7 @@ TEST(AtomicHashMapTest, int_str) {
}
TEST(AtomicHashMapTest, concurrency) {
AtomicHashMap<int, std::string, 1024> map;
AtomicHashMap<int, std::string, 128> map;
int thread_num = 32;
std::thread t[32];
volatile bool ready = false;
......@@ -83,7 +71,6 @@ TEST(AtomicHashMapTest, concurrency) {
}
for (int j = 0; j < thread_num * 1024; j++) {
auto j_str = std::to_string(j);
map.Remove(j);
map.Set(j);
map.Set(j, j_str);
map.Set(j, std::move(std::to_string(j)));
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册