@@ -149,15 +149,8 @@ TEMPLATE
149149inline bool CLASS::push (bool & collision, const Link& current, bytes& next,
150150 const Key& key) NOEXCEPT
151151{
152- // TODO: need independent error sentinel.
153- const auto previous = set_cell (next, current, key);
154- // //if (previous == terminal)
155- // // return false;
156-
157- // Conflict (body) search is bypassed by filter when key is not screened.
158- // If collision false it is assured that table does not contain the key.
159- collision = screened (previous, key);
160- return true ;
152+ // next holds previous top and can searched for dups if collision is true.
153+ return set_cell (collision, next, current, key);
161154}
162155
163156// protected
@@ -185,25 +178,25 @@ inline CLASS::cell CLASS::get_cell(const Link& index) const NOEXCEPT
185178 }
186179 else
187180 {
188- cell top{} ;
189- const auto & head = cell_array (raw) ;
181+ const auto & top = cell_array (raw) ;
182+ cell head{} ;
190183
191184 mutex_.lock_shared ();
192- cell_array (top ) = head ;
185+ cell_array (head ) = top ;
193186 mutex_.unlock_shared ();
194187
195- return top ;
188+ return head ;
196189 }
197190}
198191
199192TEMPLATE
200- inline CLASS::cell CLASS::set_cell (bytes& next, const Link& current,
193+ inline bool CLASS::set_cell (bool & collision, bytes& next, const Link& current,
201194 const Key& key) NOEXCEPT
202195{
203196 using namespace system ;
204197 const auto raw = file_.get_raw (link_to_position (index (key)));
205198 if (is_null (raw))
206- return terminal ;
199+ return false ;
207200
208201 if constexpr (aligned)
209202 {
@@ -212,35 +205,34 @@ inline CLASS::cell CLASS::set_cell(bytes& next, const Link& current,
212205 // //const std::atomic_ref<cell> head(unsafe_byte_cast<cell>(raw));
213206 auto & top = *pointer_cast<std::atomic<cell>>(raw);
214207 auto head = top.load (std::memory_order_acquire);
208+ cell update{};
215209 do
216210 {
217- next = link_array (head);
218-
219211 // Compiler could order this after top.store, which would expose key
220212 // to search before next entry is linked. Thread fence imposes order.
221213 // A release fence ensures that all prior writes (like next) are
222214 // completed before any subsequent atomic store.
215+ next = link_array (head);
216+ update = to_cell (collision, head, current, key);
223217 std::atomic_thread_fence (std::memory_order_release);
224218 }
225- while (!top.compare_exchange_weak (head, to_cell (head, current, key) ,
219+ while (!top.compare_exchange_weak (head, update ,
226220 std::memory_order_release, std::memory_order_acquire));
227-
228- return top;
229221 }
230222 else
231223 {
232- cell top{} ;
233- auto & head = cell_array (raw) ;
224+ auto & top = cell_array (raw) ;
225+ cell head{} ;
234226
235227 mutex_.lock ();
236- cell_array (top ) = head ;
237- next = link_array (top );
238- auto bytes = to_cell (top , current, key);
239- head = cell_array (bytes );
228+ cell_array (head ) = top ;
229+ next = link_array (head );
230+ auto update = to_cell (collision, head , current, key);
231+ top = cell_array (update );
240232 mutex_.unlock ();
241-
242- return top;
243233 }
234+
235+ return true ;
244236}
245237
246238// protected
@@ -293,18 +285,21 @@ INLINE constexpr CLASS::link CLASS::to_link(cell value) NOEXCEPT
293285}
294286
295287TEMPLATE
296- INLINE constexpr CLASS::cell CLASS::to_cell (cell previous, link current ,
297- const Key& key) NOEXCEPT
288+ INLINE constexpr CLASS::cell CLASS::to_cell (bool & collision, cell previous ,
289+ link current, const Key& key) NOEXCEPT
298290{
299291 if constexpr (sieve_t ::disabled)
300292 {
293+ collision = true ;
301294 return current;
302295 }
303296 else
304297 {
305298 using namespace system ;
306- const auto value = sieve_t::screen (to_filter (previous), fingerprint (key));
307- return bit_or<cell>(shift_left<cell>(value, link_bits), current);
299+ const auto sieve = to_filter (previous);
300+ const auto next = sieve_t::screen (sieve, fingerprint (key));
301+ collision = (next == sieve || sieve_t::is_saturated (next));
302+ return bit_or<cell>(shift_left<cell>(next, link_bits), current);
308303 }
309304}
310305
0 commit comments