mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
- lookup(): with a default value (const access)
For example,
Map<label> something;
value = something.lookup(key, -1);
being equivalent to the following:
Map<label> something;
value = -1; // bad value
if (something.found(key))
{
value = something[key];
}
except that lookup also makes it convenient to handle const references.
Eg,
const labelList& ids = someHash.lookup(key, labelList());
- For consistency, provide a two parameter HashTable '()' operator.
The lookup() method is, however, normally preferable when
const-only access is to be ensured.
- retain(): the counterpart to erase(), it only retains entries
corresponding to the listed keys.
For example,
HashTable<someType> largeCache;
wordHashSet preserve = ...;
largeCache.retain(preserve);
being roughly equivalent to the following two-stage process,
but with reduced overhead and typing, and fewer potential mistakes.
HashTable<someType> largeCache;
wordHashSet preserve = ...;
{
wordHashSet cull(largeCache.toc()); // all keys
cull.erase(preserve); // except those to preserve
largeCache.erase(cull); //
}
The HashSet &= operator and retain() are functionally equivalent,
but retain() also works with dissimilar value types.
414 lines
9.1 KiB
C++
414 lines
9.1 KiB
C++
/*---------------------------------------------------------------------------*\
|
|
========= |
|
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
\\ / O peration |
|
|
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
|
\\/ 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 3 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, see <http://www.gnu.org/licenses/>.
|
|
|
|
\*---------------------------------------------------------------------------*/
|
|
|
|
#include "error.H"
|
|
#include "IOstreams.H"
|
|
|
|
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
|
|
|
|
template<class T, class Key, class Hash>
|
|
inline Foam::label
|
|
Foam::StaticHashTable<T, Key, Hash>::hashKeyIndex(const Key& key) const
|
|
{
|
|
// size is power of two - this is the modulus
|
|
return Hash()(key) & (keys_.size() - 1);
|
|
}
|
|
|
|
|
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
|
|
|
template<class T, class Key, class Hash>
|
|
inline Foam::label Foam::StaticHashTable<T, Key, Hash>::size() const
|
|
{
|
|
return nElmts_;
|
|
}
|
|
|
|
|
|
template<class T, class Key, class Hash>
|
|
inline bool Foam::StaticHashTable<T, Key, Hash>::empty() const
|
|
{
|
|
return !nElmts_;
|
|
}
|
|
|
|
|
|
template<class T, class Key, class Hash>
|
|
inline bool Foam::StaticHashTable<T, Key, Hash>::insert
|
|
(
|
|
const Key& key,
|
|
const T& obj
|
|
)
|
|
{
|
|
return set(key, obj, true);
|
|
}
|
|
|
|
|
|
template<class T, class Key, class Hash>
|
|
inline bool Foam::StaticHashTable<T, Key, Hash>::set
|
|
(
|
|
const Key& key,
|
|
const T& obj
|
|
)
|
|
{
|
|
return set(key, obj, false);
|
|
}
|
|
|
|
|
|
template<class T, class Key, class Hash>
|
|
inline Foam::Xfer<Foam::StaticHashTable<T, Key, Hash>>
|
|
Foam::StaticHashTable<T, Key, Hash>::xfer()
|
|
{
|
|
return xferMove(*this);
|
|
}
|
|
|
|
|
|
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
|
|
|
template<class T, class Key, class Hash>
|
|
inline T& Foam::StaticHashTable<T, Key, Hash>::operator[](const Key& key)
|
|
{
|
|
iterator iter = find(key);
|
|
|
|
if (iter == end())
|
|
{
|
|
FatalErrorInFunction
|
|
<< toc()
|
|
<< exit(FatalError);
|
|
}
|
|
|
|
return *iter;
|
|
}
|
|
|
|
|
|
template<class T, class Key, class Hash>
|
|
inline const T& Foam::StaticHashTable<T, Key, Hash>::operator[]
|
|
(
|
|
const Key& key
|
|
) const
|
|
{
|
|
const_iterator iter = find(key);
|
|
|
|
if (iter == cend())
|
|
{
|
|
FatalErrorInFunction
|
|
<< toc()
|
|
<< exit(FatalError);
|
|
}
|
|
|
|
return *iter;
|
|
}
|
|
|
|
|
|
template<class T, class Key, class Hash>
|
|
inline T& Foam::StaticHashTable<T, Key, Hash>::operator()(const Key& key)
|
|
{
|
|
iterator iter = find(key);
|
|
|
|
if (iter == end())
|
|
{
|
|
insert(key, T());
|
|
return *find(key);
|
|
}
|
|
else
|
|
{
|
|
return *iter;
|
|
}
|
|
}
|
|
|
|
|
|
// * * * * * * * * * * * * * * * * STL iterator * * * * * * * * * * * * * * //
|
|
|
|
template<class T, class Key, class Hash>
|
|
template<class TRef, class TableRef>
|
|
inline Foam::StaticHashTable<T, Key, Hash>::Iterator<TRef, TableRef>::Iterator
|
|
(
|
|
TableRef hashTbl,
|
|
label hashIndex,
|
|
label elemIndex
|
|
)
|
|
:
|
|
hashTable_(hashTbl),
|
|
hashIndex_(hashIndex),
|
|
elemIndex_(elemIndex)
|
|
{}
|
|
|
|
|
|
template<class T, class Key, class Hash>
|
|
template<class TRef, class TableRef>
|
|
inline Foam::StaticHashTable<T, Key, Hash>::Iterator<TRef, TableRef>::Iterator
|
|
(
|
|
const iterator& iter
|
|
)
|
|
:
|
|
hashTable_(iter.hashTable_),
|
|
hashIndex_(iter.hashIndex_),
|
|
elemIndex_(iter.elemIndex_)
|
|
{}
|
|
|
|
|
|
template<class T, class Key, class Hash>
|
|
template<class TRef, class TableRef>
|
|
inline void
|
|
Foam::StaticHashTable<T, Key, Hash>::Iterator<TRef, TableRef>::operator=
|
|
(
|
|
const iterator& iter
|
|
)
|
|
{
|
|
this->hashIndex_ = iter.hashIndex_;
|
|
this->elemIndex_ = iter.elemIndex_;
|
|
}
|
|
|
|
|
|
template<class T, class Key, class Hash>
|
|
template<class TRef, class TableRef>
|
|
inline bool
|
|
Foam::StaticHashTable<T, Key, Hash>::Iterator<TRef, TableRef>::operator==
|
|
(
|
|
const iterator& iter
|
|
) const
|
|
{
|
|
return hashIndex_ == iter.hashIndex_ && elemIndex_ == iter.elemIndex_;
|
|
}
|
|
|
|
|
|
template<class T, class Key, class Hash>
|
|
template<class TRef, class TableRef>
|
|
inline bool
|
|
Foam::StaticHashTable<T, Key, Hash>::Iterator<TRef, TableRef>::operator==
|
|
(
|
|
const const_iterator& iter
|
|
) const
|
|
{
|
|
return hashIndex_ == iter.hashIndex_ && elemIndex_ == iter.elemIndex_;
|
|
}
|
|
|
|
|
|
template<class T, class Key, class Hash>
|
|
template<class TRef, class TableRef>
|
|
inline bool
|
|
Foam::StaticHashTable<T, Key, Hash>::Iterator<TRef, TableRef>::operator!=
|
|
(
|
|
const iterator& iter
|
|
) const
|
|
{
|
|
return !operator==(iter);
|
|
}
|
|
|
|
|
|
template<class T, class Key, class Hash>
|
|
template<class TRef, class TableRef>
|
|
inline bool
|
|
Foam::StaticHashTable<T, Key, Hash>::Iterator<TRef, TableRef>::operator!=
|
|
(
|
|
const const_iterator& iter
|
|
) const
|
|
{
|
|
return !operator==(iter);
|
|
}
|
|
|
|
|
|
template<class T, class Key, class Hash>
|
|
template<class TRef, class TableRef>
|
|
inline TRef
|
|
Foam::StaticHashTable<T, Key, Hash>::Iterator<TRef, TableRef>::operator*()
|
|
{
|
|
return hashTable_.objects_[hashIndex_][elemIndex_];
|
|
}
|
|
|
|
|
|
template<class T, class Key, class Hash>
|
|
template<class TRef, class TableRef>
|
|
inline TRef
|
|
Foam::StaticHashTable<T, Key, Hash>::Iterator<TRef, TableRef>::operator()()
|
|
{
|
|
return operator*();
|
|
}
|
|
|
|
|
|
template<class T, class Key, class Hash>
|
|
template<class TRef, class TableRef>
|
|
inline
|
|
typename Foam::StaticHashTable<T, Key, Hash>::template Iterator
|
|
<
|
|
TRef,
|
|
TableRef
|
|
>&
|
|
Foam::StaticHashTable<T, Key, Hash>::Iterator
|
|
<
|
|
TRef,
|
|
TableRef
|
|
>::operator++()
|
|
{
|
|
// A negative index is a special value from erase
|
|
// (see notes in HashTable)
|
|
if (hashIndex_ < 0)
|
|
{
|
|
hashIndex_ = -(hashIndex_+1) - 1;
|
|
}
|
|
else
|
|
{
|
|
// Try the next element on the local list
|
|
elemIndex_++;
|
|
|
|
if (elemIndex_ < hashTable_.objects_[hashIndex_].size())
|
|
{
|
|
return *this;
|
|
}
|
|
}
|
|
|
|
// Step to the next table entry
|
|
elemIndex_ = 0;
|
|
|
|
while
|
|
(
|
|
++hashIndex_ < hashTable_.objects_.size()
|
|
&& !hashTable_.objects_[hashIndex_].size()
|
|
)
|
|
{}
|
|
|
|
|
|
if (hashIndex_ >= hashTable_.objects_.size())
|
|
{
|
|
// make end iterator
|
|
hashIndex_ = hashTable_.keys_.size();
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
|
|
template<class T, class Key, class Hash>
|
|
template<class TRef, class TableRef>
|
|
inline
|
|
typename Foam::StaticHashTable<T, Key, Hash>::template Iterator
|
|
<
|
|
TRef,
|
|
TableRef
|
|
>
|
|
Foam::StaticHashTable<T, Key, Hash>::Iterator
|
|
<
|
|
TRef,
|
|
TableRef
|
|
>::operator++
|
|
(
|
|
int
|
|
)
|
|
{
|
|
iterator tmp = *this;
|
|
++*this;
|
|
return tmp;
|
|
}
|
|
|
|
|
|
template<class T, class Key, class Hash>
|
|
template<class TRef, class TableRef>
|
|
inline const Key&
|
|
Foam::StaticHashTable<T, Key, Hash>::Iterator<TRef, TableRef>::key() const
|
|
{
|
|
return hashTable_.keys_[hashIndex_][elemIndex_];
|
|
}
|
|
|
|
|
|
template<class T, class Key, class Hash>
|
|
inline typename Foam::StaticHashTable<T, Key, Hash>::iterator
|
|
Foam::StaticHashTable<T, Key, Hash>::begin()
|
|
{
|
|
// Find first non-empty entry
|
|
forAll(keys_, hashIdx)
|
|
{
|
|
if (keys_[hashIdx].size())
|
|
{
|
|
return iterator(*this, hashIdx, 0);
|
|
}
|
|
}
|
|
|
|
#ifdef FULLDEBUG
|
|
if (debug)
|
|
{
|
|
Info<< "StaticHashTable is empty\n";
|
|
}
|
|
#endif
|
|
|
|
return StaticHashTable<T, Key, Hash>::endIter_;
|
|
}
|
|
|
|
|
|
template<class T, class Key, class Hash>
|
|
inline const typename Foam::StaticHashTable<T, Key, Hash>::iterator&
|
|
Foam::StaticHashTable<T, Key, Hash>::end()
|
|
{
|
|
return StaticHashTable<T, Key, Hash>::endIter_;
|
|
}
|
|
|
|
|
|
template<class T, class Key, class Hash>
|
|
inline typename Foam::StaticHashTable<T, Key, Hash>::const_iterator
|
|
Foam::StaticHashTable<T, Key, Hash>::cbegin() const
|
|
{
|
|
// Find first non-empty entry
|
|
forAll(keys_, hashIdx)
|
|
{
|
|
if (keys_[hashIdx].size())
|
|
{
|
|
return const_iterator(*this, hashIdx, 0);
|
|
}
|
|
}
|
|
|
|
#ifdef FULLDEBUG
|
|
if (debug)
|
|
{
|
|
Info<< "StaticHashTable is empty\n";
|
|
}
|
|
#endif
|
|
|
|
return StaticHashTable<T, Key, Hash>::endConstIter_;
|
|
}
|
|
|
|
|
|
template<class T, class Key, class Hash>
|
|
inline const typename Foam::StaticHashTable<T, Key, Hash>::const_iterator&
|
|
Foam::StaticHashTable<T, Key, Hash>::cend() const
|
|
{
|
|
return StaticHashTable<T, Key, Hash>::endConstIter_;
|
|
}
|
|
|
|
|
|
template<class T, class Key, class Hash>
|
|
inline typename Foam::StaticHashTable<T, Key, Hash>::const_iterator
|
|
Foam::StaticHashTable<T, Key, Hash>::begin() const
|
|
{
|
|
return this->cbegin();
|
|
}
|
|
|
|
|
|
template<class T, class Key, class Hash>
|
|
inline const typename Foam::StaticHashTable<T, Key, Hash>::const_iterator&
|
|
Foam::StaticHashTable<T, Key, Hash>::end() const
|
|
{
|
|
return StaticHashTable<T, Key, Hash>::endConstIter_;
|
|
}
|
|
|
|
|
|
// ************************************************************************* //
|