DEFEATURE: remove StaticHashTable
- unused, unmaintained and slower than the regular HashTable
This commit is contained in:
parent
930d6dcaf2
commit
db552fb751
@ -30,7 +30,6 @@ Description
|
||||
#include "HashTable.H"
|
||||
#include "HashPtrTable.H"
|
||||
#include "Map.H"
|
||||
#include "StaticHashTable.H"
|
||||
#include "cpuTime.H"
|
||||
|
||||
using namespace Foam;
|
||||
@ -57,7 +56,6 @@ int main(int argc, char *argv[])
|
||||
// ie, a
|
||||
// Map<label> map(2 * nSize);
|
||||
// HashTable<label, label, Hash<label>> map(2 * nSize);
|
||||
// StaticHashTable<label, label, Hash<label>> map(2 * nSize);
|
||||
HashTable<label, label, Hash<label>> map(2 * nSize);
|
||||
|
||||
Info<< "Constructed map of size: " << nSize;
|
||||
|
@ -31,14 +31,12 @@ Description
|
||||
#include "boolList.H"
|
||||
#include "PackedBoolList.H"
|
||||
#include "HashSet.H"
|
||||
#include "StaticHashTable.H"
|
||||
#include "cpuTime.H"
|
||||
#include <vector>
|
||||
#include <unordered_set>
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
#undef TEST_STATIC_HASH
|
||||
#undef TEST_STD_BOOLLIST
|
||||
#undef TEST_STD_UNORDERED_SET
|
||||
|
||||
@ -84,20 +82,6 @@ int main(int argc, char *argv[])
|
||||
Info<< "populated labelHashSet in "
|
||||
<< timer.cpuTimeIncrement() << " s\n\n";
|
||||
|
||||
|
||||
#ifdef TEST_STATIC_HASH
|
||||
// fullStaticHash is really slow
|
||||
// give it lots of slots to help
|
||||
StaticHashTable<nil, label, Hash<label>> emptyStaticHash;
|
||||
StaticHashTable<nil, label, Hash<label>> fullStaticHash(100000);
|
||||
for (label i = 0; i < n; i++)
|
||||
{
|
||||
fullStaticHash.insert(i, nil());
|
||||
}
|
||||
Info<< "populated StaticHashTable in "
|
||||
<< timer.cpuTimeIncrement() << " s\n\n";
|
||||
#endif
|
||||
|
||||
#ifdef TEST_STD_UNORDERED_SET
|
||||
std::unordered_set<label, Foam::Hash<label>> emptyStdHash;
|
||||
std::unordered_set<label, Foam::Hash<label>> fullStdHash;
|
||||
@ -112,10 +96,6 @@ int main(int argc, char *argv[])
|
||||
|
||||
emptyHash.printInfo(Info);
|
||||
fullHash.printInfo(Info);
|
||||
#ifdef TEST_STATIC_HASH
|
||||
emptyStaticHash.printInfo(Info);
|
||||
fullStaticHash.printInfo(Info);
|
||||
#endif
|
||||
#ifdef TEST_STD_UNORDERED_SET
|
||||
printInfo(emptyStdHash);
|
||||
printInfo(fullStdHash);
|
||||
@ -305,37 +285,6 @@ int main(int argc, char *argv[])
|
||||
<< " sum " << sum << nl;
|
||||
|
||||
|
||||
#ifdef TEST_STATIC_HASH
|
||||
// Read empty StaticHashTable
|
||||
sum = 0;
|
||||
for (label iter = 0; iter < nIters; ++iter)
|
||||
{
|
||||
forAll(unpacked, i)
|
||||
{
|
||||
sum += emptyStaticHash.found(i);
|
||||
}
|
||||
}
|
||||
std::cout
|
||||
<< "Reading empty StaticHash:" << timer.cpuTimeIncrement()
|
||||
<< " s" << nl
|
||||
<< " sum " << sum << nl;
|
||||
|
||||
// Read full StaticHashTable
|
||||
sum = 0;
|
||||
for (label iter = 0; iter < nIters; ++iter)
|
||||
{
|
||||
forAll(unpacked, i)
|
||||
{
|
||||
sum += fullStaticHash.found(i);
|
||||
}
|
||||
}
|
||||
std::cout
|
||||
<< "Reading full StaticHash:" << timer.cpuTimeIncrement()
|
||||
<< " s" << nl
|
||||
<< " sum " << sum << nl;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef TEST_STD_UNORDERED_SET
|
||||
// Read empty stl set
|
||||
sum = 0;
|
||||
|
@ -1,3 +0,0 @@
|
||||
Test-staticHashTable.C
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-staticHashTable
|
@ -1,170 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 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 "StaticHashTable.H"
|
||||
#include "IOstreams.H"
|
||||
#include "StringStream.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
// use define so we can easily test other implementations
|
||||
#define HASHTABLE_CLASS StaticHashTable
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
// Main program:
|
||||
|
||||
int main()
|
||||
{
|
||||
HASHTABLE_CLASS<double> table1(13);
|
||||
|
||||
table1.insert("aaa", 1.0);
|
||||
table1.insert("aba", 2.0);
|
||||
table1.insert("aca", 3.0);
|
||||
table1.insert("ada", 4.0);
|
||||
table1.insert("aeq", 5.0);
|
||||
table1.insert("aaw", 6.0);
|
||||
table1.insert("abs", 7.0);
|
||||
table1.insert("acr", 8.0);
|
||||
table1.insert("adx", 9.0);
|
||||
table1.insert("aec", 10.0);
|
||||
|
||||
table1.erase("aaw");
|
||||
table1.erase("abs");
|
||||
|
||||
Info<< "\ntable1 toc: " << table1.toc() << endl;
|
||||
table1.printInfo(Info)
|
||||
<< "table1 [" << table1.size() << "] " << endl;
|
||||
forAllIter(HASHTABLE_CLASS<double>, table1, iter)
|
||||
{
|
||||
Info<< iter.key() << " => " << iter() << nl;
|
||||
}
|
||||
|
||||
table1.set("acr", 108);
|
||||
table1.set("adx", 109);
|
||||
table1.set("aec", 100);
|
||||
table1("aaw") -= 1000;
|
||||
table1("aeq") += 1000;
|
||||
|
||||
Info<< "\noverwrote some values table1: " << table1 << endl;
|
||||
|
||||
Info<< "\ntest find:" << endl;
|
||||
Info<< table1.find("aaa")() << nl
|
||||
<< table1.find("aba")() << nl
|
||||
<< table1.find("aca")() << nl
|
||||
<< table1.find("ada")() << nl
|
||||
<< table1.find("aeq")() << nl
|
||||
<< table1.find("acr")() << nl
|
||||
<< table1.find("adx")() << nl
|
||||
<< table1.find("aec")() << nl
|
||||
<< table1["aaa"] << nl;
|
||||
|
||||
{
|
||||
OStringStream os;
|
||||
os << table1;
|
||||
HASHTABLE_CLASS<double> readTable(IStringStream(os.str())(), 100);
|
||||
|
||||
Info<< "Istream constructor:" << readTable << endl;
|
||||
}
|
||||
|
||||
|
||||
HASHTABLE_CLASS<double> table2(table1);
|
||||
HASHTABLE_CLASS<double> table3(table1.xfer());
|
||||
|
||||
Info<< "\ncopy table1 -> table2" << nl
|
||||
<< "transfer table1 -> table3 via the xfer() method" << nl;
|
||||
|
||||
Info<< "\ntable1" << table1 << nl
|
||||
<< "\ntable2" << table2 << nl
|
||||
<< "\ntable3" << table3 << nl;
|
||||
|
||||
Info<< "\nerase table2 by iterator" << nl;
|
||||
forAllIter(HASHTABLE_CLASS<double>, table2, iter)
|
||||
{
|
||||
Info<< "erasing " << iter.key() << " => " << iter() << " ... ";
|
||||
table2.erase(iter);
|
||||
Info<< "erased" << endl;
|
||||
}
|
||||
|
||||
Info<< "\ntable1" << table1 << nl
|
||||
<< "\ntable2" << table2 << nl
|
||||
<< "\ntable3" << table3 << nl;
|
||||
|
||||
table3.resize(1);
|
||||
Info<< "\nresize(1) table3" << nl;
|
||||
table3.printInfo(Info)
|
||||
<< table3 << nl;
|
||||
|
||||
table3.resize(10000);
|
||||
Info<< "\nresize(10000) table3" << nl;
|
||||
table3.printInfo(Info)
|
||||
<< table3 << nl;
|
||||
|
||||
HASHTABLE_CLASS<double> table4;
|
||||
|
||||
table4 = table3;
|
||||
Info<< "\ncopy table3 -> table4 " << table4 << nl;
|
||||
|
||||
Info<< "\nclear table4 ... ";
|
||||
table4.clear();
|
||||
Info<< "[" << table4.size() << "] " << table4 << nl;
|
||||
|
||||
table1 = table3;
|
||||
Info<< "\ncopy table3 -> table1 (previously transferred)" << table1 << nl;
|
||||
|
||||
Info<< "test table1 == table3 : " << (table1 == table3) << nl;
|
||||
table1.erase(table1.begin());
|
||||
Info<< "removed an element - test table1 != table3 : "
|
||||
<< (table1 != table3) << nl;
|
||||
|
||||
// insert a few things into table2
|
||||
table2.set("ada", 14.0);
|
||||
table2.set("aeq", 15.0);
|
||||
table2.set("aaw", 16.0);
|
||||
table2.set("abs", 17.0);
|
||||
table2.set("adx", 20.0);
|
||||
|
||||
Info<< "\ntable1" << table1 << nl
|
||||
<< "\ntable2" << table2 << nl;
|
||||
|
||||
label nErased = table1.erase(table2);
|
||||
|
||||
Info<< "\nerase table2 keys from table1 (removed "
|
||||
<< nErased << " elements)" << nl
|
||||
<< "\ntable1" << table1 << nl
|
||||
<< "\ntable2" << table2 << nl;
|
||||
|
||||
|
||||
Info<< "\ntable3" << table3
|
||||
<< "\nclearStorage table3 ... ";
|
||||
table3.clearStorage();
|
||||
Info<< table3 << nl;
|
||||
|
||||
Info<< "\nDone\n";
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
@ -337,7 +337,6 @@ DebugSwitches
|
||||
SpalartAllmarasIDDES 0;
|
||||
SphereDrag 0;
|
||||
StandardWallInteraction 0;
|
||||
StaticHashTable 0;
|
||||
StochasticDispersionRAS 0;
|
||||
SuperBee 0;
|
||||
SuperBeeV 0;
|
||||
|
@ -147,7 +147,6 @@ primitives/Barycentric/barycentric/barycentric.C
|
||||
primitives/Barycentric2D/barycentric2D/barycentric2D.C
|
||||
|
||||
containers/HashTables/HashTable/HashTableCore.C
|
||||
containers/HashTables/StaticHashTable/StaticHashTableCore.C
|
||||
containers/Lists/SortableList/ParSortableListName.C
|
||||
containers/Lists/PackedList/PackedListCore.C
|
||||
containers/Lists/PackedList/PackedBoolList.C
|
||||
|
@ -1,530 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef StaticHashTable_C
|
||||
#define StaticHashTable_C
|
||||
|
||||
#include "StaticHashTable.H"
|
||||
#include "List.H"
|
||||
#include "IOstreams.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
Foam::StaticHashTable<T, Key, Hash>::StaticHashTable(const label size)
|
||||
:
|
||||
StaticHashTableCore(),
|
||||
keys_(StaticHashTableCore::canonicalSize(size)),
|
||||
objects_(keys_.size()),
|
||||
nElmts_(0),
|
||||
endIter_(*this, keys_.size(), 0),
|
||||
endConstIter_(*this, keys_.size(), 0)
|
||||
{
|
||||
if (size < 1)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Illegal size " << size << " for StaticHashTable."
|
||||
<< " Minimum size is 1" << abort(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
Foam::StaticHashTable<T, Key, Hash>::StaticHashTable
|
||||
(
|
||||
const StaticHashTable<T, Key, Hash>& ht
|
||||
)
|
||||
:
|
||||
StaticHashTableCore(),
|
||||
keys_(ht.keys_),
|
||||
objects_(ht.objects_),
|
||||
nElmts_(ht.nElmts_),
|
||||
endIter_(*this, keys_.size(), 0),
|
||||
endConstIter_(*this, keys_.size(), 0)
|
||||
{}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
Foam::StaticHashTable<T, Key, Hash>::StaticHashTable
|
||||
(
|
||||
const Xfer<StaticHashTable<T, Key, Hash>>& ht
|
||||
)
|
||||
:
|
||||
StaticHashTableCore(),
|
||||
keys_(0),
|
||||
objects_(0),
|
||||
nElmts_(0),
|
||||
endIter_(*this, 0, 0),
|
||||
endConstIter_(*this, 0, 0)
|
||||
{
|
||||
transfer(ht());
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
Foam::StaticHashTable<T, Key, Hash>::~StaticHashTable()
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
bool Foam::StaticHashTable<T, Key, Hash>::found(const Key& key) const
|
||||
{
|
||||
if (nElmts_)
|
||||
{
|
||||
const label hashIdx = hashKeyIndex(key);
|
||||
const List<Key>& localKeys = keys_[hashIdx];
|
||||
|
||||
forAll(localKeys, elemIdx)
|
||||
{
|
||||
if (key == localKeys[elemIdx])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef FULLDEBUG
|
||||
if (debug)
|
||||
{
|
||||
InfoInFunction << "Entry " << key << " not found in hash table\n";
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
typename Foam::StaticHashTable<T, Key, Hash>::iterator
|
||||
Foam::StaticHashTable<T, Key, Hash>::find
|
||||
(
|
||||
const Key& key
|
||||
)
|
||||
{
|
||||
if (nElmts_)
|
||||
{
|
||||
const label hashIdx = hashKeyIndex(key);
|
||||
const List<Key>& localKeys = keys_[hashIdx];
|
||||
|
||||
forAll(localKeys, elemIdx)
|
||||
{
|
||||
if (key == localKeys[elemIdx])
|
||||
{
|
||||
return iterator(*this, hashIdx, elemIdx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef FULLDEBUG
|
||||
if (debug)
|
||||
{
|
||||
InfoInFunction << "Entry " << key << " not found in hash table\n";
|
||||
}
|
||||
#endif
|
||||
|
||||
return end();
|
||||
}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
typename Foam::StaticHashTable<T, Key, Hash>::const_iterator
|
||||
Foam::StaticHashTable<T, Key, Hash>::find
|
||||
(
|
||||
const Key& key
|
||||
) const
|
||||
{
|
||||
return this->cfind(key);
|
||||
}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
typename Foam::StaticHashTable<T, Key, Hash>::const_iterator
|
||||
Foam::StaticHashTable<T, Key, Hash>::cfind
|
||||
(
|
||||
const Key& key
|
||||
) const
|
||||
{
|
||||
if (nElmts_)
|
||||
{
|
||||
const label hashIdx = hashKeyIndex(key);
|
||||
const List<Key>& localKeys = keys_[hashIdx];
|
||||
|
||||
forAll(localKeys, elemIdx)
|
||||
{
|
||||
if (key == localKeys[elemIdx])
|
||||
{
|
||||
return const_iterator(*this, hashIdx, elemIdx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef FULLDEBUG
|
||||
if (debug)
|
||||
{
|
||||
InfoInFunction << "Entry " << key << " not found in hash table\n";
|
||||
}
|
||||
#endif
|
||||
|
||||
return cend();
|
||||
}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
Foam::List<Key> Foam::StaticHashTable<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>
|
||||
bool Foam::StaticHashTable<T, Key, Hash>::set
|
||||
(
|
||||
const Key& key,
|
||||
const T& obj,
|
||||
const bool protect
|
||||
)
|
||||
{
|
||||
const label hashIdx = hashKeyIndex(key);
|
||||
List<Key>& localKeys = keys_[hashIdx];
|
||||
|
||||
label existing = localKeys.size();
|
||||
forAll(localKeys, elemIdx)
|
||||
{
|
||||
if (key == localKeys[elemIdx])
|
||||
{
|
||||
existing = elemIdx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (existing == localKeys.size())
|
||||
{
|
||||
// Not found, append
|
||||
List<T>& localObjects = objects_[hashIdx];
|
||||
|
||||
localKeys.setSize(existing+1);
|
||||
localObjects.setSize(existing+1);
|
||||
|
||||
localKeys[existing] = key;
|
||||
localObjects[existing] = obj;
|
||||
|
||||
nElmts_++;
|
||||
}
|
||||
else if (protect)
|
||||
{
|
||||
// Found - but protected from overwriting
|
||||
// this corresponds to the STL 'insert' convention
|
||||
#ifdef FULLDEBUG
|
||||
if (debug)
|
||||
{
|
||||
InfoInFunction
|
||||
<< "Cannot insert " << key << " already in hash table\n";
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Found - overwrite existing entry
|
||||
// this corresponds to the Perl convention
|
||||
objects_[hashIdx][existing] = obj;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
bool Foam::StaticHashTable<T, Key, Hash>::erase(const iterator& cit)
|
||||
{
|
||||
if (cit != end())
|
||||
{
|
||||
List<Key>& localKeys = keys_[cit.hashIndex_];
|
||||
List<T>& localObjects = objects_[cit.hashIndex_];
|
||||
|
||||
// Copy down
|
||||
for (label i = cit.elemIndex_+1; i < localKeys.size(); i++)
|
||||
{
|
||||
localKeys[i-1] = localKeys[i];
|
||||
localObjects[i-1] = localObjects[i];
|
||||
}
|
||||
localKeys.setSize(localKeys.size()-1);
|
||||
localObjects.setSize(localObjects.size()-1);
|
||||
|
||||
// Adjust iterator after erase
|
||||
iterator& it = const_cast<iterator&>(cit);
|
||||
|
||||
it.elemIndex_--;
|
||||
if (it.elemIndex_ < 0)
|
||||
{
|
||||
// No previous element in the local list
|
||||
// Mark with as special value (see notes in HashTable)
|
||||
it.hashIndex_ = -it.hashIndex_ - 1;
|
||||
it.elemIndex_ = 0;
|
||||
}
|
||||
|
||||
nElmts_--;
|
||||
|
||||
#ifdef FULLDEBUG
|
||||
if (debug)
|
||||
{
|
||||
InfoInFunction << "hashedEntry removed.\n";
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef FULLDEBUG
|
||||
if (debug)
|
||||
{
|
||||
InfoInFunction
|
||||
<< "Cannot remove hashedEntry from hash table\n";
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
bool Foam::StaticHashTable<T, Key, Hash>::erase(const Key& key)
|
||||
{
|
||||
iterator it = find(key);
|
||||
|
||||
if (it != end())
|
||||
{
|
||||
return erase(it);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
Foam::label Foam::StaticHashTable<T, Key, Hash>::erase
|
||||
(
|
||||
const StaticHashTable<T, Key, Hash>& rhs
|
||||
)
|
||||
{
|
||||
label count = 0;
|
||||
|
||||
// Remove rhs elements from this table
|
||||
// NOTE: could optimize depending on which hash is smaller
|
||||
for (iterator iter = this->begin(); iter != this->end(); ++iter)
|
||||
{
|
||||
if (rhs.found(iter.key()) && erase(iter))
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
void Foam::StaticHashTable<T, Key, Hash>::resize(const label sz)
|
||||
{
|
||||
label newSize = StaticHashTableCore::canonicalSize(sz);
|
||||
|
||||
if (newSize == keys_.size())
|
||||
{
|
||||
#ifdef FULLDEBUG
|
||||
if (debug)
|
||||
{
|
||||
InfoInFunction << "New table size == old table size\n";
|
||||
}
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (newSize < 1)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Illegal size " << newSize << " for StaticHashTable."
|
||||
<< " Minimum size is 1" << abort(FatalError);
|
||||
}
|
||||
|
||||
|
||||
StaticHashTable<T, Key, Hash> newTable(newSize);
|
||||
|
||||
for (const_iterator iter = cbegin(); iter != cend(); ++iter)
|
||||
{
|
||||
newTable.insert(iter.key(), *iter);
|
||||
}
|
||||
|
||||
transfer(newTable);
|
||||
|
||||
// Adapt end() iterators
|
||||
endIter_.hashIndex_ = keys_.size();
|
||||
endConstIter_.hashIndex_ = keys_.size();
|
||||
}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
void Foam::StaticHashTable<T, Key, Hash>::clear()
|
||||
{
|
||||
forAll(keys_, hashIdx)
|
||||
{
|
||||
keys_[hashIdx].clear();
|
||||
objects_[hashIdx].clear();
|
||||
}
|
||||
|
||||
nElmts_ = 0;
|
||||
}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
void Foam::StaticHashTable<T, Key, Hash>::clearStorage()
|
||||
{
|
||||
clear();
|
||||
resize(1);
|
||||
}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
void Foam::StaticHashTable<T, Key, Hash>::transfer
|
||||
(
|
||||
StaticHashTable<T, Key, Hash>& ht
|
||||
)
|
||||
{
|
||||
// Remove existing elements
|
||||
clear();
|
||||
|
||||
// Copy data from ht
|
||||
keys_.transfer(ht.keys_);
|
||||
objects_.transfer(ht.objects_);
|
||||
|
||||
nElmts_ = ht.nElmts_;
|
||||
ht.nElmts_ = 0;
|
||||
|
||||
// Adapt end() iterators
|
||||
endIter_.hashIndex_ = keys_.size();
|
||||
endConstIter_.hashIndex_ = keys_.size();
|
||||
|
||||
ht.endIter_.hashIndex_ = 0;
|
||||
ht.endConstIter_.hashIndex_ = 0;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
void Foam::StaticHashTable<T, Key, Hash>::operator=
|
||||
(
|
||||
const StaticHashTable<T, Key, Hash>& rhs
|
||||
)
|
||||
{
|
||||
// Check for assignment to self
|
||||
if (this == &rhs)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "attempted assignment to self"
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
|
||||
// keys could be empty from a previous transfer()
|
||||
if (keys_.empty())
|
||||
{
|
||||
keys_.setSize(rhs.keys_.size());
|
||||
objects_.setSize(keys_.size());
|
||||
|
||||
// Adapt end() iterators
|
||||
endIter_.hashIndex_ = keys_.size();
|
||||
endConstIter_.hashIndex_ = keys_.size();
|
||||
}
|
||||
else
|
||||
{
|
||||
clear();
|
||||
// keys_.size() does not change so neither does end() iterator.
|
||||
}
|
||||
|
||||
|
||||
for (const_iterator iter = rhs.cbegin(); iter != rhs.cend(); ++iter)
|
||||
{
|
||||
insert(iter.key(), *iter);
|
||||
}
|
||||
}
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
bool Foam::StaticHashTable<T, Key, Hash>::operator==
|
||||
(
|
||||
const StaticHashTable<T, Key, Hash>& rhs
|
||||
) const
|
||||
{
|
||||
// Sizes (number of keys) must match
|
||||
|
||||
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::StaticHashTable<T, Key, Hash>::operator!=
|
||||
(
|
||||
const StaticHashTable<T, Key, Hash>& rhs
|
||||
) const
|
||||
{
|
||||
return !(operator==(rhs));
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
|
||||
|
||||
#include "StaticHashTableIO.C"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
@ -1,415 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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/>.
|
||||
|
||||
Class
|
||||
Foam::StaticHashTable
|
||||
|
||||
Description
|
||||
STL conforming hash table.
|
||||
|
||||
Note
|
||||
Uses straight lists as underlying type.
|
||||
Is slower to insert than the standard HashTable, but should be more
|
||||
memory efficient and faster to access.
|
||||
|
||||
SourceFiles
|
||||
StaticHashTableI.H
|
||||
StaticHashTable.C
|
||||
StaticHashTableIO.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef StaticHashTable_H
|
||||
#define StaticHashTable_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 Key, class Hash> class StaticHashTable;
|
||||
|
||||
template<class T, class Key, class Hash> Istream& operator>>
|
||||
(
|
||||
Istream&,
|
||||
StaticHashTable<T, Key, Hash>&
|
||||
);
|
||||
|
||||
template<class T, class Key, class Hash> Ostream& operator<<
|
||||
(
|
||||
Ostream&,
|
||||
const StaticHashTable<T, Key, Hash>&
|
||||
);
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class StaticHashTableCore Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
//- Template-invariant bits for StaticHashTable
|
||||
struct StaticHashTableCore
|
||||
{
|
||||
//- Return a canonical (power-of-two) of the requested size.
|
||||
static label canonicalSize(const label requested_size);
|
||||
|
||||
//- Construct null
|
||||
StaticHashTableCore()
|
||||
{}
|
||||
|
||||
//- Define template name and debug
|
||||
ClassName("StaticHashTable");
|
||||
|
||||
//- A zero-sized end iterator
|
||||
struct iteratorEnd
|
||||
{
|
||||
//- Construct null
|
||||
iteratorEnd()
|
||||
{}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class StaticHashTable Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
template<class T, class Key=word, class Hash=string::hash>
|
||||
class StaticHashTable
|
||||
:
|
||||
public StaticHashTableCore
|
||||
{
|
||||
// Private data type for table entries
|
||||
|
||||
//- The lookup keys, ordered per hash value
|
||||
List<List<Key>> keys_;
|
||||
|
||||
//- For each key the corresponding object.
|
||||
List<List<T>> objects_;
|
||||
|
||||
//- The current number of elements in table
|
||||
label nElmts_;
|
||||
|
||||
//- Return the hash index of the Key within the current table size.
|
||||
// No checks for zero-sized tables.
|
||||
inline label hashKeyIndex(const Key& key) const;
|
||||
|
||||
//- Assign a new hashed entry to a possibly already existing key
|
||||
bool set(const Key& key, const T& obj, bool protect);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
|
||||
// Forward declaration of STL iterators
|
||||
|
||||
template<class TRef, class TableRef>
|
||||
class Iterator;
|
||||
|
||||
typedef Iterator
|
||||
<
|
||||
T&,
|
||||
StaticHashTable<T, Key, Hash>&
|
||||
> iterator;
|
||||
|
||||
typedef Iterator
|
||||
<
|
||||
const T&,
|
||||
const StaticHashTable<T, Key, Hash>&
|
||||
> const_iterator;
|
||||
|
||||
|
||||
// Declare friendship with the iterators
|
||||
|
||||
friend class Iterator
|
||||
<
|
||||
T&,
|
||||
StaticHashTable<T, Key, Hash>&
|
||||
>;
|
||||
|
||||
friend class Iterator
|
||||
<
|
||||
const T&,
|
||||
const StaticHashTable<T, Key, Hash>&
|
||||
>;
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct given initial table size
|
||||
StaticHashTable(const label size = 128);
|
||||
|
||||
//- Construct from Istream
|
||||
StaticHashTable(Istream&, const label size = 128);
|
||||
|
||||
//- Construct as copy
|
||||
StaticHashTable(const StaticHashTable<T, Key, Hash>&);
|
||||
|
||||
//- Construct by transferring the parameter contents
|
||||
StaticHashTable(const Xfer<StaticHashTable<T, Key, Hash>>&);
|
||||
|
||||
|
||||
//- Destructor
|
||||
~StaticHashTable();
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Access
|
||||
|
||||
//- 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 hashed entry is found in table
|
||||
bool found(const Key& key) const;
|
||||
|
||||
//- Find and return an iterator set at the hashed entry
|
||||
// If not found iterator = end()
|
||||
iterator find(const Key& key);
|
||||
|
||||
//- Find and return an const_iterator set at the hashed entry
|
||||
// If not found iterator = end()
|
||||
const_iterator find(const Key& key) const;
|
||||
|
||||
//- Find and return an const_iterator set at the hashed entry
|
||||
// If not found iterator = end()
|
||||
const_iterator cfind(const Key& key) const;
|
||||
|
||||
//- Return the table of contents
|
||||
List<Key> toc() const;
|
||||
|
||||
//- Print information
|
||||
Ostream& printInfo(Ostream&) const;
|
||||
|
||||
|
||||
// Edit
|
||||
|
||||
//- Insert a new hashed entry
|
||||
bool insert(const Key& key, const T& newElmt);
|
||||
|
||||
//- Assign a new hashed entry, overwriting existing entries
|
||||
inline bool set(const Key&, const T& newElmt);
|
||||
|
||||
//- Erase an hashed entry specified by given iterator
|
||||
bool erase(const iterator& it);
|
||||
|
||||
//- Erase an hashed entry specified by given key if in table
|
||||
bool erase(const Key& key);
|
||||
|
||||
//- Resize the hash table for efficiency
|
||||
void resize(const label newSize);
|
||||
|
||||
//- Remove entries in the given hash table from this hash table
|
||||
// Return the number of elements removed
|
||||
label erase(const StaticHashTable<T, Key, Hash>&);
|
||||
|
||||
//- Clear all entries from table
|
||||
void clear();
|
||||
|
||||
//- Clear the table entries and the table itself.
|
||||
// Equivalent to clear() followed by resize(1)
|
||||
void clearStorage();
|
||||
|
||||
//- Transfer the contents of the argument table into this table
|
||||
// and annul the argument table.
|
||||
void transfer(StaticHashTable<T, Key, Hash>&);
|
||||
|
||||
//- Transfer contents to the Xfer container
|
||||
inline Xfer<StaticHashTable<T, Key, Hash>> xfer();
|
||||
|
||||
|
||||
// Member Operators
|
||||
|
||||
//- Find and return an hashed entry
|
||||
inline T& operator[](const Key&);
|
||||
|
||||
//- Find and return an hashed entry
|
||||
inline const T& operator[](const Key&) const;
|
||||
|
||||
//- Find and return an hashed entry, create it null if not present.
|
||||
inline T& operator()(const Key&);
|
||||
|
||||
//- Assignment
|
||||
void operator=(const StaticHashTable<T, Key, Hash>&);
|
||||
|
||||
//- Equality. Two hash tables are equal if all contents of first are
|
||||
// also in second and vice versa.
|
||||
bool operator==(const StaticHashTable<T, Key, Hash>&) const;
|
||||
|
||||
//- The opposite of the equality operation.
|
||||
bool operator!=(const StaticHashTable<T, Key, Hash>&) const;
|
||||
|
||||
|
||||
// STL type definitions
|
||||
|
||||
//- Type of values the StaticHashTable contains.
|
||||
typedef T value_type;
|
||||
|
||||
//- Type that can be used for storing into StaticHashTable::value_type
|
||||
// objects. This type is usually List::value_type&.
|
||||
typedef T& reference;
|
||||
|
||||
//- Type that can be used for storing into constant
|
||||
// StaticHashTable::value_type objects. This type is usually const
|
||||
// StaticHashTable::value_type&.
|
||||
typedef const T& const_reference;
|
||||
|
||||
//- The type that can represent the size of a StaticHashTable.
|
||||
typedef label size_type;
|
||||
|
||||
|
||||
// STL iterator
|
||||
|
||||
//- An STL iterator
|
||||
template<class TRef, class TableRef>
|
||||
class Iterator
|
||||
{
|
||||
friend class StaticHashTable;
|
||||
|
||||
template<class TRef2, class TableRef2>
|
||||
friend class Iterator;
|
||||
|
||||
// Private data
|
||||
|
||||
//- Reference to the StaticHashTable this is an iterator for
|
||||
TableRef hashTable_;
|
||||
|
||||
//- Current hash index
|
||||
label hashIndex_;
|
||||
|
||||
//- Index of current element at hashIndex
|
||||
label elemIndex_;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from hash table, hash index and element index
|
||||
inline Iterator
|
||||
(
|
||||
TableRef,
|
||||
label hashIndex_,
|
||||
label elemIndex_
|
||||
);
|
||||
|
||||
//- Construct from the non-const iterator
|
||||
inline Iterator(const iterator&);
|
||||
|
||||
|
||||
// Member operators
|
||||
|
||||
inline void operator=(const iterator&);
|
||||
|
||||
inline bool operator==(const iterator&) const;
|
||||
inline bool operator==(const const_iterator&) const;
|
||||
|
||||
inline bool operator!=(const iterator&) const;
|
||||
inline bool operator!=(const const_iterator&) const;
|
||||
|
||||
inline TRef operator*();
|
||||
inline TRef operator()();
|
||||
|
||||
inline Iterator& operator++();
|
||||
inline Iterator operator++(int);
|
||||
|
||||
inline const Key& key() const;
|
||||
};
|
||||
|
||||
|
||||
//- Iterator set to the beginning of the StaticHashTable
|
||||
inline iterator begin();
|
||||
|
||||
//- Iterator set to beyond the end of the StaticHashTable
|
||||
inline const iterator& end();
|
||||
|
||||
//- const_iterator set to the beginning of the StaticHashTable
|
||||
inline const_iterator cbegin() const;
|
||||
|
||||
//- const_iterator set to beyond the end of the StaticHashTable
|
||||
inline const const_iterator& cend() const;
|
||||
|
||||
//- const_iterator set to the beginning of the StaticHashTable
|
||||
inline const_iterator begin() const;
|
||||
|
||||
//- const_iterator set to beyond the end of the StaticHashTable
|
||||
inline const const_iterator& end() const;
|
||||
|
||||
// IOstream Operator
|
||||
|
||||
friend Istream& operator>> <T, Key, Hash>
|
||||
(
|
||||
Istream&,
|
||||
StaticHashTable<T, Key, Hash>&
|
||||
);
|
||||
|
||||
friend Ostream& operator<< <T, Key, Hash>
|
||||
(
|
||||
Ostream&,
|
||||
const StaticHashTable<T, Key, Hash>&
|
||||
);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
//- Iterator returned by end()
|
||||
iterator endIter_;
|
||||
|
||||
//- const_iterator returned by end()
|
||||
const_iterator endConstIter_;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#include "StaticHashTableI.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifndef NoStaticHashTableC
|
||||
#ifdef NoRepository
|
||||
#include "StaticHashTable.C"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
@ -1,86 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2012 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 "StaticHashTable.H"
|
||||
#include "uLabel.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(StaticHashTableCore, 0);
|
||||
}
|
||||
|
||||
|
||||
// Approximately labelMax/4
|
||||
static const Foam::label maxTableSize(1L << (sizeof(Foam::label)*8-3));
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::label Foam::StaticHashTableCore::canonicalSize(const label requested_size)
|
||||
{
|
||||
if (requested_size < 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (requested_size >= maxTableSize)
|
||||
{
|
||||
return maxTableSize;
|
||||
}
|
||||
|
||||
// Enforce power of two - makes for a very fast modulus.
|
||||
// Use unsigned for these calculations.
|
||||
//
|
||||
// - The lower limit (8) is somewhat arbitrary, but if the hash table
|
||||
// is too small, there will be many direct table collisions.
|
||||
// - The upper limit (approx. labelMax/4) must be a power of two,
|
||||
// need not be extremely large for hashing.
|
||||
|
||||
uLabel powerOfTwo = 8u; // lower-limit
|
||||
|
||||
const uLabel size = requested_size;
|
||||
if (size <= powerOfTwo)
|
||||
{
|
||||
return powerOfTwo;
|
||||
}
|
||||
else if (size & (size-1)) // <- Modulus of i^2
|
||||
{
|
||||
// Determine power-of-two. Brute-force is fast enough.
|
||||
while (powerOfTwo < size)
|
||||
{
|
||||
powerOfTwo <<= 1;
|
||||
}
|
||||
|
||||
return powerOfTwo;
|
||||
}
|
||||
else
|
||||
{
|
||||
return size;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
@ -1,399 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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_;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
@ -1,237 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2015 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 "StaticHashTable.H"
|
||||
#include "Istream.H"
|
||||
#include "Ostream.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
Foam::StaticHashTable<T, Key, Hash>::StaticHashTable
|
||||
(
|
||||
Istream& is,
|
||||
const label size
|
||||
)
|
||||
:
|
||||
StaticHashTableCore(),
|
||||
keys_(StaticHashTableCore::canonicalSize(size)),
|
||||
objects_(StaticHashTableCore::canonicalSize(size)),
|
||||
nElmts_(0),
|
||||
endIter_(*this, keys_.size(), 0),
|
||||
endConstIter_(*this, keys_.size(), 0)
|
||||
{
|
||||
if (size < 1)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Illegal size " << size << " for StaticHashTable."
|
||||
<< " Minimum size is 1" << abort(FatalError);
|
||||
}
|
||||
|
||||
operator>>(is, *this);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
Foam::Ostream&
|
||||
Foam::StaticHashTable<T, Key, Hash>::printInfo(Ostream& os) const
|
||||
{
|
||||
label used = 0;
|
||||
label maxChain = 0;
|
||||
unsigned avgChain = 0;
|
||||
|
||||
// Find first non-empty entry
|
||||
forAll(keys_, hashIdx)
|
||||
{
|
||||
const label count = keys_[hashIdx].size();
|
||||
if (count)
|
||||
{
|
||||
++used;
|
||||
avgChain += count;
|
||||
|
||||
if (maxChain < count)
|
||||
{
|
||||
maxChain = count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
os << "StaticHashTable<T,Key,Hash>"
|
||||
<< " elements:" << size() << " slots:" << used << "/" << keys_.size()
|
||||
<< " 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, StaticHashTable<T, Key, Hash>& L)
|
||||
{
|
||||
is.fatalCheck(FUNCTION_NAME);
|
||||
|
||||
// Anull list
|
||||
L.clear();
|
||||
|
||||
is.fatalCheck(FUNCTION_NAME);
|
||||
|
||||
token firstToken(is);
|
||||
|
||||
is.fatalCheck
|
||||
(
|
||||
"operator>>(Istream&, StaticHashTable<T, Key, Hash>&) : "
|
||||
"reading first token"
|
||||
);
|
||||
|
||||
if (firstToken.isLabel())
|
||||
{
|
||||
label s = firstToken.labelToken();
|
||||
|
||||
// Read beginning of contents
|
||||
char delimiter = is.readBeginList("StaticHashTable<T, Key, Hash>");
|
||||
|
||||
if (s)
|
||||
{
|
||||
if (2*s > L.keys_.size())
|
||||
{
|
||||
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&, StaticHashTable<T, Key, Hash>&)"
|
||||
" : reading entry"
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalIOErrorInFunction
|
||||
(
|
||||
is
|
||||
) << "incorrect first token, '(', found " << firstToken.info()
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
}
|
||||
|
||||
// Read end of contents
|
||||
is.readEndList("StaticHashTable");
|
||||
}
|
||||
else if (firstToken.isPunctuation())
|
||||
{
|
||||
if (firstToken.pToken() != token::BEGIN_LIST)
|
||||
{
|
||||
FatalIOErrorInFunction
|
||||
(
|
||||
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&, StaticHashTable<T, Key, Hash>&) : "
|
||||
"reading entry"
|
||||
);
|
||||
|
||||
is >> lastToken;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalIOErrorInFunction
|
||||
(
|
||||
is
|
||||
) << "incorrect first token, expected <int> or '(', found "
|
||||
<< firstToken.info()
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
|
||||
is.fatalCheck(FUNCTION_NAME);
|
||||
|
||||
return is;
|
||||
}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
Foam::Ostream& Foam::operator<<
|
||||
(
|
||||
Ostream& os,
|
||||
const StaticHashTable<T, Key, Hash>& L)
|
||||
{
|
||||
// Write size and start delimiter
|
||||
os << nl << L.size() << nl << token::BEGIN_LIST << nl;
|
||||
|
||||
// Write contents
|
||||
for
|
||||
(
|
||||
typename StaticHashTable<T, Key, Hash>::const_iterator iter = L.begin();
|
||||
iter != L.end();
|
||||
++iter
|
||||
)
|
||||
{
|
||||
os << iter.key() << token::SPACE << iter() << nl;
|
||||
}
|
||||
|
||||
// Write end delimiter
|
||||
os << token::END_LIST;
|
||||
|
||||
os.check(FUNCTION_NAME);
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
Loading…
Reference in New Issue
Block a user