ALib C++ Framework
by
Library Version: 2605 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
containers_hashtable.hpp
Go to the documentation of this file.
1//==================================================================================================
2/// \file
3/// This header-file contributes to module \alib_containers but for technical reasons is part of
4/// the module \alib_format.
5/// is part of module \alib_format.
6///
7/// Copyright 2013-2026 A-Worx GmbH, Germany.
8/// Published under #"mainpage_license".
9//==================================================================================================
10#if ALIB_DEBUG_CONTAINERS
12
14/// Invokes method #"DbgGetHashTableDistribution" and creates human-readable
15/// output, ready to be logged or written to the console.
16///
17/// \par Availability
18/// This function is an extension, which is injected by the higher-level module \alib_format and
19/// is accessed through the header file #"F;ALib.Format.H".
20// Furthermore the configuration macro #"ALIB_DEBUG_CONTAINERS" has to be set.
21///
22/// \see
23/// Sibling namespace functions #"DbgGetHashTableDistribution" and
24/// #"DbgDumpHashtable" provided for debugging and optimization.
25///
26/// @tparam THashtable A specification of templated type #"HashTable".
27/// Deduced by the compiler by given parameter \p{hashtable}.
28/// @param hashtable The hashtable to investigate on.
29/// @param detailedBucketList If \c true is given, for each bucket a line with its size value and
30/// a "size bar" is written.
31///
32/// @return A string containing human-readable information about the distribution of elements
33/// in the hashtable.
34template<typename THashtable>
35inline
36AString DbgDumpDistribution(const THashtable& hashtable, bool detailedBucketList ) {
37 auto values = DbgGetHashTableDistribution( hashtable );
38 AString result;
39 double loadFactor= std::get<0>( values );
40 double deviation = std::get<1>( values );
41 integer minSize = std::get<2>( values );
42 integer maxSize = std::get<3>( values );
44 Formatter& formatter= *Formatter::DEFAULT;
45 formatter.GetArgContainer();
46 formatter.Format( result, "Size: {}\n"
47 "#Buckets: {}\n"
48 "Load Factor: {:.02} (Base: {:.01} Max: {:.01})\n"
49 "Deviation: {:.02} (~{:%.1})\n"
50 "Minimum: {}\n"
51 "Maximum: {}\n",
52 hashtable.Size(),
53 hashtable.BucketCount(),
54 loadFactor, hashtable.BaseLoadFactor(), hashtable.MaxLoadFactor(),
55 deviation , ( hashtable.Size() != 0
56 ? deviation / loadFactor
57 : 0.0 ),
58 minSize, maxSize );
59
60
61 // bucket filling statistics
62 integer* bucketFills= new integer[size_t(maxSize + 1)];
63 for( integer i= 0; i < maxSize ; ++i)
64 bucketFills[i]= 0;
65
66 for( uinteger i= 0; i < hashtable.BucketCount() ; ++i)
67 ++bucketFills[hashtable.BucketSize(i)];
68
69 formatter.Format( result, "Bucket Fills: Size #Buckets\n" );
70 formatter.Format( result, " -----------------\n" );
71 for( integer i= 0; i < maxSize ; ++i)
72 formatter.Format( result, " {} {}\n", i, bucketFills[i] );
73 delete[] bucketFills;
74
75
76 // detailed bucked list
77 if( detailedBucketList ) {
78 formatter.Format(result, "\nDetailed Bucket List:\n");
79 auto qtyBuckets = hashtable.BucketCount();
80 for( uinteger i= 0 ; i < qtyBuckets ; ++i ) {
81 auto bucketSize= hashtable.BucketSize( i );
82 formatter.Format(result, "{:3} ({:2}): {!FillCX}\n", i, bucketSize,
83 int(bucketSize) );
84 }
85
86 }
87 return result;
88}
89
90/// Dumps all values of the hash table sorted by buckets.
91/// Besides other scenarios of usage, this method allows investigating into how the keys of
92/// the table are distributed in the buckets, and thus learn something about the hash algorithm used.
93///
94/// Before invoking this method, specializations of #"AppendableTraits" have to be made
95/// and furthermore, boxed values of the type have to be <em>"made appendable"</em> to
96/// instances of type #"%AString". The latter is rather simple, if done using
97/// #"ALIB_BOXING_BOOTSTRAP_REGISTER_FAPPEND_FOR_APPENDABLE_TYPE;this macro" during bootstrap.
98///
99/// \note
100/// If the prerequisites for using this method seem to be too complicated and not worth the
101/// effort for a "quick debug session", it is recommended to just copy the source code of this
102/// inline function and adopt the #"Formatter::Format;*" statement to
103/// suit a specific type stored in \p{hashtable}.
104///
105/// \par Availability
106/// This function is an extension, which is injected by the higher-level module \alib_format and
107/// is accessed through the header file #"F;ALib.Format.H".
108// Furthermore, the configuration macro #"ALIB_DEBUG_CONTAINERS" has to be set.
109///
110/// \see
111/// Sibling namespace functions #"DbgGetHashTableDistribution" and
112/// #"DbgDumpDistribution" provided for debugging and optimization.
113///
114/// @tparam THashtable A specification of templated type #"HashTable".
115/// Deduced by the compiler by given parameter \p{hashtable}.
116/// @param hashtable The hashtable to investigate on.
117/// @return A string containing a dump of the given hash table's contents.
118template<typename THashtable>
119inline
120AString DbgDumpHashtable(const THashtable& hashtable ) {
121 AString result;
123 Formatter& formatter= *Formatter::DEFAULT;
124 formatter.GetArgContainer();
125 formatter.Format(result, "\nHashtable dump:\n");
126 auto qtyBuckets = hashtable.BucketCount();
127 for( uinteger i= 0 ; i < qtyBuckets ; ++i ) {
128 auto bucketSize= hashtable.BucketSize( i );
129 formatter.Format(result, "{:3} ({:2}): ", i, bucketSize );
130
131 int entryNo= 0;
132 for( auto bucketIt= hashtable.begin(i)
133 ; bucketIt != hashtable.end (i)
134 ;++bucketIt )
135 {
136 if( entryNo!=0)
137 result << " ";
138 formatter.Format(result, "{}: {}\n", entryNo, *bucketIt );
139 ++entryNo;
140 }
141 if( bucketSize == 0)
142 result << "---" << NEW_LINE;
143 }
144
145 return result;
146}
147} // namespace [alib::containers]
148#include "ALib.Lang.CIMethods.H"
149#endif //ALIB_DEBUG_CONTAINERS
#define ALIB_LOCK_RECURSIVE_WITH(lock)
#define ALIB_EXPORT
static threads::RecursiveLock DEFAULT_LOCK
static SPFormatter DEFAULT
std::tuple< double, double, integer, integer > DbgGetHashTableDistribution(const THashtable &hashtable)
AString DbgDumpHashtable(const THashtable &hashtable)
AString DbgDumpDistribution(const THashtable &hashtable, bool detailedBucketList)
format::Formatter Formatter
Type alias in namespace #"%alib".
constexpr CString NEW_LINE
A zero-terminated string containing the new-line character sequence.
Definition cstring.hpp:536
lang::integer integer
Type alias in namespace #"%alib".
Definition integers.hpp:149
strings::TAString< character, lang::HeapAllocator > AString
Type alias in namespace #"%alib".
lang::uinteger uinteger
Type alias in namespace #"%alib".
Definition integers.hpp:152