Loading...
Searching...
No Matches
HashTableIO.C
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ========= |
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 \\ / O peration |
5 \\ / A nd | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2011-2016 OpenFOAM Foundation
9 Copyright (C) 2017-2023 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
12 This file is part of OpenFOAM.
13
14 OpenFOAM is free software: you can redistribute it and/or modify it
15 under the terms of the GNU General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26
27\*---------------------------------------------------------------------------*/
28
29#include "HashTable.H"
30#include "Istream.H"
31#include "Ostream.H"
32
33// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
34
35template<class T, class Key, class Hash>
37:
38 HashTable<T, Key, Hash>()
39{
40 operator>>(is, *this);
41}
42
43
44// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
45
46template<class T, class Key, class Hash>
48{
49 label used = 0;
50 label maxChain = 0;
51 unsigned avgChain = 0;
52
53 for (label i=0; i < capacity_; ++i)
54 {
55 label count = 0;
56 for (node_type* ep = table_[i]; ep; ep = ep->next_)
57 {
58 ++count;
59 }
60
61 if (count)
62 {
63 ++used;
64 avgChain += count;
65
66 if (maxChain < count)
67 {
68 maxChain = count;
69 }
70 }
71 }
72
73 os << "HashTable<T,Key,Hash>"
74 << " elements:" << size() << " slots:" << used << "/" << capacity_
75 << " chaining(avg/max):" << (used ? (float(avgChain)/used) : 0)
76 << "/" << maxChain << endl;
77
78 return os;
79}
80
81
82template<class T, class Key, class Hash>
84(
85 Ostream& os,
86 const label shortLen
87) const
88{
89 // Similar to UList::writeList version except the following:
90 // - the keys can never be uniform
91 // - never write in binary
92
93 label i = this->size();
94
95 if
96 (
97 (i <= 1 || !shortLen)
98 || (i <= shortLen)
99 )
100 {
101 // Write size and start delimiter
102 os << i << token::BEGIN_LIST;
103
104 i = 0;
105 for (const_iterator iter = this->cbegin(); iter != this->cend(); ++iter)
106 {
107 if (i++) os << token::SPACE;
108 os << iter.key();
109 }
110
111 os << token::END_LIST; // End delimiter
112 }
113 else
114 {
115 // Write size and start delimiter
116 os << nl << i << nl << token::BEGIN_LIST << nl;
117
118 for (const_iterator iter = this->cbegin(); iter != this->cend(); ++iter)
119 {
120 os << iter.key() << nl;
121 }
122
123 os << token::END_LIST << nl; // End delimiter
124 }
125
127 return os;
128}
129
130
131template<class T, class Key, class Hash>
132Foam::Istream& Foam::HashTable<T, Key, Hash>::readTable
133(
134 Istream& is
135)
136{
137 HashTable<T, Key, Hash>& tbl = *this;
138
139 // Anull existing table
140 tbl.clear();
141
142 is.fatalCheck(FUNCTION_NAME);
143
144 token tok(is);
145
146 is.fatalCheck
147 (
148 "operator>>(Istream&, HashTable&) : "
149 "reading first token"
150 );
151
152 if (tok.isLabel())
153 {
154 const label len = tok.labelToken();
155
156 // Read beginning of contents
157 const char delimiter = is.readBeginList("HashTable");
158
159 if (len)
160 {
161 if (delimiter != token::BEGIN_LIST)
162 {
164 << "incorrect first token, '(', found "
165 << tok.info() << nl
166 << exit(FatalIOError);
167 }
168
169 tbl.reserve(tbl.size() + len);
170
171 for (label i=0; i<len; ++i)
172 {
173 Key key;
174
175 is >> key; // Read the key
176 T& val = tbl(key); // Insert nameless T() into table
177 is >> val; // Read directly into the table value
178
179 is.fatalCheck
180 (
181 "operator>>(Istream&, HashTable&) : "
182 "reading entry"
183 );
184 }
185 }
186
187 // Read end of contents
188 is.readEndList("HashTable");
189 }
190 else if (tok.isPunctuation(token::BEGIN_LIST))
191 {
192 is >> tok;
193 while (!tok.isPunctuation(token::END_LIST))
194 {
195 is.putBack(tok);
196
197 Key key;
198
199 is >> key; // Read the key
200 T& val = tbl(key); // Insert nameless T() into table
201 is >> val; // Read directly into the table value
202
203 is.fatalCheck
204 (
205 "operator>>(Istream&, HashTable&) : "
206 "reading entry"
207 );
208
209 is >> tok;
210 }
211 }
212 else
213 {
215 << "incorrect first token, expected <int> or '(', found "
216 << tok.info() << nl
217 << exit(FatalIOError);
218 }
219
220 is.fatalCheck(FUNCTION_NAME);
221 return is;
222}
223
224
225template<class T, class Key, class Hash>
226Foam::Ostream& Foam::HashTable<T, Key, Hash>::writeTable
227(
228 Ostream& os
229) const
230{
231 const HashTable<T, Key, Hash>& tbl = *this;
232
233 const label len = tbl.size();
234
235 if (len)
236 {
237 // Size and start list delimiter
238 os << nl << len << nl << token::BEGIN_LIST << nl;
239
240 // Contents
241 for (auto iter = tbl.cbegin(); iter != tbl.cend(); ++iter)
242 {
243 iter.print(os) << nl;
244 }
245
246 os << token::END_LIST; // End list delimiter
247 }
248 else
249 {
250 // Empty hash table
252 }
253
255 return os;
256}
257
258
259// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
260
261template<class T, class Key, class Hash>
262Foam::Istream& Foam::operator>>
263(
264 Istream& is,
266)
267{
268 return tbl.readTable(is);
269}
270
271
272template<class T, class Key, class Hash>
273Foam::Ostream& Foam::operator<<
274(
275 Ostream& os,
276 const HashTable<T, Key, Hash>& tbl
277)
278{
279 return tbl.writeTable(os);
280}
281
282
283// ************************************************************************* //
Forward iterator with const access.
Definition HashTable.H:1135
A HashTable similar to std::unordered_map.
Definition HashTable.H:124
Ostream & writeKeys(Ostream &os, const label shortLen=0) const
Write unordered keys (list), with line-breaks when length exceeds shortLen.
Definition HashTableIO.C:77
Ostream & printInfo(Ostream &os) const
Print information.
Definition HashTableIO.C:40
const_iterator cbegin() const
const_iterator set to the beginning of the HashTable
void reserve(label numEntries)
Reserve space for at least the specified number of elements (not the number of buckets) and regenerat...
Definition HashTable.C:729
label size() const noexcept
The number of elements in table.
Definition HashTable.H:358
std::conditional_t< std::is_same_v< Foam::zero, std::remove_cv_t< T > >, Detail::HashTableSingle< Key >, Detail::HashTablePair< Key, T > > node_type
A table entry (node) that encapsulates the key/val tuple with an additional linked-list entry for has...
Definition HashTable.H:138
void clear()
Remove all entries from table.
Definition HashTable.C:742
constexpr const_iterator cend() const noexcept
const_iterator to signal the end (for any HashTable)
friend Istream & operator>>(Istream &, HashTable< T, Key, Hash > &tbl)
constexpr HashTable() noexcept
Default construct: empty without allocation (capacity=0).
Definition HashTable.C:33
bool fatalCheck(const char *operation) const
Check IOstream status for given operation.
Definition IOstream.C:51
virtual bool check(const char *operation) const
Check IOstream status for given operation.
Definition IOstream.C:45
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition Istream.H:60
char readEndList(const char *funcName)
End read of list data, ends with ')' or '}'.
Definition Istream.C:192
char readBeginList(const char *funcName)
Begin read of list data, starts with '(' or '{'.
Definition Istream.C:171
void putBack(const token &tok)
Put back a token (copy). Only a single put back is permitted.
Definition Istream.C:71
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition Ostream.H:59
A token holds an item read from Istream.
Definition token.H:70
@ BEGIN_LIST
Begin list [isseparator].
Definition token.H:174
@ END_LIST
End list [isseparator].
Definition token.H:175
@ SPACE
Space [isspace].
Definition token.H:144
const volScalarField & T
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition error.H:629
OBJstream os(runTime.globalPath()/outputName)
#define FUNCTION_NAME
labelHashSet used(const bitSet &select)
Convert a bitset to a labelHashSet of the indices used.
Definition HashOps.C:26
constexpr auto key(const Type &t) noexcept
Helper function to return the enum value.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition Ostream.H:519
IOerror FatalIOError
Error stream (stdout output on all processes), with additional 'FOAM FATAL IO ERROR' header text and ...
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition errorManip.H:125
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
constexpr char nl
The newline '\n' character (0x0a).
Definition Ostream.H:50
Hash function class. The default definition is for primitives. Non-primitives used to hash entries on...
Definition Hash.H:48