@@ -121,20 +121,31 @@ class extrinsic_storage {
121
121
}
122
122
123
123
// --------------------------------------------------------------------------
124
- // operator[] ( pobj ) - returns the data entry for pobj
124
+ // find_or_insert ( pobj ) - returns the data entry for pobj
125
125
//
126
126
// If pobj does not yet have an entry, creates it
127
127
//
128
- auto operator [] (void * pobj) -> Value& {
128
+ auto find_or_insert (void * pobj) -> Value& {
129
129
if constexpr (debug_instrumentation) {
130
130
// m_o_relaxed is enough, inc order doesn't matter for totals
131
131
instrument_access_count.fetch_add (1 , std::memory_order_relaxed);
132
132
}
133
- auto v = lookup (pobj);
133
+ auto v = lookup (pobj, lookup_mode::find_or_insert );
134
134
assert (v);
135
135
return *v;
136
136
}
137
137
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
+
138
149
// --------------------------------------------------------------------------
139
150
// erase( pobj ) - removes the entry for pobj
140
151
//
@@ -143,7 +154,7 @@ class extrinsic_storage {
143
154
// m_o_relaxed is enough, inc order doesn't matter for totals
144
155
instrument_erase_count.fetch_add (1 , std::memory_order_relaxed);
145
156
}
146
- lookup (pobj, true );
157
+ lookup (pobj, lookup_mode::erase );
147
158
}
148
159
149
160
private:
@@ -178,9 +189,10 @@ class extrinsic_storage {
178
189
// as I think they can be correct here and they are in the hot path
179
190
// of the data structure traversal.
180
191
//
192
+ enum class lookup_mode { find, find_or_insert, erase };
181
193
auto lookup (
182
- void * pobj,
183
- bool erase = false
194
+ void * pobj,
195
+ lookup_mode mode
184
196
)
185
197
-> Value*
186
198
{
@@ -202,7 +214,7 @@ class extrinsic_storage {
202
214
// and so this thread already has exclusive access to *pobj
203
215
// and its .values data
204
216
if (pchunk->keys [i].load (std::memory_order_relaxed) == pobj) {
205
- if (erase) {
217
+ if (mode == lookup_mode:: erase) {
206
218
pchunk->keys [i].store (nullptr , std::memory_order_relaxed);
207
219
return nullptr ;
208
220
}
@@ -217,11 +229,14 @@ class extrinsic_storage {
217
229
pchunk = pchunk->next .load (std::memory_order_relaxed);
218
230
}
219
231
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) {
222
235
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
+ }
225
240
}
226
241
return nullptr ;
227
242
}
0 commit comments