mirror of
https://github.com/boostorg/unordered.git
synced 2025-07-30 03:17:15 +02:00
added latch-free erasure
This commit is contained in:
@ -799,6 +799,34 @@ public:
|
|||||||
return erase_if(x,[](const value_type&){return true;});
|
return erase_if(x,[](const value_type&){return true;});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(BOOST_UNORDERED_LATCH_FREE)
|
||||||
|
template<typename Key,typename F>
|
||||||
|
BOOST_FORCEINLINE auto erase_if(const Key& x,F&& f)->typename std::enable_if<
|
||||||
|
!is_execution_policy<Key>::value,std::size_t>::type
|
||||||
|
{
|
||||||
|
auto lck=shared_access();
|
||||||
|
auto hash=this->hash_for(x);
|
||||||
|
std::size_t res=0;
|
||||||
|
unprotected_internal_visit(
|
||||||
|
group_shared{},x,this->position_for(hash),hash,
|
||||||
|
[&,this](group_type* pg,unsigned int n,element_type* p)
|
||||||
|
{
|
||||||
|
auto expected=group_type::reduced_hash(hash);
|
||||||
|
if(reinterpret_cast<std::atomic<unsigned char>*>(pg)[n].
|
||||||
|
compare_exchange_strong(expected,1)){
|
||||||
|
if(f(cast_for(group_shared{},type_policy::value_from(*p)))){
|
||||||
|
wait_for_epochs();
|
||||||
|
super::erase(pg,n,p);
|
||||||
|
res=1;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
pg->set(n,expected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
#else
|
||||||
template<typename Key,typename F>
|
template<typename Key,typename F>
|
||||||
BOOST_FORCEINLINE auto erase_if(const Key& x,F&& f)->typename std::enable_if<
|
BOOST_FORCEINLINE auto erase_if(const Key& x,F&& f)->typename std::enable_if<
|
||||||
!is_execution_policy<Key>::value,std::size_t>::type
|
!is_execution_policy<Key>::value,std::size_t>::type
|
||||||
@ -817,6 +845,7 @@ public:
|
|||||||
});
|
});
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
std::size_t erase_if(F&& f)
|
std::size_t erase_if(F&& f)
|
||||||
@ -1825,7 +1854,7 @@ private:
|
|||||||
void wait_for_epochs()
|
void wait_for_epochs()
|
||||||
{
|
{
|
||||||
for(std::size_t i=0;i<epochs.size();++i){
|
for(std::size_t i=0;i<epochs.size();++i){
|
||||||
while(epochs[i].load(std::memory_order_acquire)){}
|
while(epochs[i].load(std::memory_order_acquire)>1){}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -382,11 +382,13 @@ private:
|
|||||||
return (int)word[narrow_cast<unsigned char>(hash)];
|
return (int)word[narrow_cast<unsigned char>(hash)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
inline static unsigned char reduced_hash(std::size_t hash)
|
inline static unsigned char reduced_hash(std::size_t hash)
|
||||||
{
|
{
|
||||||
return narrow_cast<unsigned char>(match_word(hash));
|
return narrow_cast<unsigned char>(match_word(hash));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
inline slot_type& at(std::size_t pos)
|
inline slot_type& at(std::size_t pos)
|
||||||
{
|
{
|
||||||
return m[pos];
|
return m[pos];
|
||||||
@ -532,6 +534,7 @@ private:
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
inline static unsigned char reduced_hash(std::size_t hash)
|
inline static unsigned char reduced_hash(std::size_t hash)
|
||||||
{
|
{
|
||||||
static constexpr unsigned char table[]={
|
static constexpr unsigned char table[]={
|
||||||
@ -556,6 +559,7 @@ private:
|
|||||||
return table[(unsigned char)hash];
|
return table[(unsigned char)hash];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
/* Copied from
|
/* Copied from
|
||||||
* https://github.com/simd-everywhere/simde/blob/master/simde/x86/
|
* https://github.com/simd-everywhere/simde/blob/master/simde/x86/
|
||||||
* sse2.h#L3763
|
* sse2.h#L3763
|
||||||
|
Reference in New Issue
Block a user