@@ -73,6 +73,7 @@ class SimpleHashMap {
7373 bool upsert (const K& key, const V& value);
7474 bool get (const K& input_key, V& out_val);
7575 bool erase (const K& key, V& out_val);
76+ bool try_erase (const K& key);
7677 bool update (const K& key, auto && update_cb);
7778 bool upsert_or_delete (const K& key, auto && update_or_delete_cb);
7879
@@ -102,6 +103,7 @@ class SimpleHashMap {
102103template < typename V >
103104struct SingleEntryHashNode : public ValueEntryBase , public boost ::intrusive::slist_base_hook<> {
104105 V m_value;
106+ bool evicted{false };
105107 SingleEntryHashNode (const V& value) : m_value{value} {}
106108};
107109
@@ -184,27 +186,21 @@ class SimpleHashBucket {
184186#ifndef GLOBAL_HASHSET_LOCK
185187 folly::SharedMutexWritePriority::WriteHolder holder (m_lock);
186188#endif
187- SingleEntryHashNode< V >* n = nullptr ;
188-
189- auto it = m_list.begin ();
190- for (auto itend{m_list.end ()}; it != itend; ++it) {
191- const K k = SimpleHashMap< K, V >::extractor_cb ()(it->m_value );
192- if (input_key > k) {
193- break ;
194- } else if (input_key == k) {
195- n = &*it;
196- break ;
197- }
198- }
189+ return erase_unsafe (input_key, out_val, true /* call_access_cb */ );
190+ }
199191
200- if (n) {
201- access_cb (*n, input_key, hash_op_t ::DELETE);
202- out_val = n->m_value ;
203- m_list.erase (it);
204- delete n;
205- return true ;
192+ bool try_erase (const K& input_key) {
193+ V dummy_val;
194+ #ifndef GLOBAL_HASHSET_LOCK
195+ if (m_lock.try_lock ()) {
196+ bool ret = erase_unsafe (input_key, dummy_val, false /* call_access_cb */ );
197+ m_lock.unlock ();
198+ return ret;
199+ } else {
200+ return false ;
206201 }
207- return false ;
202+ #endif
203+ return erase_unsafe (input_key, dummy_val, false );
208204 }
209205
210206 bool upsert_or_delete (const K& input_key, auto && update_or_delete_cb) {
@@ -266,9 +262,33 @@ class SimpleHashBucket {
266262 static void access_cb (const SingleEntryHashNode< V >& node, const K& key, hash_op_t op) {
267263 SimpleHashMap< K, V >::call_access_cb ((const ValueEntryBase&)node, key, op);
268264 }
265+
266+ bool erase_unsafe (const K& input_key, V& out_val, bool call_access_cb) {
267+ SingleEntryHashNode< V >* n = nullptr ;
268+
269+ auto it = m_list.begin ();
270+ for (auto itend{m_list.end ()}; it != itend; ++it) {
271+ const K k = SimpleHashMap< K, V >::extractor_cb ()(it->m_value );
272+ if (input_key > k) {
273+ break ;
274+ } else if (input_key == k) {
275+ n = &*it;
276+ break ;
277+ }
278+ }
279+
280+ if (n) {
281+ if (call_access_cb) { access_cb (*n, input_key, hash_op_t ::DELETE); }
282+ out_val = n->m_value ;
283+ m_list.erase (it);
284+ delete n;
285+ return true ;
286+ }
287+ return false ;
288+ }
269289};
270290
271- // /////////////////////////////////////////// RangeHashMap Definitions ///////////////////////////////////
291+ // /////////////////////////////////////////// SimpleHashMap Definitions ///////////////////////////////////
272292template < typename K, typename V >
273293SimpleHashMap< K, V >::SimpleHashMap(uint32_t nBuckets, const key_extractor_cb_t < K, V >& extract_cb,
274294 key_access_cb_t < K > access_cb) :
@@ -317,6 +337,12 @@ bool SimpleHashMap< K, V >::erase(const K& key, V& out_val) {
317337 return get_bucket (key).erase (key, out_val);
318338}
319339
340+ template < typename K, typename V >
341+ bool SimpleHashMap< K, V >::try_erase(const K& key) {
342+ set_current_instance (this );
343+ return get_bucket (key).try_erase (key);
344+ }
345+
320346// / This is a special atomic operation where user can insert_or_update_or_erase based on condition atomically. It
321347// / performs differently based on certain conditions.
322348// /
0 commit comments