8#ifndef HPP_ALIB_MONOMEM_DETAIL_HASHTABLEBASE
9#define HPP_ALIB_MONOMEM_DETAIL_HASHTABLEBASE 1
11#if !defined(HPP_ALIB_MONOMEM_HASHTABLE)
12# error "ALib sources with ending '.inl' must not be included from outside."
14#if !defined (HPP_ALIB_MONOMEM_FWDS)
17#if !defined (HPP_ALIB_MONOMEM_MONOALLOCATOR)
21#if !defined(HPP_ALIB_LANG_SIDILIST)
25#if !defined (HPP_ALIB_MONOMEM_DETAIL_RECYCLER)
29#if !defined(HPP_ALIB_LANG_TMP) && !defined(ALIB_DOX)
33#if ALIB_STRINGS && ALIB_ENUMS
34# if !defined(HPP_ALIB_LANG_COMMONENUMS)
38# if !defined(HPP_ALIB_LANG_COMMONENUMS_DEFS)
43#if !defined (_GLIBCXX_ALGORITHM) && !defined(_ALGORITHM_)
47namespace alib {
namespace monomem {
55#if ALIB_SIZEOF_INTEGER == 4
57#elif ALIB_SIZEOF_INTEGER == 8
61 #error "Unknown size of integer"
78template<
typename T,
typename TStored>
100 *
const_cast<size_t*
>(&
hashCode)= pHashCode;
119template<
typename T,
typename TStored>
160template<
typename T,
typename TStored,
typename TKey,lang::Caching THashCaching>
167 && !std::is_arithmetic<TKey>::value ),
168 detail::HashTableElementCached <T ALIB_COMMA TStored>,
177template<
typename T,
typename TStored,
typename TKey,lang::Caching THashCaching,
typename TRecycling>
182#if !defined(ALIB_DOX)
183template<
typename T,
typename TStored,
typename TKey,lang::Caching THashCaching>
187template<
typename T,
typename TStored,
typename TKey,lang::Caching THashCaching>
188struct HashTableRecycler<T,TStored,TKey,THashCaching,
Recycling::Shared >
189{
using type= detail::RecyclerShared <typename HashTableElementType<T,TStored,TKey,THashCaching>::type >; };
191template<
typename T,
typename TStored,
typename TKey,lang::Caching THashCaching>
192struct HashTableRecycler<T,TStored,TKey,THashCaching,
Recycling::None >
193{
using type= detail::RecyclerVoid <typename HashTableElementType<T,TStored,TKey,THashCaching>::type >; };
244 typename TRecycling >
284 return TAccess().Key( element->value );
292 return TAccess().Mapped( element->value );
300 if constexpr ( Element::CachedHashCodes )
301 return elem->getCached();
312 if( elem ==
nullptr )
315 elem->fixHashCode( hashCode );
334 template<
typename TConstOrMutable>
337 #if !defined(ALIB_DOX)
339 friend class HashTable<T,TStored,TKey,TIfMapped,THash,TEqual,TAccess,THashCaching,TRecycling>;
373 if( !pTable->buckets[pBbucketIx].isEmpty() )
376 element = pTable->buckets[pBbucketIx].first();
426 #if defined(ALIB_DOX)
492 return !(*
this == other);
511 return &
element->valueExternal;
538 template<
typename TEnableIf= TMapped>
560 template<
typename TConstOrMutable>
563 #if !defined(ALIB_DOX)
565 friend class HashTable<T,TStored,TKey,TIfMapped,THash,TEqual,TAccess,THashCaching,TRecycling>;
590 #if defined(ALIB_DOX)
654 return !(*
this == other);
672 return &
element->valueExternal;
699 template<
typename TEnableIf= TMapped>
741 float pBaseLoadFactor,
742 float pMaxLoadFactor )
763 float pBaseLoadFactor = 1.0,
764 float pMaxLoadFactor = 2.0 )
805 return ( !Element::CachedHashCodes || ( keyHashCode ==
getHashCode(elem) ) )
824 return static_cast<Element*
>(result);
826 result= result->next();
847 while( result->hasNext() && !
areEqual( result->next(), key, keyHashCode ) )
848 result= result->
next();
850 return result->hasNext() ? result :
nullptr;
866 if( previous ==
nullptr )
908 if( first !=
nullptr )
912 while( last->hasNext() )
938 recycler.disposeRecyclablesIfPrivate();
972 newMinBucketCount= (std::max)( newMinBucketCount,
986 "Internal error: Rehashing to equal or smaller bucket count." )
993 for(
uinteger bucketIdx= 0 ; bucketIdx < oldBucketCount ; ++bucketIdx )
997 if( first !=
nullptr )
1010 while( actual !=
nullptr )
1012 Element* next= actual->next();
1020 recycler.template recycleChunk<List>( oldData, oldBucketCount );
1038 const auto hashCode= THash()(key);
1041 if( element ==
nullptr )
1045 auto result= std::make_pair(
TIterator<T>(
this, bucketIdx, element ),
1050 if( result.second.element ==
nullptr
1051 || !
areEqual( result.second.element, key, hashCode ) )
1076 if (element !=
nullptr )
1077 return std::make_pair(
TIterator<T>(
this, bucketIdx, element ),
false);
1084 return std::make_pair(
TIterator<T>(
this, bucketIdx, newElement ) ,
true);
1098 std::pair<TIterator<T>,
bool>
insertOrGet(
const TKey& key,
size_t hashCode )
1102 auto* elem=
findElement( bucketIdx, key, hashCode );
1103 if( elem !=
nullptr )
1104 return std::make_pair(
TIterator<T>(
this, bucketIdx, elem ),
false);
1112 return std::make_pair(
TIterator<T>(
this, bucketIdx, newElem ),
true);
ALIB_FORCE_INLINE char * Alloc(size_t size, size_t alignment)
T * EmplaceArray(TSize length, TArgs &&... args)
TConstOrMutable * operator->() const
TIterator(THashtable *pTable, uinteger pBbucketIx, Element *pElement)
ATMP_IF_T_F(!ATMP_IS_CONST(TConstOrMutable), HashTableBase, const HashTableBase) THashtable
TConstOrMutable & Value() const
TIterator(THashtable *pTable, uinteger pBbucketIx)
TMapped value_type
Implementation of std::iterator_traits.
std::forward_iterator_tag iterator_category
Implementation of std::iterator_traits.
TIterator & operator=(const TIterator &other)=default
TIterator(const TIterator &other)=default
TIterator operator++(int)
bool operator==(TIterator other) const
TConstOrMutable & operator*() const
bool operator!=(TIterator other) const
TConstOrMutable * pointer
Implementation of std::iterator_traits.
integer difference_type
Implementation of std::iterator_traits.
TConstOrMutable & reference
Implementation of std::iterator_traits.
TLocalIterator & operator++()
TLocalIterator(const TLocalIterator &other)=default
TConstOrMutable * operator->() const
TLocalIterator operator++(int)
TConstOrMutable value_type
Implementation of std::iterator_traits.
TConstOrMutable & Value() const
TLocalIterator & operator=(const TLocalIterator &other)=default
TLocalIterator(uinteger pBucketIdx, Element *pElement)
std::forward_iterator_tag iterator_category
Implementation of std::iterator_traits.
TConstOrMutable & operator*() const
bool operator!=(TLocalIterator other) const
TConstOrMutable * pointer
Implementation of std::iterator_traits.
integer difference_type
Implementation of std::iterator_traits.
TConstOrMutable & reference
Implementation of std::iterator_traits.
bool operator==(TLocalIterator other) const
#define ATMP_IF_T_F( Cond, T, F)
#define ALIB_WARNINGS_RESTORE
#define ATMP_EQ( T, TEqual)
#define ALIB_ASSERT_ERROR(cond,...)
#define ALIB_WARNINGS_ALLOW_UNSAFE_BUFFER_USAGE
#define ATMP_SELECT_IF_1TP(TParam, ...)
#define ATMP_T_IF(T, Cond)
@ Enabled
Caching is enabled.
ALIB_WARNINGS_RESTORE ALIB_API void * dummyBucket
static constexpr int primeTableSize
ALIB_WARNINGS_ALLOW_UNSAFE_BUFFER_USAGE ALIB_API const uinteger primeNumbers[primeTableSize]
lang::uinteger uinteger
Type alias in namespace alib.
lang::integer integer
Type alias in namespace alib.
void pushFront(TElement *elem)
void next(SidiNodeBase *p)
TElement * addBehind(TElement *elem)
integer sizeLimitToRehash
Element * findElement(uinteger bucketIdx, const TKey &key, size_t keyHashCode) const
static TMapped & mappedPortion(Element *element)
bool areEqual(Element *lhs, Element *rhs) const
ATMP_IF_T_F(ATMP_EQ(TIfMapped, void), NO_MAPPING, TIfMapped) TMapped
std::pair< TIterator< T >, bool > insertIfNotExists(const TKey &key, size_t hashCode)
HashTableRecycler< T, TStored, TKey, THashCaching, TRecycling >::type recycler
static TKey & keyPortion(Element *element)
HashTableBase(MonoAllocator *pAllocator, float pBaseLoadFactor, float pMaxLoadFactor)
size_t increaseSize(integer increase, const size_t hashCode=0)
HashTableBase(MonoAllocator *pAllocator, List &pRecycler, float pBaseLoadFactor=1.0, float pMaxLoadFactor=2.0)
typename HashTableElementType< T, TStored, TKey, THashCaching >::type Element
void rehash(uinteger newMinBucketCount)
std::pair< TIterator< T >, TIterator< T > > findRange(const TKey &key)
Element * allocElement(const size_t hashCode)
std::pair< TIterator< T >, bool > insertOrGet(const TKey &key, size_t hashCode)
MonoAllocator * allocator
static size_t getHashCode(Element *elem)
uinteger insertInBucket(Element *element, const size_t hashCode)
void setMaxLoadFactor(float pMaxLoadFactor)
Node * findElementBefore(uinteger bucketIdx, size_t keyHashCode, const TKey &key) const
bool areEqual(Element *elem, const TKey &key, size_t keyHashCode) const
T valueExternal
The value as seen externally.
size_t hashCode
The cached hash code.
~HashTableElementCached()=delete
TStored value
The value as seen internally.
static constexpr bool CachedHashCodes
void fixHashCode(size_t pHashCode)
ATMP_IF_T_F( THashCaching==lang::Caching::Enabled||( THashCaching==lang::Caching::Auto &&!std::is_arithmetic< TKey >::value), detail::HashTableElementCached< T ALIB_COMMA TStored >, detail::HashTableElementUncached< T ALIB_COMMA TStored >) type
T valueExternal
The value as seen externally.
~HashTableElementUncached()=delete
TStored value
The value as seen internally.
static constexpr bool CachedHashCodes
void fixHashCode(size_t pHashCode)