@@ -121,20 +121,31 @@ class extrinsic_storage {
121121 }
122122
123123 // --------------------------------------------------------------------------
124- // operator[] ( pobj ) - returns the data entry for pobj
124+ // find_or_insert ( pobj ) - returns the data entry for pobj
125125 //
126126 // If pobj does not yet have an entry, creates it
127127 //
128- auto operator [] (void * pobj) -> Value& {
128+ auto find_or_insert (void * pobj) -> Value& {
129129 if constexpr (debug_instrumentation) {
130130 // m_o_relaxed is enough, inc order doesn't matter for totals
131131 instrument_access_count.fetch_add (1 , std::memory_order_relaxed);
132132 }
133- auto v = lookup (pobj);
133+ auto v = lookup (pobj, lookup_mode::find_or_insert );
134134 assert (v);
135135 return *v;
136136 }
137137
138+ // --------------------------------------------------------------------------
139+ // find( pobj ) - returns the data entry for pobj or null if not present
140+ //
141+ auto find (void * pobj) -> Value* {
142+ if constexpr (debug_instrumentation) {
143+ // m_o_relaxed is enough, inc order doesn't matter for totals
144+ instrument_access_count.fetch_add (1 , std::memory_order_relaxed);
145+ }
146+ return lookup (pobj, lookup_mode::find_or_insert);
147+ }
148+
138149 // --------------------------------------------------------------------------
139150 // erase( pobj ) - removes the entry for pobj
140151 //
@@ -143,7 +154,7 @@ class extrinsic_storage {
143154 // m_o_relaxed is enough, inc order doesn't matter for totals
144155 instrument_erase_count.fetch_add (1 , std::memory_order_relaxed);
145156 }
146- lookup (pobj, true );
157+ lookup (pobj, lookup_mode::erase );
147158 }
148159
149160private:
@@ -178,9 +189,10 @@ class extrinsic_storage {
178189 // as I think they can be correct here and they are in the hot path
179190 // of the data structure traversal.
180191 //
192+ enum class lookup_mode { find, find_or_insert, erase };
181193 auto lookup (
182- void * pobj,
183- bool erase = false
194+ void * pobj,
195+ lookup_mode mode
184196 )
185197 -> Value*
186198 {
@@ -202,7 +214,7 @@ class extrinsic_storage {
202214 // and so this thread already has exclusive access to *pobj
203215 // and its .values data
204216 if (pchunk->keys [i].load (std::memory_order_relaxed) == pobj) {
205- if (erase) {
217+ if (mode == lookup_mode:: erase) {
206218 pchunk->keys [i].store (nullptr , std::memory_order_relaxed);
207219 return nullptr ;
208220 }
@@ -217,11 +229,14 @@ class extrinsic_storage {
217229 pchunk = pchunk->next .load (std::memory_order_relaxed);
218230 }
219231
220- // 2. Otherwise, if we're erasing we're done but we didn't actually find something to erase
221- if (erase) {
232+ // 2. Otherwise, if we're not allowed to insert we're done
233+ // but we didn't actually find something so return null
234+ if (mode != lookup_mode::find_or_insert) {
222235 if constexpr (debug_instrumentation) {
223- // m_o_relaxed is enough, inc order doesn't matter for totals
224- instrument_erase_fail_count.fetch_add (1 , std::memory_order_relaxed);
236+ if (mode == lookup_mode::erase) {
237+ // m_o_relaxed is enough, inc order doesn't matter for totals
238+ instrument_erase_fail_count.fetch_add (1 , std::memory_order_relaxed);
239+ }
225240 }
226241 return nullptr ;
227242 }
0 commit comments