00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "HashTable.H"
00027 #include <OpenFOAM/Istream.H>
00028 #include <OpenFOAM/Ostream.H>
00029
00030
00031
00032 template<class T, class Key, class Hash>
00033 Foam::HashTable<T, Key, Hash>::HashTable(Istream& is, const label size)
00034 :
00035 HashTableName(),
00036 nElmts_(0),
00037 tableSize_(canonicalSize(size)),
00038 table_(new hashedEntry*[tableSize_]),
00039 endIter_(*this, NULL, 0),
00040 endConstIter_(*this, NULL, 0)
00041 {
00042 for (label hashIdx = 0; hashIdx < tableSize_; hashIdx++)
00043 {
00044 table_[hashIdx] = 0;
00045 }
00046
00047 operator>>(is, *this);
00048 }
00049
00050
00051
00052
00053 template<class T, class Key, class Hash>
00054 Foam::Ostream&
00055 Foam::HashTable<T, Key, Hash>::printInfo(Ostream& os) const
00056 {
00057 label used = 0;
00058 label maxChain = 0;
00059 unsigned avgChain = 0;
00060
00061 for (label hashIdx = 0; hashIdx < tableSize_; ++hashIdx)
00062 {
00063 label count = 0;
00064 for (hashedEntry* ep = table_[hashIdx]; ep; ep = ep->next_)
00065 {
00066 ++count;
00067 }
00068
00069 if (count)
00070 {
00071 ++used;
00072 avgChain += count;
00073
00074 if (maxChain < count)
00075 {
00076 maxChain = count;
00077 }
00078 }
00079 }
00080
00081 os << "HashTable<T,Key,Hash>"
00082 << " elements:" << size() << " slots:" << used << "/" << tableSize_
00083 << " chaining(avg/max):" << (used ? (float(avgChain)/used) : 0)
00084 << "/" << maxChain << endl;
00085
00086 return os;
00087 }
00088
00089
00090
00091
00092 template<class T, class Key, class Hash>
00093 Foam::Istream& Foam::operator>>
00094 (
00095 Istream& is,
00096 HashTable<T, Key, Hash>& L
00097 )
00098 {
00099 is.fatalCheck("operator>>(Istream&, HashTable<T, Key, Hash>&)");
00100
00101
00102 L.clear();
00103
00104 is.fatalCheck("operator>>(Istream&, HashTable<T, Key, Hash>&)");
00105
00106 token firstToken(is);
00107
00108 is.fatalCheck
00109 (
00110 "operator>>(Istream&, HashTable<T, Key, Hash>&) : "
00111 "reading first token"
00112 );
00113
00114 if (firstToken.isLabel())
00115 {
00116 label s = firstToken.labelToken();
00117
00118
00119 char delimiter = is.readBeginList("HashTable<T, Key, Hash>");
00120
00121 if (s)
00122 {
00123 if (2*s > L.tableSize_)
00124 {
00125 L.resize(2*s);
00126 }
00127
00128 if (delimiter == token::BEGIN_LIST)
00129 {
00130 for (label i=0; i<s; i++)
00131 {
00132 Key key;
00133 is >> key;
00134 L.insert(key, pTraits<T>(is));
00135
00136 is.fatalCheck
00137 (
00138 "operator>>(Istream&, HashTable<T, Key, Hash>&) : "
00139 "reading entry"
00140 );
00141 }
00142 }
00143 else
00144 {
00145 FatalIOErrorIn
00146 (
00147 "operator>>(Istream&, HashTable<T, Key, Hash>&)",
00148 is
00149 ) << "incorrect first token, '(', found " << firstToken.info()
00150 << exit(FatalIOError);
00151 }
00152 }
00153
00154
00155 is.readEndList("HashTable");
00156 }
00157 else if (firstToken.isPunctuation())
00158 {
00159 if (firstToken.pToken() != token::BEGIN_LIST)
00160 {
00161 FatalIOErrorIn
00162 (
00163 "operator>>(Istream&, HashTable<T, Key, Hash>&)",
00164 is
00165 ) << "incorrect first token, '(', found " << firstToken.info()
00166 << exit(FatalIOError);
00167 }
00168
00169 token lastToken(is);
00170 while
00171 (
00172 !(
00173 lastToken.isPunctuation()
00174 && lastToken.pToken() == token::END_LIST
00175 )
00176 )
00177 {
00178 is.putBack(lastToken);
00179
00180 Key key;
00181 is >> key;
00182
00183 T element;
00184 is >> element;
00185
00186 L.insert(key, element);
00187
00188 is.fatalCheck
00189 (
00190 "operator>>(Istream&, HashTable<T, Key, Hash>&) : "
00191 "reading entry"
00192 );
00193
00194 is >> lastToken;
00195 }
00196 }
00197 else
00198 {
00199 FatalIOErrorIn
00200 (
00201 "operator>>(Istream&, HashTable<T, Key, Hash>&)",
00202 is
00203 ) << "incorrect first token, expected <int> or '(', found "
00204 << firstToken.info()
00205 << exit(FatalIOError);
00206 }
00207
00208 is.fatalCheck("operator>>(Istream&, HashTable<T, Key, Hash>&)");
00209
00210 return is;
00211 }
00212
00213
00214 template<class T, class Key, class Hash>
00215 Foam::Ostream& Foam::operator<<
00216 (
00217 Ostream& os,
00218 const HashTable<T, Key, Hash>& L
00219 )
00220 {
00221
00222 os << nl << L.size() << nl << token::BEGIN_LIST << nl;
00223
00224
00225 for
00226 (
00227 typename HashTable<T, Key, Hash>::const_iterator iter = L.cbegin();
00228 iter != L.cend();
00229 ++iter
00230 )
00231 {
00232 os << iter.key() << token::SPACE << iter() << nl;
00233 }
00234
00235
00236 os << token::END_LIST;
00237
00238
00239 os.check("Ostream& operator<<(Ostream&, const HashTable&)");
00240
00241 return os;
00242 }
00243
00244
00245