Make sure the op does not change the sign of the operand
[folly.git] / folly / AtomicHashArray.h
index 640605e49906265a7cf1d7ad82c9c0ededca38d6..69e80dfb2431c5d594a1f7f8a466de701bb07378 100644 (file)
@@ -150,7 +150,11 @@ class AtomicHashArray : boost::noncopyable {
    *   iterator is set to the existing entry.
    */
   std::pair<iterator,bool> insert(const value_type& r) {
-    SimpleRetT ret = insertInternal(r);
+    SimpleRetT ret = insertInternal(r.first, r.second);
+    return std::make_pair(iterator(this, ret.idx), ret.success);
+  }
+  std::pair<iterator,bool> insert(value_type&& r) {
+    SimpleRetT ret = insertInternal(r.first, std::move(r.second));
     return std::make_pair(iterator(this, ret.idx), ret.success);
   }
 
@@ -213,7 +217,8 @@ class AtomicHashArray : boost::noncopyable {
     SimpleRetT() {}
   };
 
-  SimpleRetT insertInternal(const value_type& record);
+  template <class T>
+  SimpleRetT insertInternal(KeyT key, T&& value);
 
   SimpleRetT findInternal(const KeyT key);
 
@@ -232,6 +237,10 @@ class AtomicHashArray : boost::noncopyable {
     return cellKeyPtr(r)->load(std::memory_order_relaxed);
   }
 
+  static KeyT acquireLoadKey(const value_type& r) {
+    return cellKeyPtr(r)->load(std::memory_order_acquire);
+  }
+
   // Fun with thread local storage - atomic increment is expensive
   // (relatively), so we accumulate in the thread cache and periodically
   // flush to the actual variable, and walk through the unflushed counts when
@@ -259,7 +268,7 @@ class AtomicHashArray : boost::noncopyable {
   inline bool tryLockCell(value_type* const cell) {
     KeyT expect = kEmptyKey_;
     return cellKeyPtr(*cell)->compare_exchange_strong(expect, kLockedKey_,
-      std::memory_order_acquire);
+      std::memory_order_acq_rel);
   }
 
   inline size_t keyToAnchorIdx(const KeyT k) const {