- size_t sz = m_nBucketCountLog2.load(atomics::memory_order_relaxed);
- if ( ( ++m_ItemCounter >> sz ) > m_Buckets.load_factor() && (static_cast<size_t>(1) << sz ) < m_Buckets.capacity() )
- {
- m_nBucketCountLog2.compare_exchange_strong( sz, sz + 1, memory_model::memory_order_relaxed, atomics::memory_order_relaxed );
- }
+ size_t nMaxCount = m_nMaxItemCount.load(memory_model::memory_order_relaxed);
+ if ( ++m_ItemCounter <= nMaxCount )
+ return;
+
+ const size_t nLoadFactor = m_Buckets.load_factor();
+ size_t sz = m_nBucketCountLog2.load(memory_model::memory_order_relaxed);
+ const size_t nBucketCount = static_cast<size_t>(1) << sz;
+ if ( nMaxCount < max_item_count( nBucketCount, nLoadFactor ))
+ return; // someone already have updated m_nBucketCountLog2, so stop here
+
+ const size_t nNewMaxCount = (nBucketCount < m_Buckets.capacity()) ? max_item_count( nBucketCount << 1, nLoadFactor )
+ : std::numeric_limits<size_t>::max();
+ m_nMaxItemCount.compare_exchange_strong( nMaxCount, nNewMaxCount, memory_model::memory_order_relaxed,
+ memory_model::memory_order_relaxed );
+ m_nBucketCountLog2.compare_exchange_strong( sz, sz + 1, memory_model::memory_order_seq_cst, memory_model::memory_order_relaxed );