@@ -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,24 @@ 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+ #else
202+ // We are in global hashset lock
203+ return erase_unsafe (input_key, dummy_val, false ); #endif
204+ #endif
205+ return erase_unsafe (input_key, dummy_val, false );
208206 }
209207
210208 bool upsert_or_delete (const K& input_key, auto && update_or_delete_cb) {
@@ -266,9 +264,33 @@ class SimpleHashBucket {
266264 static void access_cb (const SingleEntryHashNode< V >& node, const K& key, hash_op_t op) {
267265 SimpleHashMap< K, V >::call_access_cb ((const ValueEntryBase&)node, key, op);
268266 }
267+
268+ bool erase_unsafe (const K& input_key, V& out_val, bool call_access_cb) {
269+ SingleEntryHashNode< V >* n = nullptr ;
270+
271+ auto it = m_list.begin ();
272+ for (auto itend{m_list.end ()}; it != itend; ++it) {
273+ const K k = SimpleHashMap< K, V >::extractor_cb ()(it->m_value );
274+ if (input_key > k) {
275+ break ;
276+ } else if (input_key == k) {
277+ n = &*it;
278+ break ;
279+ }
280+ }
281+
282+ if (n) {
283+ if (call_access_cb) { access_cb (*n, input_key, hash_op_t ::DELETE); }
284+ out_val = n->m_value ;
285+ m_list.erase (it);
286+ delete n;
287+ return true ;
288+ }
289+ return false ;
290+ }
269291};
270292
271- // /////////////////////////////////////////// RangeHashMap Definitions ///////////////////////////////////
293+ // /////////////////////////////////////////// SimpleHashMap Definitions ///////////////////////////////////
272294template < typename K, typename V >
273295SimpleHashMap< K, V >::SimpleHashMap(uint32_t nBuckets, const key_extractor_cb_t < K, V >& extract_cb,
274296 key_access_cb_t < K > access_cb) :
@@ -317,6 +339,12 @@ bool SimpleHashMap< K, V >::erase(const K& key, V& out_val) {
317339 return get_bucket (key).erase (key, out_val);
318340}
319341
342+ template < typename K, typename V >
343+ bool SimpleHashMap< K, V >::try_erase(const K& key) {
344+ set_current_instance (this );
345+ return get_bucket (key).try_erase (key);
346+ }
347+
320348// / This is a special atomic operation where user can insert_or_update_or_erase based on condition atomically. It
321349// / performs differently based on certain conditions.
322350// /
0 commit comments