initial commit for version 1.6.x patch release
[OpenFOAM-1.6.x.git] / src / OpenFOAM / containers / HashTables / HashTable / HashTableIO.C
blobbef0cf50bcac828e5c7d5655d2c3acc1fd9837d4
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
9     This file is part of OpenFOAM.
11     OpenFOAM is free software; you can redistribute it and/or modify it
12     under the terms of the GNU General Public License as published by the
13     Free Software Foundation; either version 2 of the License, or (at your
14     option) any later version.
16     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
19     for more details.
21     You should have received a copy of the GNU General Public License
22     along with OpenFOAM; if not, write to the Free Software Foundation,
23     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 \*---------------------------------------------------------------------------*/
27 #include "HashTable.H"
28 #include "Istream.H"
29 #include "Ostream.H"
31 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
33 template<class T, class Key, class Hash>
34 Foam::HashTable<T, Key, Hash>::HashTable(Istream& is, const label size)
36     HashTableName(),
37     nElmts_(0),
38     tableSize_(canonicalSize(size)),
39     table_(new hashedEntry*[tableSize_]),
40     endIter_(*this, NULL, 0),
41     endConstIter_(*this, NULL, 0)
43     for (label hashIdx = 0; hashIdx < tableSize_; hashIdx++)
44     {
45         table_[hashIdx] = 0;
46     }
48     operator>>(is, *this);
52 // * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
54 template<class T, class Key, class Hash>
55 Foam::Ostream&
56 Foam::HashTable<T, Key, Hash>::printInfo(Ostream& os) const
58     label used = 0;
59     label maxChain = 0;
60     unsigned avgChain = 0;
62     for (label hashIdx = 0; hashIdx < tableSize_; ++hashIdx)
63     {
64         label count = 0;
65         for (hashedEntry* ep = table_[hashIdx]; ep; ep = ep->next_)
66         {
67             ++count;
68         }
70         if (count)
71         {
72             ++used;
73             avgChain += count;
75             if (maxChain < count)
76             {
77                 maxChain = count;
78             }
79         }
80     }
82     os  << "HashTable<T,Key,Hash>"
83         << " elements:" << size() << " slots:" << used << "/" << tableSize_
84         << " chaining(avg/max):" << (used ? (float(avgChain)/used) : 0)
85         << "/" << maxChain << endl;
87     return os;
91 // * * * * * * * * * * * * * * * IOstream Operators  * * * * * * * * * * * * //
93 template<class T, class Key, class Hash>
94 Foam::Istream& Foam::operator>>
96     Istream& is,
97     HashTable<T, Key, Hash>& L
100     is.fatalCheck("operator>>(Istream&, HashTable<T, Key, Hash>&)");
102     // Anull list
103     L.clear();
105     is.fatalCheck("operator>>(Istream&, HashTable<T, Key, Hash>&)");
107     token firstToken(is);
109     is.fatalCheck
110     (
111         "operator>>(Istream&, HashTable<T, Key, Hash>&) : "
112         "reading first token"
113     );
115     if (firstToken.isLabel())
116     {
117         label s = firstToken.labelToken();
119         // Read beginning of contents
120         char delimiter = is.readBeginList("HashTable<T, Key, Hash>");
122         if (s)
123         {
124             if (2*s > L.tableSize_)
125             {
126                 L.resize(2*s);
127             }
129             if (delimiter == token::BEGIN_LIST)
130             {
131                 for (label i=0; i<s; i++)
132                 {
133                     Key key;
134                     is >> key;
135                     L.insert(key, pTraits<T>(is));
137                     is.fatalCheck
138                     (
139                         "operator>>(Istream&, HashTable<T, Key, Hash>&) : "
140                         "reading entry"
141                     );
142                 }
143             }
144             else
145             {
146                 FatalIOErrorIn
147                 (
148                     "operator>>(Istream&, HashTable<T, Key, Hash>&)",
149                     is
150                 )   << "incorrect first token, '(', found " << firstToken.info()
151                     << exit(FatalIOError);
152             }
153         }
155         // Read end of contents
156         is.readEndList("HashTable");
157     }
158     else if (firstToken.isPunctuation())
159     {
160         if (firstToken.pToken() != token::BEGIN_LIST)
161         {
162             FatalIOErrorIn
163             (
164                 "operator>>(Istream&, HashTable<T, Key, Hash>&)",
165                 is
166             )   << "incorrect first token, '(', found " << firstToken.info()
167                 << exit(FatalIOError);
168         }
170         token lastToken(is);
171         while
172         (
173            !(
174                 lastToken.isPunctuation()
175              && lastToken.pToken() == token::END_LIST
176             )
177         )
178         {
179             is.putBack(lastToken);
181             Key key;
182             is >> key;
184             T element;
185             is >> element;
187             L.insert(key, element);
189             is.fatalCheck
190             (
191                 "operator>>(Istream&, HashTable<T, Key, Hash>&) : "
192                 "reading entry"
193             );
195             is >> lastToken;
196         }
197     }
198     else
199     {
200         FatalIOErrorIn
201         (
202             "operator>>(Istream&, HashTable<T, Key, Hash>&)",
203             is
204         )   << "incorrect first token, expected <int> or '(', found "
205             << firstToken.info()
206             << exit(FatalIOError);
207     }
209     is.fatalCheck("operator>>(Istream&, HashTable<T, Key, Hash>&)");
211     return is;
215 template<class T, class Key, class Hash>
216 Foam::Ostream& Foam::operator<<
218     Ostream& os,
219     const HashTable<T, Key, Hash>& L
222     // Write size and start delimiter
223     os << nl << L.size() << nl << token::BEGIN_LIST << nl;
225     // Write contents
226     for
227     (
228         typename HashTable<T, Key, Hash>::const_iterator iter = L.cbegin();
229         iter != L.cend();
230         ++iter
231     )
232     {
233         os << iter.key() << token::SPACE << iter() << nl;
234     }
236     // Write end delimiter
237     os << token::END_LIST;
239     // Check state of IOstream
240     os.check("Ostream& operator<<(Ostream&, const HashTable&)");
242     return os;
246 // ************************************************************************* //