From 8bdd3501d7f6965794b3c586337b8bf67feb9dff Mon Sep 17 00:00:00 2001 From: Mark Olesen <Mark.Olesen@Germany> Date: Thu, 8 May 2008 14:29:21 +0200 Subject: [PATCH] Added set() method to HashTable. Added replace() method to DLListBase. Modified the dictionary merge code to avoid scrambling the order, but left the old version active for now. --- .../HashTables/HashTable/HashTable.C | 69 ++++++++++++++----- .../HashTables/HashTable/HashTable.H | 10 ++- .../HashTables/HashTable/HashTableI.H | 15 +++- .../linkTypes/DLListBase/DLListBase.C | 37 ++++++++++ .../linkTypes/DLListBase/DLListBase.H | 6 ++ .../linkTypes/DLListBase/DLListBaseI.H | 10 +++ src/OpenFOAM/db/dictionary/dictionary.C | 26 +++++++ 7 files changed, 154 insertions(+), 19 deletions(-) diff --git a/src/OpenFOAM/containers/HashTables/HashTable/HashTable.C b/src/OpenFOAM/containers/HashTables/HashTable/HashTable.C index 072fe7077c7..0e0d7d58f93 100644 --- a/src/OpenFOAM/containers/HashTables/HashTable/HashTable.C +++ b/src/OpenFOAM/containers/HashTables/HashTable/HashTable.C @@ -202,7 +202,12 @@ List<Key> HashTable<T, Key, Hash>::toc() const template<class T, class Key, class Hash> -bool HashTable<T, Key, Hash>::insert(const Key& key, const T& newEntry) +bool HashTable<T, Key, Hash>::set +( + const Key& key, + const T& newEntry, + const bool protect +) { if (tableSize_ == 0) { @@ -210,40 +215,70 @@ bool HashTable<T, Key, Hash>::insert(const Key& key, const T& newEntry) } label ii = Hash()(key, tableSize_); + hashedEntry* existing = 0; + hashedEntry* prev = 0; - for (hashedEntry* n=table_[ii]; n; n=n->next_) + for (hashedEntry* curr = table_[ii]; curr; curr = curr->next_) { - if (key == n->key_) + if (key == curr->key_) + { + existing = curr; + break; + } + prev = curr; + } + + // not found, insert it at the head + if (!existing) + { + table_[ii] = new hashedEntry(key, table_[ii], newEntry); + nElmts_++; + + if (double(nElmts_)/tableSize_ > 0.8) { # ifdef FULLDEBUG if (debug) { - Info<< "HashTable<T, Key, Hash>::insert" - "(const Key& key, T newEntry) : " - "Cannot insert " << key << " already in hash table\n"; + Info<< "HashTable<T, Key, Hash>::set" + "(const Key& key, T newEntry) : " + "Doubling table size\n"; } # endif - return false; + resize(2*tableSize_); } } - - table_[ii] = new hashedEntry(key, table_[ii], newEntry); - - nElmts_++; - - if (double(nElmts_)/tableSize_ > 0.8) + else if (protect) { + // found - but protected from overwriting + // this corresponds to the STL 'insert' convention # ifdef FULLDEBUG if (debug) { - Info<< "HashTable<T, Key, Hash>::insert" - "(const Key& key, T newEntry) : " - "Doubling table size\n"; + Info<< "HashTable<T, Key, Hash>::set" + "(const Key& key, T newEntry, false) : " + "Cannot insert " << key << " already in hash table\n"; } # endif + return false; + } + else + { + // found - overwrite existing entry + // this corresponds to the Perl convention + hashedEntry* elemPtr = new hashedEntry(key, existing->next_, newEntry); + + // replace existing element - within list or insert at the head + if (prev) + { + prev->next_ = elemPtr; + } + else + { + table_[ii] = elemPtr; + } - resize(2*tableSize_); + delete existing; } return true; diff --git a/src/OpenFOAM/containers/HashTables/HashTable/HashTable.H b/src/OpenFOAM/containers/HashTables/HashTable/HashTable.H index b74ac01d336..29dd037e547 100644 --- a/src/OpenFOAM/containers/HashTables/HashTable/HashTable.H +++ b/src/OpenFOAM/containers/HashTables/HashTable/HashTable.H @@ -123,6 +123,11 @@ class HashTable label nElmts_; + // Private Member Functions + + //- Assign a new hashedEntry to a possibly already existing key + bool set(const Key& key, const T& newElmt, bool protect); + public: //- Declare friendship with the HashPtrTable class @@ -181,7 +186,10 @@ public: // Edit //- Insert a new hashedEntry - bool insert(const Key& key, const T& newElmt); + inline bool insert(const Key& key, const T& newElmt); + + //- Assign a new hashedEntry, overwriting existing entries + inline bool set(const Key& key, const T& newElmt); //- Erase an hashedEntry specified by given iterator bool erase(const iterator& it); diff --git a/src/OpenFOAM/containers/HashTables/HashTable/HashTableI.H b/src/OpenFOAM/containers/HashTables/HashTable/HashTableI.H index e934aaa3168..61c5115fa31 100644 --- a/src/OpenFOAM/containers/HashTables/HashTable/HashTableI.H +++ b/src/OpenFOAM/containers/HashTables/HashTable/HashTableI.H @@ -56,6 +56,19 @@ inline label HashTable<T, Key, Hash>::size() const } +template<class T, class Key, class Hash> +inline bool HashTable<T, Key, Hash>::insert(const Key& key, const T& newEntry) +{ + return set(key, newEntry, true); +} + + +template<class T, class Key, class Hash> +inline bool HashTable<T, Key, Hash>::set(const Key& key, const T& newEntry) +{ + return set(key, newEntry, false); +} + // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // template<class T, class Key, class Hash> @@ -292,7 +305,7 @@ inline HashTable<T, Key, Hash>::const_iterator::const_iterator template<class T, class Key, class Hash> inline HashTable<T, Key, Hash>::const_iterator::const_iterator -( +( const iterator& iter ) : diff --git a/src/OpenFOAM/containers/LinkedLists/linkTypes/DLListBase/DLListBase.C b/src/OpenFOAM/containers/LinkedLists/linkTypes/DLListBase/DLListBase.C index a932c788d1f..077040d466c 100644 --- a/src/OpenFOAM/containers/LinkedLists/linkTypes/DLListBase/DLListBase.C +++ b/src/OpenFOAM/containers/LinkedLists/linkTypes/DLListBase/DLListBase.C @@ -229,6 +229,43 @@ DLListBase::link* DLListBase::remove(DLListBase::link* l) } +DLListBase::link* DLListBase::replace +( + DLListBase::link* oldLink, + DLListBase::link* newLink +) +{ + link* ret = oldLink; + + newLink->prev_ = oldLink->prev_; + newLink->next_ = oldLink->next_; + + if (oldLink == first_ && first_ == last_) + { + first_ = newLink; + last_ = newLink; + } + else if (oldLink == first_) + { + first_ = newLink; + newLink->next_->prev_ = newLink; + } + else if (oldLink == last_) + { + last_ = newLink; + newLink->prev_->next_ = newLink; + } + else + { + newLink->prev_->next_ = newLink; + newLink->next_->prev_ = newLink; + } + + ret->deregister(); + return ret; +} + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam diff --git a/src/OpenFOAM/containers/LinkedLists/linkTypes/DLListBase/DLListBase.H b/src/OpenFOAM/containers/LinkedLists/linkTypes/DLListBase/DLListBase.H index 5c7fe6e2c3d..1e51ac5c18c 100644 --- a/src/OpenFOAM/containers/LinkedLists/linkTypes/DLListBase/DLListBase.H +++ b/src/OpenFOAM/containers/LinkedLists/linkTypes/DLListBase/DLListBase.H @@ -158,6 +158,12 @@ public: // Remove and return element specified by iterator inline link* remove(iterator&); + //- Replace oldLink with newLink and return element + link* replace(link* oldLink, link* newLink); + + //- Replace oldIter with newLink and return element + inline link* replace(iterator& oldIter, link* newLink); + //- Clear the list inline void clear(); diff --git a/src/OpenFOAM/containers/LinkedLists/linkTypes/DLListBase/DLListBaseI.H b/src/OpenFOAM/containers/LinkedLists/linkTypes/DLListBase/DLListBaseI.H index 84eec49d336..617253c5e33 100644 --- a/src/OpenFOAM/containers/LinkedLists/linkTypes/DLListBase/DLListBaseI.H +++ b/src/OpenFOAM/containers/LinkedLists/linkTypes/DLListBase/DLListBaseI.H @@ -148,6 +148,16 @@ inline DLListBase::link* DLListBase::remove(DLListBase::iterator& it) } +inline DLListBase::link* DLListBase::replace +( + DLListBase::iterator& oldIter, + DLListBase::link* newLink +) +{ + return replace(oldIter.curElmt_, newLink); +} + + // * * * * * * * * * * * * * * * STL iterator * * * * * * * * * * * * * * * // inline DLListBase::iterator::iterator(DLListBase& s, link* elmt) diff --git a/src/OpenFOAM/db/dictionary/dictionary.C b/src/OpenFOAM/db/dictionary/dictionary.C index aea31e72c77..df4fbd8e565 100644 --- a/src/OpenFOAM/db/dictionary/dictionary.C +++ b/src/OpenFOAM/db/dictionary/dictionary.C @@ -34,6 +34,7 @@ defineTypeNameAndDebug(Foam::dictionary, 0); const Foam::dictionary Foam::dictionary::null; +#undef DICTIONARY_INPLACE_MERGE // * * * * * * * * * * * * * Private member functions * * * * * * * * * * * // @@ -53,7 +54,27 @@ bool Foam::dictionary::add(entry* ePtr, bool mergeEntry) } else { +#ifdef DICTIONARY_INPLACE_MERGE + if (hashedEntries_.set(ePtr->keyword(), ePtr)) + { + ePtr->name() = name_ + "::" + ePtr->keyword(); + replace(iter(), ePtr); + + return true; + } + else + { + IOWarningIn("dictionary::add(entry* ePtr)", (*this)) + << "problem replacing entry in dictionary " + << name() + << endl; + + delete ePtr; + return false; + } +#else remove(ePtr->keyword()); +#endif } } @@ -517,8 +538,12 @@ bool Foam::dictionary::merge(const dictionary& dict) } else { +#ifdef DICTIONARY_INPLACE_MERGE + add(iter().clone(*this).ptr(), true); +#else remove(keyword); add(iter().clone(*this)()); +#endif changed = true; } } @@ -526,6 +551,7 @@ bool Foam::dictionary::merge(const dictionary& dict) { // not found - just add add(iter().clone(*this)()); + changed = true; } } -- GitLab