/// Initializises the splitter with reference to \p h and start bit offset \p nBitOffset
split_bitstring( bitstring const& h, size_t nBitOffset )
: m_ptr( reinterpret_cast<uint_type const*>( &h ) + nBitOffset / c_nBitPerInt )
- , m_pos( nBitOffset % c_nBitPerInt )
+ , m_pos( nBitOffset )
, m_first( reinterpret_cast<uint_type const*>(&h))
# ifdef _DEBUG
, m_last( m_first + c_nHashSize )
else if ( nBits == nRest ) {
result = *m_ptr >> ( c_nBitPerInt - nRest );
++m_ptr;
+ assert( m_pos % c_nBitPerInt == 0 );
}
else {
uint_type const lsb = *m_ptr >> ( c_nBitPerInt - nRest );
return reinterpret_cast<bitstring const *>( m_first );
}
+ /// Returns current bit offset from beginning of bit-string
+ size_t bit_offset() const
+ {
+ return m_pos;
+ }
+
private:
//@cond
uint_type const* m_ptr; ///< current position in the hash
struct traverse_data {
hash_splitter splitter;
array_node * pArr;
- size_t nOffset;
size_t nSlot;
size_t nHeight;
{
splitter.reset();
pArr = arr.head();
- nOffset = arr.metrics().head_node_size_log;
nSlot = splitter.cut( arr.metrics().head_node_size_log );
nHeight = 1;
}
pos.nSlot = pos.splitter.cut( metrics().array_node_size_log );
assert( pos.nSlot < metrics().array_node_size );
pos.pArr = to_array(slot.ptr());
- pos.nOffset += metrics().array_node_size_log;
++pos.nHeight;
}
else if (slot.bits() == flag_array_converting) {
bool expand_slot( traverse_data& pos, node_ptr current)
{
- bool bRet = expand_slot( pos.pArr, pos.nSlot, current, pos.nOffset );
- //pos.reset( *this );
- return bRet;
+ return expand_slot( pos.pArr, pos.nSlot, current, pos.splitter.bit_offset());
}
private:
if ( pos.pArr->nodes[pos.nSlot].load( memory_model::memory_order_acquire ) != slot ) {
// slot value has been changed - retry
stats().onSlotChanged();
+ continue;
}
else if ( slot.ptr() && cmp( hash, hash_accessor()(*slot.ptr())) == 0 ) {
// item found
if (guard.protect( pos.pArr->nodes[pos.nSlot], [](node_ptr p) -> value_type * { return p.ptr(); }) != slot) {
// slot value has been changed - retry
stats().onSlotChanged();
+ continue;
}
else if (slot.ptr() && cmp(hash, hash_accessor()(*slot.ptr())) == 0) {
// item found
stats().onSlotChanged();
}
else if (slot.ptr()) {
- if (cmp(hash, hash_accessor()(*slot.ptr())) == 0 && pred(*slot.ptr())) {
+ if ( cmp(hash, hash_accessor()(*slot.ptr())) == 0 && pred(*slot.ptr())) {
// item found - replace it with nullptr
if ( pos.pArr->nodes[pos.nSlot].compare_exchange_strong(slot, node_ptr(nullptr), memory_model::memory_order_acquire, atomics::memory_order_relaxed)) {
// slot is guarded by HP