From c7c9a6e0034bb20fbb411294209add9a088fa826 Mon Sep 17 00:00:00 2001 From: Mark Olesen <Mark.Olesen@Germany> Date: Wed, 4 Nov 2009 09:06:26 +0100 Subject: [PATCH] Activate the reworked HashTable - previous draft version was HashTbl - accidentally still had canonicalSize in templated code --- src/OpenFOAM/Make/files | 3 +- .../HashTables/HashTable/HashTable.C | 256 +++---- .../HashTables/HashTable/HashTable.H | 297 +++++--- .../HashTableCore.C} | 34 +- .../HashTables/HashTable/HashTableI.H | 454 ++++++------ .../HashTables/HashTable/HashTableIO.C | 17 +- .../HashTables/HashTable/HashTableName.C | 33 - .../containers/HashTables/HashTbl/HashTbl.C | 645 ------------------ .../containers/HashTables/HashTbl/HashTbl.H | 563 --------------- .../containers/HashTables/HashTbl/HashTblI.H | 530 -------------- .../containers/HashTables/HashTbl/HashTblIO.C | 249 ------- 11 files changed, 561 insertions(+), 2520 deletions(-) rename src/OpenFOAM/containers/HashTables/{HashTbl/HashTblCore.C => HashTable/HashTableCore.C} (68%) delete mode 100644 src/OpenFOAM/containers/HashTables/HashTable/HashTableName.C delete mode 100644 src/OpenFOAM/containers/HashTables/HashTbl/HashTbl.C delete mode 100644 src/OpenFOAM/containers/HashTables/HashTbl/HashTbl.H delete mode 100644 src/OpenFOAM/containers/HashTables/HashTbl/HashTblI.H delete mode 100644 src/OpenFOAM/containers/HashTables/HashTbl/HashTblIO.C diff --git a/src/OpenFOAM/Make/files b/src/OpenFOAM/Make/files index b4915fc2881..d9a30f3a824 100644 --- a/src/OpenFOAM/Make/files +++ b/src/OpenFOAM/Make/files @@ -61,8 +61,7 @@ $(sha1)/SHA1Digest.C primitives/random/Random.C -containers/HashTables/HashTbl/HashTblCore.C -containers/HashTables/HashTable/HashTableName.C +containers/HashTables/HashTable/HashTableCore.C containers/HashTables/StaticHashTable/StaticHashTableCore.C containers/Lists/SortableList/ParSortableListName.C containers/Lists/PackedList/PackedListName.C diff --git a/src/OpenFOAM/containers/HashTables/HashTable/HashTable.C b/src/OpenFOAM/containers/HashTables/HashTable/HashTable.C index 10bcadc761a..4bc3921682d 100644 --- a/src/OpenFOAM/containers/HashTables/HashTable/HashTable.C +++ b/src/OpenFOAM/containers/HashTables/HashTable/HashTable.C @@ -30,44 +30,15 @@ License #include "HashTable.H" #include "List.H" -// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * // - -template<class T, class Key, class Hash> -Foam::label Foam::HashTable<T, Key, Hash>::canonicalSize(const label size) -{ - if (size < 1) - { - return 0; - } - - // enforce power of two - unsigned int goodSize = size; - - if (goodSize & (goodSize - 1)) - { - // brute-force is fast enough - goodSize = 1; - while (goodSize < unsigned(size)) - { - goodSize <<= 1; - } - } - - return goodSize; -} - - // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // template<class T, class Key, class Hash> Foam::HashTable<T, Key, Hash>::HashTable(const label size) : - HashTableName(), + HashTableCore(), nElmts_(0), - tableSize_(canonicalSize(size)), - table_(NULL), - endIter_(*this, NULL, 0), - endConstIter_(*this, NULL, 0) + tableSize_(HashTableCore::canonicalSize(size)), + table_(NULL) { if (tableSize_) { @@ -84,12 +55,10 @@ Foam::HashTable<T, Key, Hash>::HashTable(const label size) template<class T, class Key, class Hash> Foam::HashTable<T, Key, Hash>::HashTable(const HashTable<T, Key, Hash>& ht) : - HashTableName(), + HashTableCore(), nElmts_(0), tableSize_(ht.tableSize_), - table_(NULL), - endIter_(*this, NULL, 0), - endConstIter_(*this, NULL, 0) + table_(NULL) { if (tableSize_) { @@ -113,12 +82,10 @@ Foam::HashTable<T, Key, Hash>::HashTable const Xfer<HashTable<T, Key, Hash> >& ht ) : - HashTableName(), + HashTableCore(), nElmts_(0), tableSize_(0), - table_(NULL), - endIter_(*this, NULL, 0), - endConstIter_(*this, NULL, 0) + table_(NULL) { transfer(ht()); } @@ -182,7 +149,7 @@ Foam::HashTable<T, Key, Hash>::find { if (key == ep->key_) { - return iterator(*this, ep, hashIdx); + return iterator(this, ep, hashIdx); } } } @@ -195,7 +162,7 @@ Foam::HashTable<T, Key, Hash>::find } # endif - return end(); + return iterator(); } @@ -214,7 +181,7 @@ Foam::HashTable<T, Key, Hash>::find { if (key == ep->key_) { - return const_iterator(*this, ep, hashIdx); + return const_iterator(this, ep, hashIdx); } } } @@ -227,32 +194,32 @@ Foam::HashTable<T, Key, Hash>::find } # endif - return cend(); + return const_iterator(); } template<class T, class Key, class Hash> Foam::List<Key> Foam::HashTable<T, Key, Hash>::toc() const { - List<Key> tofc(nElmts_); - label i = 0; + List<Key> keys(nElmts_); + label keyI = 0; for (const_iterator iter = cbegin(); iter != cend(); ++iter) { - tofc[i++] = iter.key(); + keys[keyI++] = iter.key(); } - return tofc; + return keys; } template<class T, class Key, class Hash> Foam::List<Key> Foam::HashTable<T, Key, Hash>::sortedToc() const { - List<Key> sortedList = this->toc(); - sort(sortedList); + List<Key> sortedLst = this->toc(); + sort(sortedLst); - return sortedList; + return sortedLst; } @@ -290,7 +257,7 @@ bool Foam::HashTable<T, Key, Hash>::set table_[hashIdx] = new hashedEntry(key, table_[hashIdx], newEntry); nElmts_++; - if (double(nElmts_)/tableSize_ > 0.8) + if (double(nElmts_)/tableSize_ > 0.8 && tableSize_ < maxTableSize) { # ifdef FULLDEBUG if (debug) @@ -342,18 +309,22 @@ bool Foam::HashTable<T, Key, Hash>::set template<class T, class Key, class Hash> -bool Foam::HashTable<T, Key, Hash>::erase(const iterator& cit) +bool Foam::HashTable<T, Key, Hash>::iteratorBase::erase() { - if (cit.elmtPtr_) // note: endIter_ also has 0 elmtPtr_ + // note: entryPtr_ is NULL for end(), so this catches that too + if (entryPtr_) { - iterator& it = const_cast<iterator&>(cit); - - // Search element before elmtPtr_ + // Search element before entryPtr_ hashedEntry* prev = 0; - for (hashedEntry* ep = table_[it.hashIndex_]; ep; ep = ep->next_) + for + ( + hashedEntry* ep = hashTable_->table_[hashIndex_]; + ep; + ep = ep->next_ + ) { - if (ep == it.elmtPtr_) + if (ep == entryPtr_) { break; } @@ -362,98 +333,76 @@ bool Foam::HashTable<T, Key, Hash>::erase(const iterator& cit) if (prev) { - // Have element before elmtPtr - prev->next_ = it.elmtPtr_->next_; - delete it.elmtPtr_; - it.elmtPtr_ = prev; + // has an element before entryPtr - reposition to there + prev->next_ = entryPtr_->next_; + delete entryPtr_; + entryPtr_ = prev; } else { - // elmtPtr is first element on SLList - table_[it.hashIndex_] = it.elmtPtr_->next_; - delete it.elmtPtr_; - - // Search back for previous non-zero table entry - while (--it.hashIndex_ >= 0 && !table_[it.hashIndex_]) - {} - - if (it.hashIndex_ >= 0) - { - // In table entry search for last element - it.elmtPtr_ = table_[it.hashIndex_]; - - while (it.elmtPtr_ && it.elmtPtr_->next_) - { - it.elmtPtr_ = it.elmtPtr_->next_; - } - } - else - { - // No previous found. Mark with special value which is - // - not end()/cend() - // - handled by operator++ - it.elmtPtr_ = reinterpret_cast<hashedEntry*>(this); - it.hashIndex_ = -1; - } + // entryPtr was first element on SLList + hashTable_->table_[hashIndex_] = entryPtr_->next_; + delete entryPtr_; + + // assign any non-NULL pointer value so it doesn't look + // like end()/cend() + entryPtr_ = reinterpret_cast<hashedEntry*>(this); + + // Mark with special hashIndex value to signal it has been rewound. + // The next increment will bring it back to the present location. + // + // From the current position 'curPos', we wish to continue at + // prevPos='curPos-1', which we mark as markPos='-curPos-1'. + // The negative lets us notice it is special, the extra '-1' + // is needed to avoid ambiguity for position '0'. + // To retrieve prevPos, we would later use '-(markPos+1) - 1' + hashIndex_ = -hashIndex_ - 1; } - nElmts_--; - -# ifdef FULLDEBUG - if (debug) - { - Info<< "HashTable<T, Key, Hash>::erase(iterator&) : " - << "hashedEntry " << it.elmtPtr_->key_ << " removed.\n"; - } -# endif + hashTable_->nElmts_--; return true; } else { -# ifdef FULLDEBUG - if (debug) - { - Info<< "HashTable<T, Key, Hash>::erase(iterator&) : " - << "cannot remove hashedEntry from hash table\n"; - } -# endif - return false; } } + +// NOTE: +// We use (const iterator&) here, but manipulate its contents anyhow. +// The parameter should be (iterator&), but then the compiler doesn't find +// it correctly and tries to call as (iterator) instead. +// template<class T, class Key, class Hash> -bool Foam::HashTable<T, Key, Hash>::erase(const Key& key) +bool Foam::HashTable<T, Key, Hash>::erase(const iterator& iter) { - iterator fnd = find(key); + // adjust iterator after erase + return const_cast<iterator&>(iter).erase(); +} - if (fnd != end()) - { - return erase(fnd); - } - else - { - return false; - } + +template<class T, class Key, class Hash> +bool Foam::HashTable<T, Key, Hash>::erase(const Key& key) +{ + return erase(find(key)); } template<class T, class Key, class Hash> Foam::label Foam::HashTable<T, Key, Hash>::erase(const UList<Key>& keys) { + const label nTotal = nElmts_; label count = 0; - // Remove listed keys from this table - if (this->size()) + // Remove listed keys from this table - terminates early if possible + for (label keyI = 0; count < nTotal && keyI < keys.size(); ++keyI) { - forAll(keys, keyI) + if (erase(keys[keyI])) { - if (erase(keys[keyI])) - { - count++; - } + count++; } } @@ -462,24 +411,21 @@ Foam::label Foam::HashTable<T, Key, Hash>::erase(const UList<Key>& keys) template<class T, class Key, class Hash> -template<class AnyType> +template<class AnyType, class AnyHash> Foam::label Foam::HashTable<T, Key, Hash>::erase ( - const HashTable<AnyType, Key, Hash>& rhs + const HashTable<AnyType, Key, AnyHash>& rhs ) { label count = 0; - // Remove rhs elements from this table - if (this->size()) + // Remove rhs keys from this table - terminates early if possible + // Could optimize depending on which hash is smaller ... + for (iterator iter = begin(); iter != end(); ++iter) { - // NOTE: could further optimize depending on which hash is smaller - for (iterator iter = begin(); iter != end(); ++iter) + if (rhs.found(iter.key()) && erase(iter)) { - if (rhs.found(iter.key()) && erase(iter)) - { - count++; - } + count++; } } @@ -490,7 +436,7 @@ Foam::label Foam::HashTable<T, Key, Hash>::erase template<class T, class Key, class Hash> void Foam::HashTable<T, Key, Hash>::resize(const label sz) { - label newSize = canonicalSize(sz); + label newSize = HashTableCore::canonicalSize(sz); if (newSize == tableSize_) { @@ -505,22 +451,22 @@ void Foam::HashTable<T, Key, Hash>::resize(const label sz) return; } - HashTable<T, Key, Hash>* newTable = new HashTable<T, Key, Hash>(newSize); + HashTable<T, Key, Hash>* tmpTable = new HashTable<T, Key, Hash>(newSize); for (const_iterator iter = cbegin(); iter != cend(); ++iter) { - newTable->insert(iter.key(), *iter); + tmpTable->insert(iter.key(), *iter); } - label oldTableSize = tableSize_; - tableSize_ = newTable->tableSize_; - newTable->tableSize_ = oldTableSize; + label oldSize = tableSize_; + tableSize_ = tmpTable->tableSize_; + tmpTable->tableSize_ = oldSize; hashedEntry** oldTable = table_; - table_ = newTable->table_; - newTable->table_ = oldTable; + table_ = tmpTable->table_; + tmpTable->table_ = oldTable; - delete newTable; + delete tmpTable; } @@ -556,6 +502,19 @@ void Foam::HashTable<T, Key, Hash>::clearStorage() } +template<class T, class Key, class Hash> +void Foam::HashTable<T, Key, Hash>::shrink() +{ + const label newSize = HashTableCore::canonicalSize(nElmts_); + + if (newSize < tableSize_) + { + // avoid having the table disappear on us + resize(newSize ? newSize : 2); + } +} + + template<class T, class Key, class Hash> void Foam::HashTable<T, Key, Hash>::transfer(HashTable<T, Key, Hash>& ht) { @@ -619,18 +578,12 @@ bool Foam::HashTable<T, Key, Hash>::operator== const HashTable<T, Key, Hash>& rhs ) const { - // Are all my elements in rhs? - for (const_iterator iter = cbegin(); iter != cend(); ++iter) + // sizes (number of keys) must match + if (size() != rhs.size()) { - const_iterator fnd = rhs.find(iter.key()); - - if (fnd == rhs.cend() || fnd() != iter()) - { - return false; - } + return false; } - // Are all rhs elements in me? for (const_iterator iter = rhs.cbegin(); iter != rhs.cend(); ++iter) { const_iterator fnd = find(iter.key()); @@ -640,6 +593,7 @@ bool Foam::HashTable<T, Key, Hash>::operator== return false; } } + return true; } diff --git a/src/OpenFOAM/containers/HashTables/HashTable/HashTable.H b/src/OpenFOAM/containers/HashTables/HashTable/HashTable.H index 666b93ebec8..a945859880a 100644 --- a/src/OpenFOAM/containers/HashTables/HashTable/HashTable.H +++ b/src/OpenFOAM/containers/HashTables/HashTable/HashTable.H @@ -71,23 +71,60 @@ Ostream& operator<<(Ostream&, const HashTable<T, Key, Hash>&); /*---------------------------------------------------------------------------*\ - Class HashTableName Declaration + Class HashTableCore Declaration \*---------------------------------------------------------------------------*/ -TemplateName(HashTable); +//- Template-invariant bits for HashTable +struct HashTableCore +{ + //- Return a canonical (power-of-two) size + static label canonicalSize(const label); + + //- Maximum allowable table size + static const label maxTableSize; + + //- Construct null + HashTableCore() + {} + + //- Define template name and debug + ClassName("HashTable"); + + //- A zero-sized end iterator + struct iteratorEnd + { + //- Construct null + iteratorEnd() + {} + }; + + //- iteratorEnd set to beyond the end of any HashTable + inline static iteratorEnd cend() + { + return iteratorEnd(); + } + + //- iteratorEnd set to beyond the end of any HashTable + inline static iteratorEnd end() + { + return iteratorEnd(); + } + +}; /*---------------------------------------------------------------------------*\ - Class HashTable Declaration + Class HashTable Declaration \*---------------------------------------------------------------------------*/ template<class T, class Key=word, class Hash=string::hash> class HashTable : - public HashTableName + public HashTableCore { // Private data type for table entries + //- Structure to hold a hashed entry with SLList for collisions struct hashedEntry { //- The lookup key @@ -99,18 +136,15 @@ class HashTable //- The data object T obj_; - //- Constructors + //- Construct from key, next pointer and object + inline hashedEntry(const Key&, hashedEntry* next, const T&); - //- Construct given key, next pointer and object - inline hashedEntry - ( - const Key&, - hashedEntry* next, - const T& newEntry - ); + private: + //- Disallow default bitwise copy construct + hashedEntry(const hashedEntry&); - //- Dissallow construction as copy - hashedEntry(const hashedEntry&); + //- Disallow default bitwise assignment + void operator=(const hashedEntry&); }; @@ -119,7 +153,7 @@ class HashTable //- The current number of elements in table label nElmts_; - //- Number of primary entries allocated in table (not necessarily used) + //- Number of primary entries allocated in table label tableSize_; //- The table of primary entries @@ -140,17 +174,23 @@ class HashTable public: + // Forward declaration of iterators + + class iteratorBase; + class iterator; + class const_iterator; + //- Declare friendship with the HashPtrTable class template<class T2, class Key2, class Hash2> friend class HashPtrTable; + //- Declare friendship with the iteratorBase + friend class iteratorBase; - // Forward declaration of STL iterators - - class iterator; + //- Declare friendship with the iterator friend class iterator; - class const_iterator; + //- Declare friendship with the const_iterator friend class const_iterator; @@ -178,7 +218,10 @@ public: // Access - //- Return number of elements in table. + //- The size of the underlying table + inline label capacity() const; + + //- Return number of elements in table inline label size() const; //- Return true if the hash table is empty @@ -212,10 +255,11 @@ public: //- Assign a new hashedEntry, overwriting existing entries inline bool set(const Key&, const T& newElmt); - //- Erase an hashedEntry specified by given iterator + //- Erase a hashedEntry specified by given iterator + // This invalidates the iterator until the next operator++ bool erase(const iterator&); - //- Erase an hashedEntry specified by given key if in table + //- Erase a hashedEntry specified by the given key bool erase(const Key&); //- Remove entries given by the listed keys from this HashTable @@ -224,10 +268,10 @@ public: //- Remove entries given by the given keys from this HashTable // Return the number of elements removed. - // The parameter HashTable needs the same type of keys, but - // but the type of values held is arbitrary. - template<class AnyType> - label erase(const HashTable<AnyType, Key, Hash>&); + // The parameter HashTable needs the same type of key, but the + // type of values held and the hashing function are arbitrary. + template<class AnyType, class AnyHash> + label erase(const HashTable<AnyType, Key, AnyHash>&); //- Resize the hash table for efficiency void resize(const label newSize); @@ -239,31 +283,33 @@ public: // Equivalent to clear() followed by resize(0) void clearStorage(); + //- Shrink the allocated table to approx. twice number of elements + void shrink(); + //- Transfer the contents of the argument table into this table // and annull the argument table. void transfer(HashTable<T, Key, Hash>&); //- Transfer contents to the Xfer container - inline Xfer<HashTable<T, Key, Hash> > xfer(); + inline Xfer< HashTable<T, Key, Hash> > xfer(); // Member Operators - //- Find and return an hashedEntry + //- Find and return a hashedEntry inline T& operator[](const Key&); - //- Find and return an hashedEntry + //- Find and return a hashedEntry inline const T& operator[](const Key&) const; - //- Find and return an hashedEntry, create it null if not present. + //- Find and return a hashedEntry, create it null if not present inline T& operator()(const Key&); //- Assignment void operator=(const HashTable<T, Key, Hash>&); - //- Equality. Two hash tables are equal if all contents of first are - // also in second and vice versa. So does not depend on table size or - // order! + //- Equality. Hash tables are equal if the keys and values are equal. + // Independent of table storage size and table order. bool operator==(const HashTable<T, Key, Hash>&) const; //- The opposite of the equality operation. Takes linear time. @@ -289,134 +335,193 @@ public: typedef label size_type; - // STL iterator + // Iterators and helpers - //- An STL-conforming iterator - class iterator + //- The iterator base for HashTable + // Note: data and functions are protected, to allow reuse by iterator + // and prevent most external usage. + // iterator and const_iterator have the same size, allowing + // us to reinterpret_cast between them (if desired) + class iteratorBase { - friend class HashTable; - friend class const_iterator; + // Private Data - // Private data - - //- Reference to the HashTable this is an iterator for - HashTable<T, Key, Hash>& hashTable_; + //- Pointer to the HashTable for which this is an iterator + // This also lets us use the default bitwise copy/assignment + HashTable<T, Key, Hash>* hashTable_; //- Current element - hashedEntry* elmtPtr_; + hashedEntry* entryPtr_; //- Current hash index label hashIndex_; - public: + protected: + + // Protected Member Functions // Constructors + //- Construct null - equivalent to an 'end' position + inline iteratorBase(); + + //- Construct from hash table, moving to its 'begin' position + inline explicit iteratorBase + ( + const HashTable<T, Key, Hash>* curHashTable + ); + //- Construct from hash table, element and hash index - inline iterator + inline explicit iteratorBase ( - HashTable<T, Key, Hash>& curHashTable, - hashedEntry* elmt, - label hashIndex + const HashTable<T, Key, Hash>* curHashTable, + const hashedEntry* elmt, + const label hashIndex ); + + //- Increment to the next position + inline void increment(); + + //- Erase the HashTable element at the current position + bool erase(); + + //- Return non-const access to referenced object + inline T& object(); + + //- Return const access to referenced object + inline const T& cobject() const; + + public: + // Member operators - inline void operator=(const iterator&); + // Access + + //- Return the Key corresponding to the iterator + inline const Key& key() const; + + //- Compare hashedEntry element pointers + inline bool operator==(const iteratorBase&) const; + inline bool operator!=(const iteratorBase&) const; + + //- Compare hashedEntry to iteratorEnd pointers + inline bool operator==(const iteratorEnd& unused) const; + inline bool operator!=(const iteratorEnd& unused) const; + }; + + + //- An STL-conforming iterator + class iterator + : + public iteratorBase + { + friend class HashTable; + + // Private Member Functions + + //- Construct from hash table, moving to its 'begin' position + inline explicit iterator + ( + HashTable<T, Key, Hash>* curHashTable + ); + + //- Construct from hash table, element and hash index + inline explicit iterator + ( + HashTable<T, Key, Hash>* curHashTable, + hashedEntry* elmt, + const label hashIndex + ); + + public: + + // Constructors + + //- Construct null (end iterator) + inline iterator(); + + //- Construct end iterator + inline iterator(const iteratorEnd& unused); + + // Member operators - inline bool operator==(const iterator&) const; - inline bool operator!=(const iterator&) const; + //- Conversion to a const_iterator + inline operator const_iterator() const; - inline bool operator==(const const_iterator&) const; - inline bool operator!=(const const_iterator&) const; + // Access + //- Return referenced hash value inline T& operator*(); inline T& operator()(); + //- Return referenced hash value inline const T& operator*() const; inline const T& operator()() const; inline iterator& operator++(); inline iterator operator++(int); - - inline const Key& key() const; }; - //- iterator set to the begining of the HashTable inline iterator begin(); - //- iterator set to beyond the end of the HashTable - inline const iterator& end(); - // STL const_iterator //- An STL-conforming const_iterator class const_iterator + : + public iteratorBase { - friend class iterator; - - // Private data - - //- Reference to the HashTable this is an iterator for - const HashTable<T, Key, Hash>& hashTable_; - - //- Current element - const hashedEntry* elmtPtr_; - - //- Current hash index - label hashIndex_; - + friend class HashTable; - public: + // Private Member Functions - // Constructors + //- Construct from hash table, moving to its 'begin' position + inline explicit const_iterator + ( + const HashTable<T, Key, Hash>* curHashTable + ); //- Construct from hash table, element and hash index - inline const_iterator + inline explicit const_iterator ( - const HashTable<T, Key, Hash>& curHashTable, + const HashTable<T, Key, Hash>* curHashTable, const hashedEntry* elmt, - label hashIndex + const label hashIndex ); - //- Construct from the non-const iterator - inline const_iterator(const iterator&); + public: + // Constructors - // Member operators + //- Construct null (end iterator) + inline const_iterator(); - inline void operator=(const const_iterator&); + //- Construct end iterator + inline const_iterator(const iteratorEnd& unused); - inline bool operator==(const const_iterator&) const; - inline bool operator!=(const const_iterator&) const; + // Member operators - inline bool operator==(const iterator&) const; - inline bool operator!=(const iterator&) const; + // Access + //- Return referenced hash value inline const T& operator*() const; inline const T& operator()() const; inline const_iterator& operator++(); inline const_iterator operator++(int); - inline const Key& key() const; }; //- const_iterator set to the beginning of the HashTable inline const_iterator cbegin() const; - //- const_iterator set to beyond the end of the HashTable - inline const const_iterator& cend() const; - //- const_iterator set to the beginning of the HashTable inline const_iterator begin() const; - //- const_iterator set to beyond the end of the HashTable - inline const const_iterator& end() const; - // IOstream Operator @@ -432,14 +537,6 @@ public: const HashTable<T, Key, Hash>& ); - -private: - - //- iterator returned by end() - iterator endIter_; - - //- const_iterator returned by end() - const_iterator endConstIter_; }; diff --git a/src/OpenFOAM/containers/HashTables/HashTbl/HashTblCore.C b/src/OpenFOAM/containers/HashTables/HashTable/HashTableCore.C similarity index 68% rename from src/OpenFOAM/containers/HashTables/HashTbl/HashTblCore.C rename to src/OpenFOAM/containers/HashTables/HashTable/HashTableCore.C index 3f1d4d3cc66..1162ad5c1d7 100644 --- a/src/OpenFOAM/containers/HashTables/HashTbl/HashTblCore.C +++ b/src/OpenFOAM/containers/HashTables/HashTable/HashTableCore.C @@ -24,18 +24,44 @@ License \*---------------------------------------------------------------------------*/ -#include "HashTbl.H" +#include "HashTable.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // -defineTypeNameAndDebug(Foam::HashTblCore, 0); +defineTypeNameAndDebug(Foam::HashTableCore, 0); -const Foam::label Foam::HashTblCore::maxTableSize +const Foam::label Foam::HashTableCore::maxTableSize ( - Foam::HashTblCore::canonicalSize + Foam::HashTableCore::canonicalSize ( Foam::labelMax/2 ) ); +// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // + +Foam::label Foam::HashTableCore::canonicalSize(const label size) +{ + if (size < 1) + { + return 0; + } + + // enforce power of two + unsigned int goodSize = size; + + if (goodSize & (goodSize - 1)) + { + // brute-force is fast enough + goodSize = 1; + while (goodSize < unsigned(size)) + { + goodSize <<= 1; + } + } + + return goodSize; +} + + // ************************************************************************* // diff --git a/src/OpenFOAM/containers/HashTables/HashTable/HashTableI.H b/src/OpenFOAM/containers/HashTables/HashTable/HashTableI.H index 5212d57f516..610f3ccf2fd 100644 --- a/src/OpenFOAM/containers/HashTables/HashTable/HashTableI.H +++ b/src/OpenFOAM/containers/HashTables/HashTable/HashTableI.H @@ -33,12 +33,12 @@ inline Foam::HashTable<T, Key, Hash>::hashedEntry::hashedEntry ( const Key& key, hashedEntry* next, - const T& newEntry + const T& obj ) : key_(key), next_(next), - obj_(newEntry) + obj_(obj) {} @@ -55,6 +55,13 @@ Foam::HashTable<T, Key, Hash>::hashKeyIndex(const Key& key) const // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // +template<class T, class Key, class Hash> +inline Foam::label Foam::HashTable<T, Key, Hash>::capacity() const +{ + return tableSize_; +} + + template<class T, class Key, class Hash> inline Foam::label Foam::HashTable<T, Key, Hash>::size() const { @@ -152,70 +159,218 @@ inline T& Foam::HashTable<T, Key, Hash>::operator()(const Key& key) } -// * * * * * * * * * * * * * * * * STL iterator * * * * * * * * * * * * * * // +// * * * * * * * * * * * * * * * iterator base * * * * * * * * * * * * * * * // template<class T, class Key, class Hash> -inline Foam::HashTable<T, Key, Hash>::iterator::iterator +inline Foam::HashTable<T, Key, Hash>::iteratorBase::iteratorBase() +: + hashTable_(0), + entryPtr_(0), + hashIndex_(0) +{} + + +template<class T, class Key, class Hash> +inline Foam::HashTable<T, Key, Hash>::iteratorBase::iteratorBase ( - HashTable<T, Key, Hash>& hashTbl, - hashedEntry* elmt, - label hashIndex + const HashTable<T, Key, Hash>* hashTbl ) : - hashTable_(hashTbl), - elmtPtr_(elmt), - hashIndex_(hashIndex) -{} + hashTable_(const_cast<HashTable<T, Key, Hash>*>(hashTbl)), + entryPtr_(0), + hashIndex_(0) +{ + if (hashTable_->nElmts_ && hashTable_->table_) + { + // find first non-NULL table entry + while + ( + !(entryPtr_ = hashTable_->table_[hashIndex_]) + && ++hashIndex_ < hashTable_->tableSize_ + ) + {} + + if (hashIndex_ >= hashTable_->tableSize_) + { + // make into an end iterator + entryPtr_ = 0; + hashIndex_ = 0; + } + } +} template<class T, class Key, class Hash> -inline void Foam::HashTable<T, Key, Hash>::iterator::operator= +inline Foam::HashTable<T, Key, Hash>::iteratorBase::iteratorBase ( - const iterator& iter + const HashTable<T, Key, Hash>* hashTbl, + const hashedEntry* elmt, + const label hashIndex ) +: + hashTable_(const_cast<HashTable<T, Key, Hash>*>(hashTbl)), + entryPtr_(const_cast<hashedEntry*>(elmt)), + hashIndex_(hashIndex) +{} + + +template<class T, class Key, class Hash> +inline void +Foam::HashTable<T, Key, Hash>::iteratorBase::increment() +{ + // A negative index is a special value from erase + if (hashIndex_ < 0) + { + // the markPos='-curPos-1', but we wish to continue at 'curPos-1' + // thus use '-(markPos+1) -1' + hashIndex_ = -(hashIndex_+1) - 1; + } + else if (entryPtr_) + { + if (entryPtr_->next_) + { + // Move to next element on the SLList + entryPtr_ = entryPtr_->next_; + return; + } + } + // else + // { + // // if we reach here (entryPtr_ is NULL) it is already at the end() + // // we should probably stop + // } + + + // Step to the next table entry + while + ( + ++hashIndex_ < hashTable_->tableSize_ + && !(entryPtr_ = hashTable_->table_[hashIndex_]) + ) + {} + + if (hashIndex_ >= hashTable_->tableSize_) + { + // make into an end iterator + entryPtr_ = 0; + hashIndex_ = 0; + } +} + + +template<class T, class Key, class Hash> +inline +const Key& Foam::HashTable<T, Key, Hash>::iteratorBase::key() const +{ + return entryPtr_->key_; +} + + +template<class T, class Key, class Hash> +inline T& +Foam::HashTable<T, Key, Hash>::iteratorBase::object() { - elmtPtr_ = iter.elmtPtr_; - hashIndex_ = iter.hashIndex_; + return entryPtr_->obj_; } template<class T, class Key, class Hash> -inline bool Foam::HashTable<T, Key, Hash>::iterator::operator== +inline const T& +Foam::HashTable<T, Key, Hash>::iteratorBase::cobject() const +{ + return entryPtr_->obj_; +} + + +template<class T, class Key, class Hash> +inline bool Foam::HashTable<T, Key, Hash>::iteratorBase::operator== ( - const iterator& iter + const iteratorBase& iter ) const { - return elmtPtr_ == iter.elmtPtr_; + return entryPtr_ == iter.entryPtr_; } template<class T, class Key, class Hash> -inline bool Foam::HashTable<T, Key, Hash>::iterator::operator!= +inline bool Foam::HashTable<T, Key, Hash>::iteratorBase::operator!= ( - const iterator& iter + const iteratorBase& iter ) const { - return elmtPtr_ != iter.elmtPtr_; + return entryPtr_ != iter.entryPtr_; } template<class T, class Key, class Hash> -inline bool Foam::HashTable<T, Key, Hash>::iterator::operator== +inline bool Foam::HashTable<T, Key, Hash>::iteratorBase::operator== ( - const const_iterator& iter + const iteratorEnd& ) const { - return elmtPtr_ == iter.elmtPtr_; + return !entryPtr_; } template<class T, class Key, class Hash> -inline bool Foam::HashTable<T, Key, Hash>::iterator::operator!= +inline bool Foam::HashTable<T, Key, Hash>::iteratorBase::operator!= ( - const const_iterator& iter + const iteratorEnd& ) const { - return elmtPtr_ != iter.elmtPtr_; + return entryPtr_; +} + + +// * * * * * * * * * * * * * * * * STL iterator * * * * * * * * * * * * * * // + +template<class T, class Key, class Hash> +inline Foam::HashTable<T, Key, Hash>::iterator::iterator() +: + iteratorBase() +{} + + +template<class T, class Key, class Hash> +inline Foam::HashTable<T, Key, Hash>::iterator::iterator +( + const iteratorEnd& +) +: + iteratorBase() +{} + + +template<class T, class Key, class Hash> +inline Foam::HashTable<T, Key, Hash>::iterator::iterator +( + HashTable<T, Key, Hash>* hashTbl +) +: + iteratorBase(hashTbl) +{} + + +template<class T, class Key, class Hash> +inline Foam::HashTable<T, Key, Hash>::iterator::iterator +( + HashTable<T, Key, Hash>* hashTbl, + hashedEntry* elmt, + const label hashIndex +) +: + iteratorBase(hashTbl, elmt, hashIndex) +{} + + +template<class T, class Key, class Hash> +inline Foam::HashTable<T, Key, Hash>::iterator::operator +typename Foam::HashTable<T, Key, Hash>::const_iterator() const +{ + return *reinterpret_cast + < + const typename Foam::HashTable<T, Key, Hash>::const_iterator* + >(this); } @@ -223,7 +378,7 @@ template<class T, class Key, class Hash> inline T& Foam::HashTable<T, Key, Hash>::iterator::operator*() { - return elmtPtr_->obj_; + return this->object(); } @@ -231,7 +386,7 @@ template<class T, class Key, class Hash> inline T& Foam::HashTable<T, Key, Hash>::iterator::operator()() { - return elmtPtr_->obj_; + return this->object(); } @@ -239,7 +394,7 @@ template<class T, class Key, class Hash> inline const T& Foam::HashTable<T, Key, Hash>::iterator::operator*() const { - return elmtPtr_->obj_; + return this->cobject(); } @@ -247,7 +402,7 @@ template<class T, class Key, class Hash> inline const T& Foam::HashTable<T, Key, Hash>::iterator::operator()() const { - return elmtPtr_->obj_; + return this->cobject(); } @@ -256,53 +411,18 @@ inline typename Foam::HashTable<T, Key, Hash>::iterator& Foam::HashTable<T, Key, Hash>::iterator::operator++() { - // Check for special value from erase. (sets hashIndex to -1) - if (hashIndex_ >= 0) - { - // Do we have additional elements on the SLList? - if (elmtPtr_ && elmtPtr_->next_) - { - elmtPtr_ = elmtPtr_->next_; - return *this; - } - } - - // Step to the next table entry - while - ( - ++hashIndex_ < hashTable_.tableSize_ - && !(elmtPtr_ = hashTable_.table_[hashIndex_]) - ) - {} - - if (hashIndex_ == hashTable_.tableSize_) - { - // make end iterator - elmtPtr_ = 0; - hashIndex_ = 0; - } + this->increment(); return *this; } template<class T, class Key, class Hash> inline typename Foam::HashTable<T, Key, Hash>::iterator -Foam::HashTable<T, Key, Hash>::iterator::operator++ -( - int -) +Foam::HashTable<T, Key, Hash>::iterator::operator++(int) { - iterator tmp = *this; - ++*this; - return tmp; -} - - -template<class T, class Key, class Hash> -inline -const Key& Foam::HashTable<T, Key, Hash>::iterator::key() const -{ - return elmtPtr_->key_; + iterator old = *this; + this->increment(); + return old; } @@ -310,135 +430,64 @@ template<class T, class Key, class Hash> inline typename Foam::HashTable<T, Key, Hash>::iterator Foam::HashTable<T, Key, Hash>::begin() { - label i = 0; - - if (nElmts_) - { - while (table_ && !table_[i] && ++i < tableSize_) - {} - } - else - { - i = tableSize_; - } - - if (i == tableSize_) - { -# ifdef FULLDEBUG - if (debug) - { - Info<< "HashTable is empty\n"; - } -# endif - - return HashTable<T, Key, Hash>::endIter_; - } - else - { - return iterator(*this, table_[i], i); - } -} - - -template<class T, class Key, class Hash> -inline const typename Foam::HashTable<T, Key, Hash>::iterator& -Foam::HashTable<T, Key, Hash>::end() -{ - return HashTable<T, Key, Hash>::endIter_; + return iterator(this); } // * * * * * * * * * * * * * * * STL const_iterator * * * * * * * * * * * * * // template<class T, class Key, class Hash> -inline Foam::HashTable<T, Key, Hash>::const_iterator::const_iterator -( - const HashTable<T, Key, Hash>& hashTbl, - const hashedEntry* elmt, - label hashIndex -) +inline Foam::HashTable<T, Key, Hash>::const_iterator::const_iterator() : - hashTable_(hashTbl), - elmtPtr_(elmt), - hashIndex_(hashIndex) + iteratorBase() {} template<class T, class Key, class Hash> inline Foam::HashTable<T, Key, Hash>::const_iterator::const_iterator ( - const iterator& iter + const iteratorEnd& ) : - hashTable_(iter.hashTable_), - elmtPtr_(iter.elmtPtr_), - hashIndex_(iter.hashIndex_) + iteratorBase() {} template<class T, class Key, class Hash> -inline void Foam::HashTable<T, Key, Hash>::const_iterator::operator= +inline Foam::HashTable<T, Key, Hash>::const_iterator::const_iterator ( - const const_iterator& iter + const HashTable<T, Key, Hash>* hashTbl ) -{ - elmtPtr_ = iter.elmtPtr_; - hashIndex_ = iter.hashIndex_; -} - - -template<class T, class Key, class Hash> -inline bool Foam::HashTable<T, Key, Hash>::const_iterator::operator== -( - const const_iterator& iter -) const -{ - return elmtPtr_ == iter.elmtPtr_; -} - - -template<class T, class Key, class Hash> -inline bool Foam::HashTable<T, Key, Hash>::const_iterator::operator!= -( - const const_iterator& iter -) const -{ - return elmtPtr_ != iter.elmtPtr_; -} - - -template<class T, class Key, class Hash> -inline bool Foam::HashTable<T, Key, Hash>::const_iterator::operator== -( - const iterator& iter -) const -{ - return elmtPtr_ == iter.elmtPtr_; -} +: + iteratorBase(hashTbl) +{} template<class T, class Key, class Hash> -inline bool Foam::HashTable<T, Key, Hash>::const_iterator::operator!= +inline Foam::HashTable<T, Key, Hash>::const_iterator::const_iterator ( - const iterator& iter -) const -{ - return elmtPtr_ != iter.elmtPtr_; -} + const HashTable<T, Key, Hash>* hashTbl, + const hashedEntry* elmt, + const label hashIndex +) +: + iteratorBase(hashTbl, elmt, hashIndex) +{} template<class T, class Key, class Hash> inline const T& Foam::HashTable<T, Key, Hash>::const_iterator::operator*() const { - return elmtPtr_->obj_; + return this->cobject(); } + template<class T, class Key, class Hash> inline const T& Foam::HashTable<T, Key, Hash>::const_iterator::operator()() const { - return elmtPtr_->obj_; + return this->cobject(); } @@ -447,43 +496,18 @@ inline typename Foam::HashTable<T, Key, Hash>::const_iterator& Foam::HashTable<T, Key, Hash>::const_iterator::operator++() { - if - ( - !(elmtPtr_ = elmtPtr_->next_) - && ++hashIndex_ < hashTable_.tableSize_ - && !(elmtPtr_ = hashTable_.table_[hashIndex_]) - ) - { - while - ( - ++hashIndex_ < hashTable_.tableSize_ - && !(elmtPtr_ = hashTable_.table_[hashIndex_]) - ) - {} - } - + this->increment(); return *this; } template<class T, class Key, class Hash> inline typename Foam::HashTable<T, Key, Hash>::const_iterator -Foam::HashTable<T, Key, Hash>::const_iterator::operator++ -( - int -) -{ - const_iterator tmp = *this; - ++*this; - return tmp; -} - - -template<class T, class Key, class Hash> -inline -const Key& Foam::HashTable<T, Key, Hash>::const_iterator::key() const +Foam::HashTable<T, Key, Hash>::const_iterator::operator++(int) { - return elmtPtr_->key_; + const_iterator old = *this; + this->increment(); + return old; } @@ -491,41 +515,7 @@ template<class T, class Key, class Hash> inline typename Foam::HashTable<T, Key, Hash>::const_iterator Foam::HashTable<T, Key, Hash>::cbegin() const { - label i = 0; - - if (nElmts_) - { - while (table_ && !table_[i] && ++i < tableSize_) - {} - } - else - { - i = tableSize_; - } - - if (i == tableSize_) - { -# ifdef FULLDEBUG - if (debug) - { - Info<< "HashTable is empty\n"; - } -# endif - - return HashTable<T, Key, Hash>::endConstIter_; - } - else - { - return const_iterator(*this, table_[i], i); - } -} - - -template<class T, class Key, class Hash> -inline const typename Foam::HashTable<T, Key, Hash>::const_iterator& -Foam::HashTable<T, Key, Hash>::cend() const -{ - return HashTable<T, Key, Hash>::endConstIter_; + return const_iterator(this); } @@ -537,12 +527,4 @@ Foam::HashTable<T, Key, Hash>::begin() const } -template<class T, class Key, class Hash> -inline const typename Foam::HashTable<T, Key, Hash>::const_iterator& -Foam::HashTable<T, Key, Hash>::end() const -{ - return HashTable<T, Key, Hash>::endConstIter_; -} - - // ************************************************************************* // diff --git a/src/OpenFOAM/containers/HashTables/HashTable/HashTableIO.C b/src/OpenFOAM/containers/HashTables/HashTable/HashTableIO.C index bef0cf50bca..0459dcab68d 100644 --- a/src/OpenFOAM/containers/HashTables/HashTable/HashTableIO.C +++ b/src/OpenFOAM/containers/HashTables/HashTable/HashTableIO.C @@ -33,16 +33,19 @@ License template<class T, class Key, class Hash> Foam::HashTable<T, Key, Hash>::HashTable(Istream& is, const label size) : - HashTableName(), + HashTableCore(), nElmts_(0), - tableSize_(canonicalSize(size)), - table_(new hashedEntry*[tableSize_]), - endIter_(*this, NULL, 0), - endConstIter_(*this, NULL, 0) + tableSize_(HashTableCore::canonicalSize(size)), + table_(NULL) { - for (label hashIdx = 0; hashIdx < tableSize_; hashIdx++) + if (tableSize_) { - table_[hashIdx] = 0; + table_ = new hashedEntry*[tableSize_]; + + for (label hashIdx = 0; hashIdx < tableSize_; hashIdx++) + { + table_[hashIdx] = 0; + } } operator>>(is, *this); diff --git a/src/OpenFOAM/containers/HashTables/HashTable/HashTableName.C b/src/OpenFOAM/containers/HashTables/HashTable/HashTableName.C deleted file mode 100644 index a8063190417..00000000000 --- a/src/OpenFOAM/containers/HashTables/HashTable/HashTableName.C +++ /dev/null @@ -1,33 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd. - \\/ M anipulation | -------------------------------------------------------------------------------- -License - This file is part of OpenFOAM. - - OpenFOAM is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - OpenFOAM is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with OpenFOAM; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -\*---------------------------------------------------------------------------*/ - -#include "HashTable.H" - -// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // - -defineTypeNameAndDebug(Foam::HashTableName, 0); - -// ************************************************************************* // diff --git a/src/OpenFOAM/containers/HashTables/HashTbl/HashTbl.C b/src/OpenFOAM/containers/HashTables/HashTbl/HashTbl.C deleted file mode 100644 index eb43d430a48..00000000000 --- a/src/OpenFOAM/containers/HashTables/HashTbl/HashTbl.C +++ /dev/null @@ -1,645 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd. - \\/ M anipulation | -------------------------------------------------------------------------------- -License - This file is part of OpenFOAM. - - OpenFOAM is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - OpenFOAM is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with OpenFOAM; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -\*---------------------------------------------------------------------------*/ - -#ifndef HashTbl_C -#define HashTbl_C - -#include "HashTbl.H" -#include "List.H" - -// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * // - -Foam::label Foam::HashTblCore::canonicalSize(const label size) -{ - if (size < 1) - { - return 0; - } - - // enforce power of two - unsigned int goodSize = size; - - if (goodSize & (goodSize - 1)) - { - // brute-force is fast enough - goodSize = 1; - while (goodSize < unsigned(size)) - { - goodSize <<= 1; - } - } - - return goodSize; -} - - -// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // - -template<class T, class Key, class Hash> -Foam::HashTbl<T, Key, Hash>::HashTbl(const label size) -: - HashTblCore(), - nElmts_(0), - tableSize_(HashTblCore::canonicalSize(size)), - table_(NULL) -{ - if (tableSize_) - { - table_ = new hashedEntry*[tableSize_]; - - for (label hashIdx = 0; hashIdx < tableSize_; hashIdx++) - { - table_[hashIdx] = 0; - } - } -} - - -template<class T, class Key, class Hash> -Foam::HashTbl<T, Key, Hash>::HashTbl(const HashTbl<T, Key, Hash>& ht) -: - HashTblCore(), - nElmts_(0), - tableSize_(ht.tableSize_), - table_(NULL) -{ - if (tableSize_) - { - table_ = new hashedEntry*[tableSize_]; - - for (label hashIdx = 0; hashIdx < tableSize_; hashIdx++) - { - table_[hashIdx] = 0; - } - - for (const_iterator iter = ht.cbegin(); iter != ht.cend(); ++iter) - { - insert(iter.key(), *iter); - } - } -} - -template<class T, class Key, class Hash> -Foam::HashTbl<T, Key, Hash>::HashTbl -( - const Xfer<HashTbl<T, Key, Hash> >& ht -) -: - HashTblCore(), - nElmts_(0), - tableSize_(0), - table_(NULL) -{ - transfer(ht()); -} - - -// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // - -template<class T, class Key, class Hash> -Foam::HashTbl<T, Key, Hash>::~HashTbl() -{ - if (table_) - { - clear(); - delete[] table_; - } -} - - -// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // - -template<class T, class Key, class Hash> -bool Foam::HashTbl<T, Key, Hash>::found(const Key& key) const -{ - if (nElmts_) - { - const label hashIdx = hashKeyIndex(key); - - for (hashedEntry* ep = table_[hashIdx]; ep; ep = ep->next_) - { - if (key == ep->key_) - { - return true; - } - } - } - -# ifdef FULLDEBUG - if (debug) - { - Info<< "HashTbl<T, Key, Hash>::found(const Key& key) : " - << "Entry " << key << " not found in hash table\n"; - } -# endif - - return false; -} - - -template<class T, class Key, class Hash> -typename Foam::HashTbl<T, Key, Hash>::iterator -Foam::HashTbl<T, Key, Hash>::find -( - const Key& key -) -{ - if (nElmts_) - { - const label hashIdx = hashKeyIndex(key); - - for (hashedEntry* ep = table_[hashIdx]; ep; ep = ep->next_) - { - if (key == ep->key_) - { - return iterator(this, ep, hashIdx); - } - } - } - -# ifdef FULLDEBUG - if (debug) - { - Info<< "HashTbl<T, Key, Hash>::find(const Key& key) : " - << "Entry " << key << " not found in hash table\n"; - } -# endif - - return iterator(); -} - - -template<class T, class Key, class Hash> -typename Foam::HashTbl<T, Key, Hash>::const_iterator -Foam::HashTbl<T, Key, Hash>::find -( - const Key& key -) const -{ - if (nElmts_) - { - const label hashIdx = hashKeyIndex(key); - - for (hashedEntry* ep = table_[hashIdx]; ep; ep = ep->next_) - { - if (key == ep->key_) - { - return const_iterator(this, ep, hashIdx); - } - } - } - -# ifdef FULLDEBUG - if (debug) - { - Info<< "HashTbl<T, Key, Hash>::find(const Key& key) const : " - << "Entry " << key << " not found in hash table\n"; - } -# endif - - return const_iterator(); -} - - -template<class T, class Key, class Hash> -Foam::List<Key> Foam::HashTbl<T, Key, Hash>::toc() const -{ - List<Key> keys(nElmts_); - label keyI = 0; - - for (const_iterator iter = cbegin(); iter != cend(); ++iter) - { - keys[keyI++] = iter.key(); - } - - return keys; -} - - -template<class T, class Key, class Hash> -Foam::List<Key> Foam::HashTbl<T, Key, Hash>::sortedToc() const -{ - List<Key> sortedLst = this->toc(); - sort(sortedLst); - - return sortedLst; -} - - -template<class T, class Key, class Hash> -bool Foam::HashTbl<T, Key, Hash>::set -( - const Key& key, - const T& newEntry, - const bool protect -) -{ - if (!tableSize_) - { - resize(2); - } - - const label hashIdx = hashKeyIndex(key); - - hashedEntry* existing = 0; - hashedEntry* prev = 0; - - for (hashedEntry* ep = table_[hashIdx]; ep; ep = ep->next_) - { - if (key == ep->key_) - { - existing = ep; - break; - } - prev = ep; - } - - // not found, insert it at the head - if (!existing) - { - table_[hashIdx] = new hashedEntry(key, table_[hashIdx], newEntry); - nElmts_++; - - if (double(nElmts_)/tableSize_ > 0.8 && tableSize_ < maxTableSize) - { -# ifdef FULLDEBUG - if (debug) - { - Info<< "HashTbl<T, Key, Hash>::set" - "(const Key& key, T newEntry) : " - "Doubling table size\n"; - } -# endif - - resize(2*tableSize_); - } - } - else if (protect) - { - // found - but protected from overwriting - // this corresponds to the STL 'insert' convention -# ifdef FULLDEBUG - if (debug) - { - Info<< "HashTbl<T, Key, Hash>::set" - "(const Key& key, T newEntry, true) : " - "Cannot insert " << key << " already in hash table\n"; - } -# endif - return false; - } - else - { - // found - overwrite existing entry - // this corresponds to the Perl convention - hashedEntry* ep = new hashedEntry(key, existing->next_, newEntry); - - // replace existing element - within list or insert at the head - if (prev) - { - prev->next_ = ep; - } - else - { - table_[hashIdx] = ep; - } - - delete existing; - } - - return true; -} - - -template<class T, class Key, class Hash> -bool Foam::HashTbl<T, Key, Hash>::iteratorBase::erase() -{ - // note: entryPtr_ is NULL for end(), so this catches that too - if (entryPtr_) - { - // Search element before entryPtr_ - hashedEntry* prev = 0; - - for - ( - hashedEntry* ep = hashTable_->table_[hashIndex_]; - ep; - ep = ep->next_ - ) - { - if (ep == entryPtr_) - { - break; - } - prev = ep; - } - - if (prev) - { - // has an element before entryPtr - reposition to there - prev->next_ = entryPtr_->next_; - delete entryPtr_; - entryPtr_ = prev; - } - else - { - // entryPtr was first element on SLList - hashTable_->table_[hashIndex_] = entryPtr_->next_; - delete entryPtr_; - - // assign any non-NULL pointer value so it doesn't look - // like end()/cend() - entryPtr_ = reinterpret_cast<hashedEntry*>(this); - - // Mark with special hashIndex value to signal it has been rewound. - // The next increment will bring it back to the present location. - // - // From the current position 'curPos', we wish to continue at - // prevPos='curPos-1', which we mark as markPos='-curPos-1'. - // The negative lets us notice it is special, the extra '-1' - // is needed to avoid ambiguity for position '0'. - // To retrieve prevPos, we would later use '-(markPos+1) - 1' - hashIndex_ = -hashIndex_ - 1; - } - - hashTable_->nElmts_--; - - return true; - } - else - { - return false; - } -} - - - -// NOTE: -// We use (const iterator&) here, but manipulate its contents anyhow. -// The parameter should be (iterator&), but then the compiler doesn't find -// it correctly and tries to call as (iterator) instead. -// -template<class T, class Key, class Hash> -bool Foam::HashTbl<T, Key, Hash>::erase(const iterator& cit) -{ - // adjust iterator after erase - return const_cast<iterator&>(cit).erase(); -} - - -template<class T, class Key, class Hash> -bool Foam::HashTbl<T, Key, Hash>::erase(const Key& key) -{ - return erase(find(key)); -} - - -template<class T, class Key, class Hash> -Foam::label Foam::HashTbl<T, Key, Hash>::erase(const UList<Key>& keys) -{ - const label nTotal = nElmts_; - label count = 0; - - // Remove listed keys from this table - terminates early if possible - for (label keyI = 0; count < nTotal && keyI < keys.size(); ++keyI) - { - if (erase(keys[keyI])) - { - count++; - } - } - - return count; -} - - -template<class T, class Key, class Hash> -template<class AnyType, class AnyHash> -Foam::label Foam::HashTbl<T, Key, Hash>::erase -( - const HashTbl<AnyType, Key, AnyHash>& rhs -) -{ - label count = 0; - - // Remove rhs keys from this table - terminates early if possible - // Could optimize depending on which hash is smaller ... - for (iterator iter = begin(); iter != end(); ++iter) - { - if (rhs.found(iter.key()) && erase(iter)) - { - count++; - } - } - - return count; -} - - -template<class T, class Key, class Hash> -void Foam::HashTbl<T, Key, Hash>::resize(const label sz) -{ - label newSize = HashTblCore::canonicalSize(sz); - - if (newSize == tableSize_) - { -# ifdef FULLDEBUG - if (debug) - { - Info<< "HashTbl<T, Key, Hash>::resize(const label) : " - << "new table size == old table size\n"; - } -# endif - - return; - } - - HashTbl<T, Key, Hash>* tmpTable = new HashTbl<T, Key, Hash>(newSize); - - for (const_iterator iter = cbegin(); iter != cend(); ++iter) - { - tmpTable->insert(iter.key(), *iter); - } - - label oldSize = tableSize_; - tableSize_ = tmpTable->tableSize_; - tmpTable->tableSize_ = oldSize; - - hashedEntry** oldTable = table_; - table_ = tmpTable->table_; - tmpTable->table_ = oldTable; - - delete tmpTable; -} - - -template<class T, class Key, class Hash> -void Foam::HashTbl<T, Key, Hash>::clear() -{ - if (nElmts_) - { - for (label hashIdx = 0; hashIdx < tableSize_; hashIdx++) - { - if (table_[hashIdx]) - { - hashedEntry* ep = table_[hashIdx]; - while (hashedEntry* next = ep->next_) - { - delete ep; - ep = next; - } - delete ep; - table_[hashIdx] = 0; - } - } - nElmts_ = 0; - } -} - - -template<class T, class Key, class Hash> -void Foam::HashTbl<T, Key, Hash>::clearStorage() -{ - clear(); - resize(0); -} - - -template<class T, class Key, class Hash> -void Foam::HashTbl<T, Key, Hash>::shrink() -{ - const label newSize = HashTblCore::canonicalSize(nElmts_); - - if (newSize < tableSize_) - { - // avoid having the table disappear on us - resize(newSize ? newSize : 2); - } -} - - -template<class T, class Key, class Hash> -void Foam::HashTbl<T, Key, Hash>::transfer(HashTbl<T, Key, Hash>& ht) -{ - // as per the Destructor - if (table_) - { - clear(); - delete[] table_; - } - - tableSize_ = ht.tableSize_; - ht.tableSize_ = 0; - - table_ = ht.table_; - ht.table_ = NULL; - - nElmts_ = ht.nElmts_; - ht.nElmts_ = 0; -} - - -// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // - -template<class T, class Key, class Hash> -void Foam::HashTbl<T, Key, Hash>::operator= -( - const HashTbl<T, Key, Hash>& rhs -) -{ - // Check for assignment to self - if (this == &rhs) - { - FatalErrorIn - ( - "HashTbl<T, Key, Hash>::operator=" - "(const HashTbl<T, Key, Hash>&)" - ) << "attempted assignment to self" - << abort(FatalError); - } - - // could be zero-sized from a previous transfer() - if (!tableSize_) - { - resize(rhs.tableSize_); - } - else - { - clear(); - } - - for (const_iterator iter = rhs.cbegin(); iter != rhs.cend(); ++iter) - { - insert(iter.key(), *iter); - } -} - - -template<class T, class Key, class Hash> -bool Foam::HashTbl<T, Key, Hash>::operator== -( - const HashTbl<T, Key, Hash>& rhs -) const -{ - // sizes (number of keys) must match - if (size() != rhs.size()) - { - return false; - } - - for (const_iterator iter = rhs.cbegin(); iter != rhs.cend(); ++iter) - { - const_iterator fnd = find(iter.key()); - - if (fnd == cend() || fnd() != iter()) - { - return false; - } - } - - return true; -} - - -template<class T, class Key, class Hash> -bool Foam::HashTbl<T, Key, Hash>::operator!= -( - const HashTbl<T, Key, Hash>& rhs -) const -{ - return !(operator==(rhs)); -} - - -// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * // - -#include "HashTblIO.C" - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -#endif - -// ************************************************************************* // diff --git a/src/OpenFOAM/containers/HashTables/HashTbl/HashTbl.H b/src/OpenFOAM/containers/HashTables/HashTbl/HashTbl.H deleted file mode 100644 index 8ba924f00b6..00000000000 --- a/src/OpenFOAM/containers/HashTables/HashTbl/HashTbl.H +++ /dev/null @@ -1,563 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd. - \\/ M anipulation | -------------------------------------------------------------------------------- -License - This file is part of OpenFOAM. - - OpenFOAM is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - OpenFOAM is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with OpenFOAM; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -Class - Foam::HashTbl - -Description - An STL-conforming hash table. - -Note - Hashing index collisions are handled via chaining using a singly-linked - list with the colliding entry being added to the head of the linked - list. Thus copying the hash table (or indeed even resizing it) will - often result in a different hash order. Use a sorted table-of-contents - when the hash order is important. - -SourceFiles - HashTblI.H - HashTbl.C - HashTblIO.C - -\*---------------------------------------------------------------------------*/ - -#ifndef HashTbl_H -#define HashTbl_H - -#include "label.H" -#include "uLabel.H" -#include "word.H" -#include "Xfer.H" -#include "className.H" - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -namespace Foam -{ - -// Forward declaration of friend functions and operators - -template<class T> class List; -template<class T> class UList; -template<class T, class Key, class Hash> class HashTbl; -template<class T, class Key, class Hash> class HashPtrTable; - -template<class T, class Key, class Hash> -Istream& operator>>(Istream&, HashTbl<T, Key, Hash>&); - -template<class T, class Key, class Hash> -Ostream& operator<<(Ostream&, const HashTbl<T, Key, Hash>&); - - -/*---------------------------------------------------------------------------*\ - Class HashTblCore Declaration -\*---------------------------------------------------------------------------*/ - -//- Template-invariant bits for HashTbl -struct HashTblCore -{ - //- Return a canonical (power-of-two) size - static label canonicalSize(const label); - - //- Maximum allowable table size - static const label maxTableSize; - - //- Construct null - HashTblCore() - {} - - //- Define template name and debug - ClassName("HashTbl"); - - //- A zero-sized end iterator - struct iteratorEnd - { - //- Construct null - iteratorEnd() - {} - }; - - //- iteratorEnd set to beyond the end of any HashTbl - static iteratorEnd cend() - { - return iteratorEnd(); - } - - //- iteratorEnd set to beyond the end of any HashTbl - static iteratorEnd end() - { - return iteratorEnd(); - } - -}; - - -/*---------------------------------------------------------------------------*\ - Class HashTbl Declaration -\*---------------------------------------------------------------------------*/ - -template<class T, class Key=word, class Hash=string::hash> -class HashTbl -: - public HashTblCore -{ - // Private data type for table entries - - //- Structure to hold a hashed entry with SLList for collisions - struct hashedEntry - { - //- The lookup key - Key key_; - - //- Pointer to next hashedEntry in sub-list - hashedEntry* next_; - - //- The data object - T obj_; - - //- Construct from key, next pointer and object - inline hashedEntry(const Key&, hashedEntry* next, const T&); - - private: - //- Disallow default bitwise copy construct - hashedEntry(const hashedEntry&); - - //- Disallow default bitwise assignment - void operator=(const hashedEntry&); - }; - - - // Private data: size of table, the table and current number of elements - - //- The current number of elements in table - label nElmts_; - - //- Number of primary entries allocated in table - label tableSize_; - - //- The table of primary entries - hashedEntry** table_; - - - // Private Member Functions - - //- Return a canonical (power-of-two) size - static label canonicalSize(const label); - - //- Return the hash index of the Key within the current table size. - // No checks for zero-sized tables. - inline label hashKeyIndex(const Key&) const; - - //- Assign a new hashedEntry to a possibly already existing key - bool set(const Key&, const T& newElmt, bool protect); - -public: - - // Forward declaration of iterators - - class iteratorBase; - class iterator; - class const_iterator; - - //- Declare friendship with the HashPtrTable class - template<class T2, class Key2, class Hash2> - friend class HashPtrTable; - - //- Declare friendship with the iteratorBase - friend class iteratorBase; - - //- Declare friendship with the iterator - friend class iterator; - - //- Declare friendship with the const_iterator - friend class const_iterator; - - - // Constructors - - //- Construct given initial table size - HashTbl(const label size = 128); - - //- Construct from Istream - HashTbl(Istream&, const label size = 128); - - //- Construct as copy - HashTbl(const HashTbl<T, Key, Hash>&); - - //- Construct by transferring the parameter contents - HashTbl(const Xfer<HashTbl<T, Key, Hash> >&); - - - // Destructor - - ~HashTbl(); - - - // Member Functions - - // Access - - //- The size of the underlying table - inline label capacity() const; - - //- Return number of elements in table - inline label size() const; - - //- Return true if the hash table is empty - inline bool empty() const; - - //- Return true if hashedEntry is found in table - bool found(const Key&) const; - - //- Find and return an iterator set at the hashedEntry - // If not found iterator = end() - iterator find(const Key&); - - //- Find and return an const_iterator set at the hashedEntry - // If not found iterator = end() - const_iterator find(const Key&) const; - - //- Return the table of contents - List<Key> toc() const; - - //- Return the table of contents as a sorted list - List<Key> sortedToc() const; - - //- Print information - Ostream& printInfo(Ostream&) const; - - // Edit - - //- Insert a new hashedEntry - inline bool insert(const Key&, const T& newElmt); - - //- Assign a new hashedEntry, overwriting existing entries - inline bool set(const Key&, const T& newElmt); - - //- Erase a hashedEntry specified by given iterator - // This invalidates the iterator until the next operator++ - bool erase(const iterator&); - - //- Erase a hashedEntry specified by the given key - bool erase(const Key&); - - //- Remove entries given by the listed keys from this HashTbl - // Return the number of elements removed - label erase(const UList<Key>&); - - //- Remove entries given by the given keys from this HashTbl - // Return the number of elements removed. - // The parameter HashTbl needs the same type of key, but the - // type of values held and the hashing function are arbitrary. - template<class AnyType, class AnyHash> - label erase(const HashTbl<AnyType, Key, AnyHash>&); - - //- Resize the hash table for efficiency - void resize(const label newSize); - - //- Clear all entries from table - void clear(); - - //- Clear the table entries and the table itself. - // Equivalent to clear() followed by resize(0) - void clearStorage(); - - //- Shrink the allocated table to approx. twice number of elements - void shrink(); - - //- Transfer the contents of the argument table into this table - // and annull the argument table. - void transfer(HashTbl<T, Key, Hash>&); - - //- Transfer contents to the Xfer container - inline Xfer< HashTbl<T, Key, Hash> > xfer(); - - - // Member Operators - - //- Find and return a hashedEntry - inline T& operator[](const Key&); - - //- Find and return a hashedEntry - inline const T& operator[](const Key&) const; - - //- Find and return a hashedEntry, create it null if not present - inline T& operator()(const Key&); - - //- Assignment - void operator=(const HashTbl<T, Key, Hash>&); - - //- Equality. Hash tables are equal if the keys and values are equal. - // Independent of table storage size and table order. - bool operator==(const HashTbl<T, Key, Hash>&) const; - - //- The opposite of the equality operation. Takes linear time. - bool operator!=(const HashTbl<T, Key, Hash>&) const; - - - - // STL type definitions - - //- Type of values the HashTbl contains. - typedef T value_type; - - //- Type that can be used for storing into HashTbl::value_type - // objects. This type is usually List::value_type&. - typedef T& reference; - - //- Type that can be used for storing into constant - // HashTbl::value_type objects. This type is usually const - // HashTbl::value_type&. - typedef const T& const_reference; - - //- The type that can represent the size of a HashTbl. - typedef label size_type; - - - // Iterators and helpers - - //- The iterator base for HashTbl - // Note: data and functions are protected, to allow reuse by iterator - // and prevent most external usage. - // iterator and const_iterator have the same size, allowing - // us to reinterpret_cast between them (if desired) - class iteratorBase - { - // Private Data - - //- Pointer to the HashTbl for which this is an iterator - // This also lets us use the default bitwise copy/assignment - HashTbl<T, Key, Hash>* hashTable_; - - //- Current element - hashedEntry* entryPtr_; - - //- Current hash index - label hashIndex_; - - protected: - - // Protected Member Functions - - // Constructors - - //- Construct null - equivalent to an 'end' position - inline iteratorBase(); - - //- Construct from hash table, moving to its 'begin' position - inline explicit iteratorBase - ( - const HashTbl<T, Key, Hash>* curHashTbl - ); - - //- Construct from hash table, element and hash index - inline explicit iteratorBase - ( - const HashTbl<T, Key, Hash>* curHashTbl, - const hashedEntry* elmt, - const label hashIndex - ); - - - //- Increment to the next position - inline void increment(); - - //- Erase the HashTbl element at the current position - bool erase(); - - //- Return non-const access to referenced object - inline T& object(); - - //- Return const access to referenced object - inline const T& cobject() const; - - public: - - // Member operators - - // Access - - //- Return the Key corresponding to the iterator - inline const Key& key() const; - - //- Compare hashedEntry element pointers - inline bool operator==(const iteratorBase&) const; - inline bool operator!=(const iteratorBase&) const; - - //- Compare hashedEntry to iteratorEnd pointers - inline bool operator==(const iteratorEnd&) const; - inline bool operator!=(const iteratorEnd&) const; - }; - - - //- An STL-conforming iterator - class iterator - : - public iteratorBase - { - friend class HashTbl; - - // Private Member Functions - - //- Construct from hash table, moving to its 'begin' position - inline explicit iterator - ( - HashTbl<T, Key, Hash>* curHashTbl - ); - - //- Construct from hash table, element and hash index - inline explicit iterator - ( - HashTbl<T, Key, Hash>* curHashTbl, - hashedEntry* elmt, - const label hashIndex - ); - - public: - - // Constructors - - //- Construct null (end iterator) - inline iterator(); - - //- Construct end iterator - inline iterator(const iteratorEnd&); - - // Member operators - - //- Conversion to a const_iterator - inline operator const_iterator() const; - - // Access - - //- Return referenced hash value - inline T& operator*(); - inline T& operator()(); - - //- Return referenced hash value - inline const T& operator*() const; - inline const T& operator()() const; - - inline iterator& operator++(); - inline iterator operator++(int); - }; - - //- iterator set to the begining of the HashTbl - inline iterator begin(); - - - // STL const_iterator - - //- An STL-conforming const_iterator - class const_iterator - : - public iteratorBase - { - friend class HashTbl; - - // Private Member Functions - - //- Construct from hash table, moving to its 'begin' position - inline explicit const_iterator - ( - const HashTbl<T, Key, Hash>* curHashTbl - ); - - //- Construct from hash table, element and hash index - inline explicit const_iterator - ( - const HashTbl<T, Key, Hash>* curHashTbl, - const hashedEntry* elmt, - const label hashIndex - ); - - public: - - // Constructors - - //- Construct null (end iterator) - inline const_iterator(); - - //- Construct end iterator - inline const_iterator(const iteratorEnd&); - - // Member operators - - // Access - - //- Return referenced hash value - inline const T& operator*() const; - inline const T& operator()() const; - - inline const_iterator& operator++(); - inline const_iterator operator++(int); - - }; - - - //- const_iterator set to the beginning of the HashTbl - inline const_iterator cbegin() const; - - //- const_iterator set to the beginning of the HashTbl - inline const_iterator begin() const; - - - // IOstream Operator - - friend Istream& operator>> <T, Key, Hash> - ( - Istream&, - HashTbl<T, Key, Hash>& - ); - - friend Ostream& operator<< <T, Key, Hash> - ( - Ostream&, - const HashTbl<T, Key, Hash>& - ); - -}; - - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -} // End namespace Foam - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -# include "HashTblI.H" - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -#ifndef NoHashTblC -#ifdef NoRepository -# include "HashTbl.C" -#endif -#endif - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -#endif - -// ************************************************************************* // diff --git a/src/OpenFOAM/containers/HashTables/HashTbl/HashTblI.H b/src/OpenFOAM/containers/HashTables/HashTbl/HashTblI.H deleted file mode 100644 index 7da1ad81cc6..00000000000 --- a/src/OpenFOAM/containers/HashTables/HashTbl/HashTblI.H +++ /dev/null @@ -1,530 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd. - \\/ M anipulation | -------------------------------------------------------------------------------- -License - This file is part of OpenFOAM. - - OpenFOAM is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - OpenFOAM is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with OpenFOAM; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -\*---------------------------------------------------------------------------*/ - -#include "error.H" - -// * * * * * * * * * * * * * Private Member Classes * * * * * * * * * * * * // - -template<class T, class Key, class Hash> -inline Foam::HashTbl<T, Key, Hash>::hashedEntry::hashedEntry -( - const Key& key, - hashedEntry* next, - const T& obj -) -: - key_(key), - next_(next), - obj_(obj) -{} - - -// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * // - -template<class T, class Key, class Hash> -inline Foam::label -Foam::HashTbl<T, Key, Hash>::hashKeyIndex(const Key& key) const -{ - // size is power of two - this is the modulus - return Hash()(key) & (tableSize_ - 1); -} - - -// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // - -template<class T, class Key, class Hash> -inline Foam::label Foam::HashTbl<T, Key, Hash>::capacity() const -{ - return tableSize_; -} - - -template<class T, class Key, class Hash> -inline Foam::label Foam::HashTbl<T, Key, Hash>::size() const -{ - return nElmts_; -} - - -template<class T, class Key, class Hash> -inline bool Foam::HashTbl<T, Key, Hash>::empty() const -{ - return !nElmts_; -} - - -template<class T, class Key, class Hash> -inline bool Foam::HashTbl<T, Key, Hash>::insert -( - const Key& key, - const T& newEntry -) -{ - return set(key, newEntry, true); -} - - -template<class T, class Key, class Hash> -inline bool Foam::HashTbl<T, Key, Hash>::set -( - const Key& key, - const T& newEntry -) -{ - return set(key, newEntry, false); -} - - -template<class T, class Key, class Hash> -inline Foam::Xfer<Foam::HashTbl<T, Key, Hash> > -Foam::HashTbl<T, Key, Hash>::xfer() -{ - return xferMove(*this); -} - - -// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // - -template<class T, class Key, class Hash> -inline T& Foam::HashTbl<T, Key, Hash>::operator[](const Key& key) -{ - iterator iter = find(key); - - if (iter == end()) - { - FatalErrorIn("HashTbl<T, Key, Hash>::operator[](const Key&)") - << key << " not found in table. Valid entries: " - << toc() - << exit(FatalError); - } - - return *iter; -} - - -template<class T, class Key, class Hash> -inline const T& Foam::HashTbl<T, Key, Hash>::operator[](const Key& key) const -{ - const_iterator iter = find(key); - - if (iter == cend()) - { - FatalErrorIn("HashTbl<T, Key, Hash>::operator[](const Key&) const") - << key << " not found in table. Valid entries: " - << toc() - << exit(FatalError); - } - - return *iter; -} - - -template<class T, class Key, class Hash> -inline T& Foam::HashTbl<T, Key, Hash>::operator()(const Key& key) -{ - iterator iter = find(key); - - if (iter == end()) - { - insert(key, T()); - return *find(key); - } - else - { - return *iter; - } -} - - -// * * * * * * * * * * * * * * * iterator base * * * * * * * * * * * * * * * // - -template<class T, class Key, class Hash> -inline Foam::HashTbl<T, Key, Hash>::iteratorBase::iteratorBase() -: - hashTable_(0), - entryPtr_(0), - hashIndex_(0) -{} - - -template<class T, class Key, class Hash> -inline Foam::HashTbl<T, Key, Hash>::iteratorBase::iteratorBase -( - const HashTbl<T, Key, Hash>* hashTbl -) -: - hashTable_(const_cast<HashTbl<T, Key, Hash>*>(hashTbl)), - entryPtr_(0), - hashIndex_(0) -{ - if (hashTable_->nElmts_ && hashTable_->table_) - { - // find first non-NULL table entry - while - ( - !(entryPtr_ = hashTable_->table_[hashIndex_]) - && ++hashIndex_ < hashTable_->tableSize_ - ) - {} - - if (hashIndex_ >= hashTable_->tableSize_) - { - // make into an end iterator - entryPtr_ = 0; - hashIndex_ = 0; - } - } -} - - -template<class T, class Key, class Hash> -inline Foam::HashTbl<T, Key, Hash>::iteratorBase::iteratorBase -( - const HashTbl<T, Key, Hash>* hashTbl, - const hashedEntry* elmt, - const label hashIndex -) -: - hashTable_(const_cast<HashTbl<T, Key, Hash>*>(hashTbl)), - entryPtr_(const_cast<hashedEntry*>(elmt)), - hashIndex_(hashIndex) -{} - - -template<class T, class Key, class Hash> -inline void -Foam::HashTbl<T, Key, Hash>::iteratorBase::increment() -{ - // A negative index is a special value from erase - if (hashIndex_ < 0) - { - // the markPos='-curPos-1', but we wish to continue at 'curPos-1' - // thus use '-(markPos+1) -1' - hashIndex_ = -(hashIndex_+1) - 1; - } - else if (entryPtr_) - { - if (entryPtr_->next_) - { - // Move to next element on the SLList - entryPtr_ = entryPtr_->next_; - return; - } - } - // else - // { - // // if we reach here (entryPtr_ is NULL) it is already at the end() - // // we should probably stop - // } - - - // Step to the next table entry - while - ( - ++hashIndex_ < hashTable_->tableSize_ - && !(entryPtr_ = hashTable_->table_[hashIndex_]) - ) - {} - - if (hashIndex_ >= hashTable_->tableSize_) - { - // make into an end iterator - entryPtr_ = 0; - hashIndex_ = 0; - } -} - - -template<class T, class Key, class Hash> -inline -const Key& Foam::HashTbl<T, Key, Hash>::iteratorBase::key() const -{ - return entryPtr_->key_; -} - - -template<class T, class Key, class Hash> -inline T& -Foam::HashTbl<T, Key, Hash>::iteratorBase::object() -{ - return entryPtr_->obj_; -} - - -template<class T, class Key, class Hash> -inline const T& -Foam::HashTbl<T, Key, Hash>::iteratorBase::cobject() const -{ - return entryPtr_->obj_; -} - - -template<class T, class Key, class Hash> -inline bool Foam::HashTbl<T, Key, Hash>::iteratorBase::operator== -( - const iteratorBase& iter -) const -{ - return entryPtr_ == iter.entryPtr_; -} - - -template<class T, class Key, class Hash> -inline bool Foam::HashTbl<T, Key, Hash>::iteratorBase::operator!= -( - const iteratorBase& iter -) const -{ - return entryPtr_ != iter.entryPtr_; -} - - -template<class T, class Key, class Hash> -inline bool Foam::HashTbl<T, Key, Hash>::iteratorBase::operator== -( - const iteratorEnd& -) const -{ - return !entryPtr_; -} - - -template<class T, class Key, class Hash> -inline bool Foam::HashTbl<T, Key, Hash>::iteratorBase::operator!= -( - const iteratorEnd& -) const -{ - return entryPtr_; -} - - -// * * * * * * * * * * * * * * * * STL iterator * * * * * * * * * * * * * * // - -template<class T, class Key, class Hash> -inline Foam::HashTbl<T, Key, Hash>::iterator::iterator() -: - iteratorBase() -{} - - -template<class T, class Key, class Hash> -inline Foam::HashTbl<T, Key, Hash>::iterator::iterator -( - const iteratorEnd& -) -: - iteratorBase() -{} - - -template<class T, class Key, class Hash> -inline Foam::HashTbl<T, Key, Hash>::iterator::iterator -( - HashTbl<T, Key, Hash>* hashTbl -) -: - iteratorBase(hashTbl) -{} - - -template<class T, class Key, class Hash> -inline Foam::HashTbl<T, Key, Hash>::iterator::iterator -( - HashTbl<T, Key, Hash>* hashTbl, - hashedEntry* elmt, - const label hashIndex -) -: - iteratorBase(hashTbl, elmt, hashIndex) -{} - - -template<class T, class Key, class Hash> -inline Foam::HashTbl<T, Key, Hash>::iterator::operator -typename Foam::HashTbl<T, Key, Hash>::const_iterator() const -{ - return *reinterpret_cast - < - const typename Foam::HashTbl<T, Key, Hash>::const_iterator* - >(this); -} - - -template<class T, class Key, class Hash> -inline T& -Foam::HashTbl<T, Key, Hash>::iterator::operator*() -{ - return this->object(); -} - - -template<class T, class Key, class Hash> -inline T& -Foam::HashTbl<T, Key, Hash>::iterator::operator()() -{ - return this->object(); -} - - -template<class T, class Key, class Hash> -inline const T& -Foam::HashTbl<T, Key, Hash>::iterator::operator*() const -{ - return this->cobject(); -} - - -template<class T, class Key, class Hash> -inline const T& -Foam::HashTbl<T, Key, Hash>::iterator::operator()() const -{ - return this->cobject(); -} - - -template<class T, class Key, class Hash> -inline -typename Foam::HashTbl<T, Key, Hash>::iterator& -Foam::HashTbl<T, Key, Hash>::iterator::operator++() -{ - this->increment(); - return *this; -} - - -template<class T, class Key, class Hash> -inline typename Foam::HashTbl<T, Key, Hash>::iterator -Foam::HashTbl<T, Key, Hash>::iterator::operator++(int) -{ - iterator old = *this; - this->increment(); - return old; -} - - -template<class T, class Key, class Hash> -inline typename Foam::HashTbl<T, Key, Hash>::iterator -Foam::HashTbl<T, Key, Hash>::begin() -{ - return iterator(this); -} - - -// * * * * * * * * * * * * * * * STL const_iterator * * * * * * * * * * * * * // - -template<class T, class Key, class Hash> -inline Foam::HashTbl<T, Key, Hash>::const_iterator::const_iterator() -: - iteratorBase() -{} - - -template<class T, class Key, class Hash> -inline Foam::HashTbl<T, Key, Hash>::const_iterator::const_iterator -( - const iteratorEnd& -) -: - iteratorBase() -{} - - -template<class T, class Key, class Hash> -inline Foam::HashTbl<T, Key, Hash>::const_iterator::const_iterator -( - const HashTbl<T, Key, Hash>* hashTbl -) -: - iteratorBase(hashTbl) -{} - - -template<class T, class Key, class Hash> -inline Foam::HashTbl<T, Key, Hash>::const_iterator::const_iterator -( - const HashTbl<T, Key, Hash>* hashTbl, - const hashedEntry* elmt, - const label hashIndex -) -: - iteratorBase(hashTbl, elmt, hashIndex) -{} - - -template<class T, class Key, class Hash> -inline const T& -Foam::HashTbl<T, Key, Hash>::const_iterator::operator*() const -{ - return this->cobject(); -} - - -template<class T, class Key, class Hash> -inline const T& -Foam::HashTbl<T, Key, Hash>::const_iterator::operator()() const -{ - return this->cobject(); -} - - -template<class T, class Key, class Hash> -inline -typename Foam::HashTbl<T, Key, Hash>::const_iterator& -Foam::HashTbl<T, Key, Hash>::const_iterator::operator++() -{ - this->increment(); - return *this; -} - - -template<class T, class Key, class Hash> -inline typename Foam::HashTbl<T, Key, Hash>::const_iterator -Foam::HashTbl<T, Key, Hash>::const_iterator::operator++(int) -{ - const_iterator old = *this; - this->increment(); - return old; -} - - -template<class T, class Key, class Hash> -inline typename Foam::HashTbl<T, Key, Hash>::const_iterator -Foam::HashTbl<T, Key, Hash>::cbegin() const -{ - return const_iterator(this); -} - - -template<class T, class Key, class Hash> -inline typename Foam::HashTbl<T, Key, Hash>::const_iterator -Foam::HashTbl<T, Key, Hash>::begin() const -{ - return this->cbegin(); -} - - -// ************************************************************************* // diff --git a/src/OpenFOAM/containers/HashTables/HashTbl/HashTblIO.C b/src/OpenFOAM/containers/HashTables/HashTbl/HashTblIO.C deleted file mode 100644 index 84e848d389b..00000000000 --- a/src/OpenFOAM/containers/HashTables/HashTbl/HashTblIO.C +++ /dev/null @@ -1,249 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd. - \\/ M anipulation | -------------------------------------------------------------------------------- -License - This file is part of OpenFOAM. - - OpenFOAM is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - OpenFOAM is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with OpenFOAM; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -\*---------------------------------------------------------------------------*/ - -#include "HashTbl.H" -#include "Istream.H" -#include "Ostream.H" - -// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // - -template<class T, class Key, class Hash> -Foam::HashTbl<T, Key, Hash>::HashTbl(Istream& is, const label size) -: - HashTblCore(), - nElmts_(0), - tableSize_(HashTblCore::canonicalSize(size)), - table_(NULL) -{ - if (tableSize_) - { - table_ = new hashedEntry*[tableSize_]; - - for (label hashIdx = 0; hashIdx < tableSize_; hashIdx++) - { - table_[hashIdx] = 0; - } - } - - operator>>(is, *this); -} - - -// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // - -template<class T, class Key, class Hash> -Foam::Ostream& -Foam::HashTbl<T, Key, Hash>::printInfo(Ostream& os) const -{ - label used = 0; - label maxChain = 0; - unsigned avgChain = 0; - - for (label hashIdx = 0; hashIdx < tableSize_; ++hashIdx) - { - label count = 0; - for (hashedEntry* ep = table_[hashIdx]; ep; ep = ep->next_) - { - ++count; - } - - if (count) - { - ++used; - avgChain += count; - - if (maxChain < count) - { - maxChain = count; - } - } - } - - os << "HashTbl<T,Key,Hash>" - << " elements:" << size() << " slots:" << used << "/" << tableSize_ - << " chaining(avg/max):" << (used ? (float(avgChain)/used) : 0) - << "/" << maxChain << endl; - - return os; -} - - -// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * // - -template<class T, class Key, class Hash> -Foam::Istream& Foam::operator>> -( - Istream& is, - HashTbl<T, Key, Hash>& L -) -{ - is.fatalCheck("operator>>(Istream&, HashTbl<T, Key, Hash>&)"); - - // Anull list - L.clear(); - - is.fatalCheck("operator>>(Istream&, HashTbl<T, Key, Hash>&)"); - - token firstToken(is); - - is.fatalCheck - ( - "operator>>(Istream&, HashTbl<T, Key, Hash>&) : " - "reading first token" - ); - - if (firstToken.isLabel()) - { - label s = firstToken.labelToken(); - - // Read beginning of contents - char delimiter = is.readBeginList("HashTbl<T, Key, Hash>"); - - if (s) - { - if (2*s > L.tableSize_) - { - L.resize(2*s); - } - - if (delimiter == token::BEGIN_LIST) - { - for (label i=0; i<s; i++) - { - Key key; - is >> key; - L.insert(key, pTraits<T>(is)); - - is.fatalCheck - ( - "operator>>(Istream&, HashTbl<T, Key, Hash>&) : " - "reading entry" - ); - } - } - else - { - FatalIOErrorIn - ( - "operator>>(Istream&, HashTbl<T, Key, Hash>&)", - is - ) << "incorrect first token, '(', found " << firstToken.info() - << exit(FatalIOError); - } - } - - // Read end of contents - is.readEndList("HashTbl"); - } - else if (firstToken.isPunctuation()) - { - if (firstToken.pToken() != token::BEGIN_LIST) - { - FatalIOErrorIn - ( - "operator>>(Istream&, HashTbl<T, Key, Hash>&)", - is - ) << "incorrect first token, '(', found " << firstToken.info() - << exit(FatalIOError); - } - - token lastToken(is); - while - ( - !( - lastToken.isPunctuation() - && lastToken.pToken() == token::END_LIST - ) - ) - { - is.putBack(lastToken); - - Key key; - is >> key; - - T element; - is >> element; - - L.insert(key, element); - - is.fatalCheck - ( - "operator>>(Istream&, HashTbl<T, Key, Hash>&) : " - "reading entry" - ); - - is >> lastToken; - } - } - else - { - FatalIOErrorIn - ( - "operator>>(Istream&, HashTbl<T, Key, Hash>&)", - is - ) << "incorrect first token, expected <int> or '(', found " - << firstToken.info() - << exit(FatalIOError); - } - - is.fatalCheck("operator>>(Istream&, HashTbl<T, Key, Hash>&)"); - - return is; -} - - -template<class T, class Key, class Hash> -Foam::Ostream& Foam::operator<< -( - Ostream& os, - const HashTbl<T, Key, Hash>& L -) -{ - // Write size and start delimiter - os << nl << L.size() << nl << token::BEGIN_LIST << nl; - - // Write contents - for - ( - typename HashTbl<T, Key, Hash>::const_iterator iter = L.cbegin(); - iter != L.cend(); - ++iter - ) - { - os << iter.key() << token::SPACE << iter() << nl; - } - - // Write end delimiter - os << token::END_LIST; - - // Check state of IOstream - os.check("Ostream& operator<<(Ostream&, const HashTbl&)"); - - return os; -} - - -// ************************************************************************* // -- GitLab