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