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

HashTableI.H

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 <OpenFOAM/error.H>
00027 
00028 // * * * * * * * * * * * * * Private Member Classes * * * * * * * * * * * * //
00029 
00030 template<class T, class Key, class Hash>
00031 inline Foam::HashTable<T, Key, Hash>::hashedEntry::hashedEntry
00032 (
00033     const Key& key,
00034     hashedEntry* next,
00035     const T& newEntry
00036 )
00037 :
00038     key_(key),
00039     next_(next),
00040     obj_(newEntry)
00041 {}
00042 
00043 
00044 // * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * * //
00045 
00046 template<class T, class Key, class Hash>
00047 inline Foam::label
00048 Foam::HashTable<T, Key, Hash>::hashKeyIndex(const Key& key) const
00049 {
00050     // size is power of two - this is the modulus
00051     return Hash()(key) & (tableSize_ - 1);
00052 }
00053 
00054 
00055 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
00056 
00057 template<class T, class Key, class Hash>
00058 inline Foam::label Foam::HashTable<T, Key, Hash>::size() const
00059 {
00060     return nElmts_;
00061 }
00062 
00063 
00064 template<class T, class Key, class Hash>
00065 inline bool Foam::HashTable<T, Key, Hash>::empty() const
00066 {
00067     return !nElmts_;
00068 }
00069 
00070 
00071 template<class T, class Key, class Hash>
00072 inline bool Foam::HashTable<T, Key, Hash>::insert
00073 (
00074     const Key& key,
00075     const T& newEntry
00076 )
00077 {
00078     return set(key, newEntry, true);
00079 }
00080 
00081 
00082 template<class T, class Key, class Hash>
00083 inline bool Foam::HashTable<T, Key, Hash>::set
00084 (
00085     const Key& key,
00086     const T& newEntry
00087 )
00088 {
00089     return set(key, newEntry, false);
00090 }
00091 
00092 
00093 template<class T, class Key, class Hash>
00094 inline Foam::Xfer<Foam::HashTable<T, Key, Hash> >
00095 Foam::HashTable<T, Key, Hash>::xfer()
00096 {
00097     return xferMove(*this);
00098 }
00099 
00100 
00101 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
00102 
00103 template<class T, class Key, class Hash>
00104 inline T& Foam::HashTable<T, Key, Hash>::operator[](const Key& key)
00105 {
00106     iterator iter = find(key);
00107 
00108     if (iter == end())
00109     {
00110         FatalErrorIn("HashTable<T, Key, Hash>::operator[](const Key&)")
00111             << key << " not found in table.  Valid entries: "
00112             << toc()
00113             << exit(FatalError);
00114     }
00115 
00116     return *iter;
00117 }
00118 
00119 
00120 template<class T, class Key, class Hash>
00121 inline const T& Foam::HashTable<T, Key, Hash>::operator[](const Key& key) const
00122 {
00123     const_iterator iter = find(key);
00124 
00125     if (iter == cend())
00126     {
00127         FatalErrorIn("HashTable<T, Key, Hash>::operator[](const Key&) const")
00128             << key << " not found in table.  Valid entries: "
00129             << toc()
00130             << exit(FatalError);
00131     }
00132 
00133     return *iter;
00134 }
00135 
00136 
00137 template<class T, class Key, class Hash>
00138 inline T& Foam::HashTable<T, Key, Hash>::operator()(const Key& key)
00139 {
00140     iterator iter = find(key);
00141 
00142     if (iter == end())
00143     {
00144         insert(key, T());
00145         return *find(key);
00146     }
00147     else
00148     {
00149         return *iter;
00150     }
00151 }
00152 
00153 
00154 // * * * * * * * * * * * * * * * * STL iterator  * * * * * * * * * * * * * * //
00155 
00156 template<class T, class Key, class Hash>
00157 inline Foam::HashTable<T, Key, Hash>::iterator::iterator
00158 (
00159     HashTable<T, Key, Hash>& hashTbl,
00160     hashedEntry* elmt,
00161     label hashIndex
00162 )
00163 :
00164     hashTable_(hashTbl),
00165     elmtPtr_(elmt),
00166     hashIndex_(hashIndex)
00167 {}
00168 
00169 
00170 template<class T, class Key, class Hash>
00171 inline void Foam::HashTable<T, Key, Hash>::iterator::operator=
00172 (
00173     const iterator& iter
00174 )
00175 {
00176     elmtPtr_ = iter.elmtPtr_;
00177     hashIndex_ = iter.hashIndex_;
00178 }
00179 
00180 
00181 template<class T, class Key, class Hash>
00182 inline bool Foam::HashTable<T, Key, Hash>::iterator::operator==
00183 (
00184     const iterator& iter
00185 ) const
00186 {
00187     return elmtPtr_ == iter.elmtPtr_;
00188 }
00189 
00190 
00191 template<class T, class Key, class Hash>
00192 inline bool Foam::HashTable<T, Key, Hash>::iterator::operator!=
00193 (
00194     const iterator& iter
00195 ) const
00196 {
00197     return elmtPtr_ != iter.elmtPtr_;
00198 }
00199 
00200 
00201 template<class T, class Key, class Hash>
00202 inline bool Foam::HashTable<T, Key, Hash>::iterator::operator==
00203 (
00204     const const_iterator& iter
00205 ) const
00206 {
00207     return elmtPtr_ == iter.elmtPtr_;
00208 }
00209 
00210 
00211 template<class T, class Key, class Hash>
00212 inline bool Foam::HashTable<T, Key, Hash>::iterator::operator!=
00213 (
00214     const const_iterator& iter
00215 ) const
00216 {
00217     return elmtPtr_ != iter.elmtPtr_;
00218 }
00219 
00220 
00221 template<class T, class Key, class Hash>
00222 inline T&
00223 Foam::HashTable<T, Key, Hash>::iterator::operator*()
00224 {
00225     return elmtPtr_->obj_;
00226 }
00227 
00228 
00229 template<class T, class Key, class Hash>
00230 inline T&
00231 Foam::HashTable<T, Key, Hash>::iterator::operator()()
00232 {
00233     return elmtPtr_->obj_;
00234 }
00235 
00236 
00237 template<class T, class Key, class Hash>
00238 inline const T&
00239 Foam::HashTable<T, Key, Hash>::iterator::operator*() const
00240 {
00241     return elmtPtr_->obj_;
00242 }
00243 
00244 
00245 template<class T, class Key, class Hash>
00246 inline const T&
00247 Foam::HashTable<T, Key, Hash>::iterator::operator()() const
00248 {
00249     return elmtPtr_->obj_;
00250 }
00251 
00252 
00253 template<class T, class Key, class Hash>
00254 inline
00255 typename Foam::HashTable<T, Key, Hash>::iterator&
00256 Foam::HashTable<T, Key, Hash>::iterator::operator++()
00257 {
00258     // Check for special value from erase. (sets hashIndex to -1)
00259     if (hashIndex_ >= 0)
00260     {
00261         // Do we have additional elements on the SLList?
00262         if (elmtPtr_ && elmtPtr_->next_)
00263         {
00264             elmtPtr_ = elmtPtr_->next_;
00265             return *this;
00266         }
00267     }
00268 
00269     // Step to the next table entry
00270     while
00271     (
00272         ++hashIndex_ < hashTable_.tableSize_
00273      && !(elmtPtr_ = hashTable_.table_[hashIndex_])
00274     )
00275     {}
00276 
00277     if (hashIndex_ == hashTable_.tableSize_)
00278     {
00279         // make end iterator
00280         elmtPtr_ = 0;
00281         hashIndex_ = 0;
00282     }
00283     return *this;
00284 }
00285 
00286 
00287 template<class T, class Key, class Hash>
00288 inline typename Foam::HashTable<T, Key, Hash>::iterator
00289 Foam::HashTable<T, Key, Hash>::iterator::operator++
00290 (
00291     int
00292 )
00293 {
00294     iterator tmp = *this;
00295     ++*this;
00296     return tmp;
00297 }
00298 
00299 
00300 template<class T, class Key, class Hash>
00301 inline
00302 const Key& Foam::HashTable<T, Key, Hash>::iterator::key() const
00303 {
00304     return elmtPtr_->key_;
00305 }
00306 
00307 
00308 template<class T, class Key, class Hash>
00309 inline typename Foam::HashTable<T, Key, Hash>::iterator
00310 Foam::HashTable<T, Key, Hash>::begin()
00311 {
00312     label i = 0;
00313 
00314     if (nElmts_)
00315     {
00316         while (table_ && !table_[i] && ++i < tableSize_)
00317         {}
00318     }
00319     else
00320     {
00321         i = tableSize_;
00322     }
00323 
00324     if (i == tableSize_)
00325     {
00326 #       ifdef FULLDEBUG
00327         if (debug)
00328         {
00329             Info<< "HashTable is empty\n";
00330         }
00331 #       endif
00332 
00333         return HashTable<T, Key, Hash>::endIter_;
00334     }
00335     else
00336     {
00337         return iterator(*this, table_[i], i);
00338     }
00339 }
00340 
00341 
00342 template<class T, class Key, class Hash>
00343 inline const typename Foam::HashTable<T, Key, Hash>::iterator&
00344 Foam::HashTable<T, Key, Hash>::end()
00345 {
00346     return HashTable<T, Key, Hash>::endIter_;
00347 }
00348 
00349 
00350 // * * * * * * * * * * * * * * * STL const_iterator * * * * * * * * * * * * * //
00351 
00352 template<class T, class Key, class Hash>
00353 inline Foam::HashTable<T, Key, Hash>::const_iterator::const_iterator
00354 (
00355     const HashTable<T, Key, Hash>& hashTbl,
00356     const hashedEntry* elmt,
00357     label hashIndex
00358 )
00359 :
00360     hashTable_(hashTbl),
00361     elmtPtr_(elmt),
00362     hashIndex_(hashIndex)
00363 {}
00364 
00365 
00366 template<class T, class Key, class Hash>
00367 inline Foam::HashTable<T, Key, Hash>::const_iterator::const_iterator
00368 (
00369     const iterator& iter
00370 )
00371 :
00372     hashTable_(iter.hashTable_),
00373     elmtPtr_(iter.elmtPtr_),
00374     hashIndex_(iter.hashIndex_)
00375 {}
00376 
00377 
00378 template<class T, class Key, class Hash>
00379 inline void Foam::HashTable<T, Key, Hash>::const_iterator::operator=
00380 (
00381     const const_iterator& iter
00382 )
00383 {
00384     elmtPtr_ = iter.elmtPtr_;
00385     hashIndex_ = iter.hashIndex_;
00386 }
00387 
00388 
00389 template<class T, class Key, class Hash>
00390 inline bool Foam::HashTable<T, Key, Hash>::const_iterator::operator==
00391 (
00392     const const_iterator& iter
00393 ) const
00394 {
00395     return elmtPtr_ == iter.elmtPtr_;
00396 }
00397 
00398 
00399 template<class T, class Key, class Hash>
00400 inline bool Foam::HashTable<T, Key, Hash>::const_iterator::operator!=
00401 (
00402     const const_iterator& iter
00403 ) const
00404 {
00405     return elmtPtr_ != iter.elmtPtr_;
00406 }
00407 
00408 
00409 template<class T, class Key, class Hash>
00410 inline bool Foam::HashTable<T, Key, Hash>::const_iterator::operator==
00411 (
00412     const iterator& iter
00413 ) const
00414 {
00415     return elmtPtr_ == iter.elmtPtr_;
00416 }
00417 
00418 
00419 template<class T, class Key, class Hash>
00420 inline bool Foam::HashTable<T, Key, Hash>::const_iterator::operator!=
00421 (
00422     const iterator& iter
00423 ) const
00424 {
00425     return elmtPtr_ != iter.elmtPtr_;
00426 }
00427 
00428 
00429 template<class T, class Key, class Hash>
00430 inline const T&
00431 Foam::HashTable<T, Key, Hash>::const_iterator::operator*() const
00432 {
00433     return elmtPtr_->obj_;
00434 }
00435 
00436 template<class T, class Key, class Hash>
00437 inline const T&
00438 Foam::HashTable<T, Key, Hash>::const_iterator::operator()() const
00439 {
00440     return elmtPtr_->obj_;
00441 }
00442 
00443 
00444 template<class T, class Key, class Hash>
00445 inline
00446 typename Foam::HashTable<T, Key, Hash>::const_iterator&
00447 Foam::HashTable<T, Key, Hash>::const_iterator::operator++()
00448 {
00449     if
00450     (
00451         !(elmtPtr_ = elmtPtr_->next_)
00452      && ++hashIndex_ < hashTable_.tableSize_
00453      && !(elmtPtr_ = hashTable_.table_[hashIndex_])
00454     )
00455     {
00456         while
00457         (
00458             ++hashIndex_ < hashTable_.tableSize_
00459          && !(elmtPtr_ = hashTable_.table_[hashIndex_])
00460         )
00461         {}
00462     }
00463 
00464     return *this;
00465 }
00466 
00467 
00468 template<class T, class Key, class Hash>
00469 inline typename Foam::HashTable<T, Key, Hash>::const_iterator
00470 Foam::HashTable<T, Key, Hash>::const_iterator::operator++
00471 (
00472     int
00473 )
00474 {
00475     const_iterator tmp = *this;
00476     ++*this;
00477     return tmp;
00478 }
00479 
00480 
00481 template<class T, class Key, class Hash>
00482 inline
00483 const Key& Foam::HashTable<T, Key, Hash>::const_iterator::key() const
00484 {
00485     return elmtPtr_->key_;
00486 }
00487 
00488 
00489 template<class T, class Key, class Hash>
00490 inline typename Foam::HashTable<T, Key, Hash>::const_iterator
00491 Foam::HashTable<T, Key, Hash>::cbegin() const
00492 {
00493     label i = 0;
00494 
00495     if (nElmts_)
00496     {
00497         while (table_ && !table_[i] && ++i < tableSize_)
00498         {}
00499     }
00500     else
00501     {
00502         i = tableSize_;
00503     }
00504 
00505     if (i == tableSize_)
00506     {
00507 #       ifdef FULLDEBUG
00508         if (debug)
00509         {
00510             Info<< "HashTable is empty\n";
00511         }
00512 #       endif
00513 
00514         return HashTable<T, Key, Hash>::endConstIter_;
00515     }
00516     else
00517     {
00518         return const_iterator(*this, table_[i], i);
00519     }
00520 }
00521 
00522 
00523 template<class T, class Key, class Hash>
00524 inline const typename Foam::HashTable<T, Key, Hash>::const_iterator&
00525 Foam::HashTable<T, Key, Hash>::cend() const
00526 {
00527     return HashTable<T, Key, Hash>::endConstIter_;
00528 }
00529 
00530 
00531 template<class T, class Key, class Hash>
00532 inline typename Foam::HashTable<T, Key, Hash>::const_iterator
00533 Foam::HashTable<T, Key, Hash>::begin() const
00534 {
00535     return this->cbegin();
00536 }
00537 
00538 
00539 template<class T, class Key, class Hash>
00540 inline const typename Foam::HashTable<T, Key, Hash>::const_iterator&
00541 Foam::HashTable<T, Key, Hash>::end() const
00542 {
00543     return HashTable<T, Key, Hash>::endConstIter_;
00544 }
00545 
00546 
00547 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines