FreeFOAM The Cross-Platform CFD Toolkit
Hosted by SourceForge:
Get FreeFOAM at SourceForge.net.
            Fast, secure and Free Open Source software downloads

HashTableIO.C

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002   =========                 |
00003   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
00004    \\    /   O peration     |
00005     \\  /    A nd           | Copyright (C) 1991-2010 OpenCFD Ltd.
00006      \\/     M anipulation  |
00007 -------------------------------------------------------------------------------
00008 License
00009     This file is part of OpenFOAM.
00010 
00011     OpenFOAM is free software: you can redistribute it and/or modify it
00012     under the terms of the GNU General Public License as published by
00013     the Free Software Foundation, either version 3 of the License, or
00014     (at your option) any later version.
00015 
00016     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
00017     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00019     for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
00023 
00024 \*---------------------------------------------------------------------------*/
00025 
00026 #include "HashTable.H"
00027 #include <OpenFOAM/Istream.H>
00028 #include <OpenFOAM/Ostream.H>
00029 
00030 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
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 // * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
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 // * * * * * * * * * * * * * * * IOstream Operators  * * * * * * * * * * * * //
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     // Anull list
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         // Read beginning of contents
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         // Read end of contents
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     // Write size and start delimiter
00222     os << nl << L.size() << nl << token::BEGIN_LIST << nl;
00223 
00224     // Write contents
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     // Write end delimiter
00236     os << token::END_LIST;
00237 
00238     // Check state of IOstream
00239     os.check("Ostream& operator<<(Ostream&, const HashTable&)");
00240 
00241     return os;
00242 }
00243 
00244 
00245 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines