@@ -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
@@ -184,27 +185,21 @@ class SimpleHashBucket {
184185#ifndef GLOBAL_HASHSET_LOCK
185186 folly::SharedMutexWritePriority::WriteHolder holder (m_lock);
186187#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- }
188+ return erase_unsafe (input_key, out_val, true /* call_access_cb */ );
189+ }
199190
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 ;
191+ bool try_erase (const K& input_key) {
192+ V dummy_val;
193+ #ifndef GLOBAL_HASHSET_LOCK
194+ if (m_lock.try_lock ()) {
195+ bool ret = erase_unsafe (input_key, dummy_val, false /* call_access_cb */ );
196+ m_lock.unlock ();
197+ return ret;
198+ } else {
199+ return false ;
206200 }
207- return false ;
201+ #endif
202+ return erase_unsafe (input_key, dummy_val, false );
208203 }
209204
210205 bool upsert_or_delete (const K& input_key, auto && update_or_delete_cb) {
@@ -266,9 +261,33 @@ class SimpleHashBucket {
266261 static void access_cb (const SingleEntryHashNode< V >& node, const K& key, hash_op_t op) {
267262 SimpleHashMap< K, V >::call_access_cb ((const ValueEntryBase&)node, key, op);
268263 }
264+
265+ bool erase_unsafe (const K& input_key, V& out_val, bool call_access_cb) {
266+ SingleEntryHashNode< V >* n = nullptr ;
267+
268+ auto it = m_list.begin ();
269+ for (auto itend{m_list.end ()}; it != itend; ++it) {
270+ const K k = SimpleHashMap< K, V >::extractor_cb ()(it->m_value );
271+ if (input_key > k) {
272+ break ;
273+ } else if (input_key == k) {
274+ n = &*it;
275+ break ;
276+ }
277+ }
278+
279+ if (n) {
280+ if (call_access_cb) { access_cb (*n, input_key, hash_op_t ::DELETE); }
281+ out_val = n->m_value ;
282+ m_list.erase (it);
283+ delete n;
284+ return true ;
285+ }
286+ return false ;
287+ }
269288};
270289
271- // /////////////////////////////////////////// RangeHashMap Definitions ///////////////////////////////////
290+ // /////////////////////////////////////////// SimpleHashMap Definitions ///////////////////////////////////
272291template < typename K, typename V >
273292SimpleHashMap< K, V >::SimpleHashMap(uint32_t nBuckets, const key_extractor_cb_t < K, V >& extract_cb,
274293 key_access_cb_t < K > access_cb) :
@@ -317,6 +336,12 @@ bool SimpleHashMap< K, V >::erase(const K& key, V& out_val) {
317336 return get_bucket (key).erase (key, out_val);
318337}
319338
339+ template < typename K, typename V >
340+ bool SimpleHashMap< K, V >::try_erase(const K& key) {
341+ set_current_instance (this );
342+ return get_bucket (key).try_erase (key);
343+ }
344+
320345// / This is a special atomic operation where user can insert_or_update_or_erase based on condition atomically. It
321346// / performs differently based on certain conditions.
322347// /
0 commit comments