third attempt

This commit is contained in:
joaquintides
2022-11-27 20:54:26 +01:00
parent 602488abc1
commit 0a91421fb8

View File

@@ -656,33 +656,7 @@ private:
* these values and positioning to be as uncorrelated as possible. * these values and positioning to be as uncorrelated as possible.
*/ */
#if 1 #if 0
struct pow2_size_policy
{
static inline std::size_t size_index(std::size_t n)
{
// TODO: min size is 2, see if we can bring it down to 1 without loss
// of performance
std::size_t size_index_=sizeof(std::size_t)*CHAR_BIT-
(n<=2?1:((std::size_t)(boost::core::bit_width(n-1))));
std::size_t salt=xmx(size_index_)&~0xffu;
return salt|size_index_;
}
static inline std::size_t size(std::size_t size_index_)
{
return std::size_t(1)<<(sizeof(std::size_t)*CHAR_BIT-(size_index_&0xffu));
}
static constexpr std::size_t min_size(){return 2;}
static inline std::size_t position(std::size_t hash,std::size_t size_index_)
{
return hash>>(size_index_&0xffu);
}
};
#else
struct pow2_size_policy struct pow2_size_policy
{ {
static inline std::size_t size_index(std::size_t n) static inline std::size_t size_index(std::size_t n)
@@ -703,9 +677,65 @@ struct pow2_size_policy
static inline std::size_t position(std::size_t hash,std::size_t size_index_) static inline std::size_t position(std::size_t hash,std::size_t size_index_)
{ {
auto rot=(sizeof(std::size_t)*CHAR_BIT-size_index_)/4+1; return hash>>size_index_;
auto carry=hash>>(sizeof(std::size_t)*CHAR_BIT-rot); }
return ((hash<<rot)>>size_index_)|carry; };
#else
struct pow2_size_policy
{
static inline std::size_t size_index(std::size_t n)
{
// TODO: min size is 2, see if we can bring it down to 1 without loss
// of performance
std::size_t used_bits_=n<=2?1:((std::size_t)(boost::core::bit_width(n-1)));
std::size_t used_mask_=(std::size_t(1)<<used_bits_)-1;
std::size_t used_hi_=used_bits_>=10?(5-(used_bits_%6))*2:0;
std::size_t used_lo_=used_bits_-used_hi_;
std::size_t unused_bits_=total_bits-used_bits_;
return (used_mask_<<24)|(used_hi_<<16)|(used_lo_<<8)|unused_bits_;
}
static inline std::size_t size(std::size_t size_index_)
{
return std::size_t(1)<<(total_bits-unused_bits(size_index_));
}
static constexpr std::size_t min_size(){return 2;}
static inline std::size_t position(std::size_t hash,std::size_t size_index_)
{
std::size_t used_mask_=used_mask(size_index_);
std::size_t used_hi_=used_hi(size_index_);
std::size_t used_lo_=used_lo(size_index_);
std::size_t unused_bits_=unused_bits(size_index_);
hash>>=unused_bits_;
return ((hash>>used_lo_)|(hash<<used_hi_))&used_mask_;
}
private:
static constexpr std::size_t total_bits=sizeof(std::size_t)*CHAR_BIT;
static inline std::size_t used_mask(std::size_t size_index_)
{
return size_index_>>24;
}
static inline std::size_t used_hi(std::size_t size_index_)
{
return (size_index_>>16)&0xffu;
}
static inline std::size_t used_lo(std::size_t size_index_)
{
return (size_index_>>8)&0xffu;
}
static inline std::size_t unused_bits(std::size_t size_index_)
{
return size_index_&0xffu;
} }
}; };
#endif #endif
@@ -755,18 +785,18 @@ private:
struct no_mix struct no_mix
{ {
template<typename Hash,typename T> template<typename Hash,typename T>
static inline std::size_t mix(const Hash& h,const T& x,std::size_t salt) static inline std::size_t mix(const Hash& h,const T& x)
{ {
return boost::core::rotl(h(x),(2*salt)&(64-1)); return h(x);
} }
}; };
struct xmx_mix struct xmx_mix
{ {
template<typename Hash,typename T> template<typename Hash,typename T>
static inline std::size_t mix(const Hash& h,const T& x,std::size_t salt) static inline std::size_t mix(const Hash& h,const T& x)
{ {
return xmx(h(x)^salt); return xmx(h(x));
} }
}; };
@@ -1581,13 +1611,7 @@ private:
template<typename Key> template<typename Key>
inline std::size_t hash_for(const Key& x)const inline std::size_t hash_for(const Key& x)const
{ {
return hash_for(x,arrays); return mix_policy::mix(h(),x);
}
template<typename Key>
inline std::size_t hash_for(const Key& x,const arrays_type& arrays_)const
{
return mix_policy::mix(h(),x,arrays_.groups_size_index);
} }
inline std::size_t position_for(std::size_t hash)const inline std::size_t position_for(std::size_t hash)const
@@ -1802,7 +1826,7 @@ private:
value_type* p,const arrays_type& arrays_,std::size_t& num_destroyed) value_type* p,const arrays_type& arrays_,std::size_t& num_destroyed)
{ {
nosize_transfer_element( nosize_transfer_element(
p,hash_for(key_from(*p),arrays_),arrays_,num_destroyed, p,hash_for(key_from(*p)),arrays_,num_destroyed,
std::integral_constant< /* std::move_if_noexcept semantics */ std::integral_constant< /* std::move_if_noexcept semantics */
bool, bool,
std::is_nothrow_move_constructible<init_type>::value|| std::is_nothrow_move_constructible<init_type>::value||