HashTable / StaticHashTable changes

StaticHashTable:
- erase(iterator&) now actually alters the iterator and iterator++() handles
  it properly
- clear() also sets count to zero
- operator=(const StaticHashTable&) doesn't crash after a previous transfer
- operator(), operator==() and operator!=() added

HashTable:
- operator=(const HashTable&) gets tableSize if required, eg, after a
  previous transfer)

HashSet / Map
- add xfer<...> constructor for underlying HashTable
This commit is contained in:
Mark Olesen
2009-01-02 13:24:30 +01:00
parent 973b9ea0ce
commit a010121427
15 changed files with 813 additions and 537 deletions

View File

@ -24,90 +24,122 @@ License
\*---------------------------------------------------------------------------*/
#include <iostream>
#include "HashTable.H"
#include "IOstreams.H"
#include "IStringStream.H"
#include "OStringStream.H"
using namespace Foam;
// use define so we can easily test other implementations
#define HASHTABLE_CLASS HashTable
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main()
{
//for (;;)
HASHTABLE_CLASS<double> table1(100);
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;
Info<< "\ntable1 [" << table1.size() << "] " << endl;
forAllIter(HASHTABLE_CLASS<double>, table1, iter)
{
HashTable<double> myTable(100);
myTable.insert("aaa", 1.0);
myTable.insert("aba", 2.0);
myTable.insert("aca", 3.0);
myTable.insert("ada", 4.0);
myTable.insert("aeq", 5.0);
myTable.insert("aaw", 6.0);
myTable.insert("abs", 7.0);
myTable.insert("acr", 8.0);
myTable.insert("adx", 9.0);
myTable.insert("aec", 10.0);
myTable.erase("aaw");
myTable.erase("abs");
std::cerr << myTable.find("aaa")() << '\n';
std::cerr << myTable.find("aba")() << '\n';
std::cerr << myTable.find("aca")() << '\n';
std::cerr << myTable.find("ada")() << '\n';
std::cerr << myTable.find("aeq")() << '\n';
//std::cerr << myTable.find("aaw")() << '\n';
//std::cerr << myTable.find("abs")() << '\n';
std::cerr << myTable.find("acr")() << '\n';
std::cerr << myTable.find("adx")() << '\n';
std::cerr << myTable.find("aec")() << '\n';
std::cerr << "\nprint table\n" << std::endl;
for
(
HashTable<double>::iterator iter = myTable.begin();
iter != myTable.end();
++iter
)
{
std::cerr << *iter << '\n';
Info<< iter.key() << " => " << iter() << nl;
}
std::cerr << "\nprint table\n" << std::endl;
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;
forAllIter(HashTable<double>, myTable, iter)
{
std::cerr << *iter << '\n';
OStringStream os;
os << table1;
HASHTABLE_CLASS<double> readTable(IStringStream(os.str())(), 100);
Info<< "Istream constructor:" << readTable << endl;
}
std::cerr << "\ncopy of table\n" << std::endl;
HashTable<double> myTable2;
myTable2 = myTable;
HASHTABLE_CLASS<double> table2(table1);
HASHTABLE_CLASS<double> table3(table1.transfer());
forAllConstIter(HashTable<double>, myTable2, iter2)
Info<< "\ncopy table1 -> table2" << nl
<< "transfer table1 -> table3 via the transfer() method" << nl;
Info<< "\ntable1" << table1 << nl
<< "\ntable2" << table1 << nl
<< "\ntable3" << table3 << nl;
Info<< "\ndelete table2" << nl;
forAllIter(HASHTABLE_CLASS<double>, table2, iter)
{
std::cerr << *iter2 << '\n';
Info<< "deleting " << iter.key() << " => " << iter() << " ... ";
table2.erase(iter);
Info<< "deleted" << endl;
}
std::cerr << "\ndelete entries\n" << std::endl;
Info<< "\ntable1" << table1 << nl
<< "\ntable2" << table2 << nl
<< "\ntable3" << table3 << nl;
forAllIter(HashTable<double>, myTable, iter)
{
std::cerr << "deleting " << *iter << '\n';
myTable.erase(iter);
std::cerr << "deleted\n";
}
table3.resize(1);
Info<< "\nresize(1) table3" << table3 << nl;
forAllConstIter(HashTable<double>, myTable, iter)
{
std::cerr << *iter << '\n';
}
}
table3.resize(10000);
Info<< "\nresize(10000) table3" << table3 << nl;
std::cerr << "\nBye.\n";
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;
Info<< "\nclearStorage table3 ... ";
table3.clearStorage();
Info<< table3 << nl;
Info<< "\nDone\n";
return 0;
}

View File

@ -28,6 +28,7 @@ Description
#include "HashTable.H"
#include "HashPtrTable.H"
#include "Map.H"
using namespace Foam;
@ -36,38 +37,46 @@ using namespace Foam;
int main(int argc, char *argv[])
{
HashTable<label, Foam::string> testTable(0);
HashTable<label, Foam::string> table1(0);
testTable.insert("kjhk", 10);
testTable.insert("kjhk2", 12);
table1.insert("kjhk", 10);
table1.insert("kjhk2", 12);
Info<< testTable << endl;
Info<< testTable.toc() << endl;
Info<< "table1: " << table1 << nl
<< "toc: " << table1.toc() << endl;
HashTable<label, label, Hash<label> > testTable2(10);
HashTable<label, label, Hash<label> > table2(10);
testTable2.insert(3, 10);
testTable2.insert(5, 12);
testTable2.insert(7, 16);
table2.insert(3, 10);
table2.insert(5, 12);
table2.insert(7, 16);
Info<< testTable2 << endl;
Info<< testTable2.toc() << endl;
Info<< "table2: " << table2 << nl
<< "toc: " << table2.toc() << endl;
HashTable<label, label, Hash<label> > testTable3(1);
testTable3.transfer(testTable2);
Map<label> table3(1);
table3.transfer(table2);
Info<< testTable2 << endl;
Info<< testTable2.toc() << endl;
Info<< "table2: " << table2 << nl
<< "toc: " << table2.toc() << endl;
Info<< testTable3 << endl;
Info<< testTable3.toc() << endl;
Info<< "table3: " << table3 << nl
<< "toc: " << table3.toc() << endl;
Foam::HashPtrTable<label, Foam::string> testPtrTable(0);
testPtrTable.insert("kjhkjh", new label(10));
Map<label> table4(table3.transfer());
Info<< testPtrTable.toc() << endl;
Info<< "table3: " << table3 << nl
<< "toc: " << table3.toc() << endl;
Info << "End\n" << endl;
Info<< "table4: " << table4 << nl
<< "toc: " << table4.toc() << endl;
HashPtrTable<label, Foam::string> ptable1(0);
ptable1.insert("kjhkjh", new label(10));
Info<< "PtrTable toc: " << ptable1.toc() << endl;
Info<< "End\n" << endl;
return 0;
}

View File

@ -0,0 +1,3 @@
staticHashTableTest.C
EXE = $(FOAM_APPBIN)/staticHashTableTest

View File

@ -22,12 +22,8 @@ License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Description
\*---------------------------------------------------------------------------*/
#include <iostream>
#include "StaticHashTable.H"
#include "IOstreams.H"
#include "IStringStream.H"
@ -35,103 +31,115 @@ Description
using namespace Foam;
// use define so we can easily test other implementations
#define HASHTABLE_CLASS StaticHashTable
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main()
{
//for (;;)
HASHTABLE_CLASS<double> table1(100);
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;
Info<< "\ntable1 [" << table1.size() << "] " << endl;
forAllIter(HASHTABLE_CLASS<double>, table1, iter)
{
StaticHashTable<double> myTable(10);
Info<< iter.key() << " => " << iter() << nl;
}
myTable.insert("aaa", 1.0);
myTable.insert("aba", 2.0);
myTable.insert("aca", 3.0);
myTable.insert("ada", 4.0);
myTable.insert("aeq", 5.0);
myTable.insert("aaw", 6.0);
myTable.insert("abs", 7.0);
myTable.insert("acr", 8.0);
myTable.insert("adx", 9.0);
myTable.insert("aec", 10.0);
table1.set("acr", 108);
table1.set("adx", 109);
table1.set("aec", 100);
table1("aaw") -= 1000;
table1("aeq") += 1000;
Pout<< "Foam output operator:" << nl << endl;
Pout<< myTable << endl;
Info<< "\noverwrote some values table1: " << table1 << endl;
//myTable.erase("aaw");
//myTable.erase("abs");
//std::cerr << "Size now:" << myTable.size() << '\n';
Pout<< "toc:" << nl << endl;
Pout<< myTable.toc() << endl;
std::cerr << myTable.find("aaa")() << '\n';
std::cerr << myTable.find("aba")() << '\n';
std::cerr << myTable.find("aca")() << '\n';
std::cerr << myTable.find("ada")() << '\n';
std::cerr << myTable.find("aeq")() << '\n';
std::cerr << myTable.find("aaw")() << '\n';
std::cerr << myTable.find("abs")() << '\n';
std::cerr << myTable.find("acr")() << '\n';
std::cerr << myTable.find("adx")() << '\n';
std::cerr << myTable.find("aec")() << '\n';
std::cerr << myTable["aaa"] << '\n';
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);
os << myTable;
IStringStream is(os.str());
Pout<< "Foam Istream constructor:" << nl << endl;
StaticHashTable<double> readTable(is, 100);
Pout<< readTable << endl;
}
std::cerr << "\ncopy construct of table\n" << std::endl;
StaticHashTable<double> myTable1(myTable);
Pout<< "myTable1:" << myTable1 << endl;
std::cerr << "\nassignment of table\n" << std::endl;
StaticHashTable<double> myTable2(100);
myTable2.transfer(myTable);
//Pout<< "myTable:" << myTable << endl;
forAllConstIter(StaticHashTable<double>, myTable2, iter2)
{
std::cerr << *iter2 << '\n';
}
std::cerr << "\ntable resize 1\n" << std::endl;
myTable2.resize(1);
forAllConstIter(StaticHashTable<double>, myTable2, iter2)
{
std::cerr << *iter2 << '\n';
}
std::cerr << "\ntable size 10000\n" << std::endl;
myTable2.resize(10000);
forAllConstIter(StaticHashTable<double>, myTable2, iter2)
{
std::cerr << *iter2 << '\n';
}
Info<< "Istream constructor:" << readTable << endl;
}
std::cerr << "\nBye.\n";
HASHTABLE_CLASS<double> table2(table1);
HASHTABLE_CLASS<double> table3(table1.transfer());
Info<< "\ncopy table1 -> table2" << nl
<< "transfer table1 -> table3 via the transfer() method" << nl;
Info<< "\ntable1" << table1 << nl
<< "\ntable2" << table1 << nl
<< "\ntable3" << table3 << nl;
Info<< "\ndelete table2" << nl;
forAllIter(HASHTABLE_CLASS<double>, table2, iter)
{
Info<< "deleting " << iter.key() << " => " << iter() << " ... ";
table2.erase(iter);
Info<< "deleted" << endl;
}
Info<< "\ntable1" << table1 << nl
<< "\ntable2" << table2 << nl
<< "\ntable3" << table3 << nl;
table3.resize(1);
Info<< "\nresize(1) table3" << table3 << nl;
table3.resize(10000);
Info<< "\nresize(10000) table3" << 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;
Info<< "\nclearStorage table3 ... ";
table3.clearStorage();
Info<< table3 << nl;
Info<< "\nDone\n";
return 0;
}

View File

@ -54,7 +54,7 @@ namespace Foam
{
/*---------------------------------------------------------------------------*\
Class HashSet Declaration
Class HashSet Declaration
\*---------------------------------------------------------------------------*/
template<class Key=word, class Hash=string::hash>
@ -106,6 +106,12 @@ public:
HashTable<empty, Key, Hash>(hs)
{}
//- Construct by transferring the parameter contents
HashSet(const xfer<HashTable<empty, Key, Hash> >& hs)
:
HashTable<empty, Key, Hash>(hs)
{}
//- Construct from table of contents of the HashTable
template<class T>
HashSet(const HashTable<T, Key, Hash>& ht);

View File

@ -30,15 +30,10 @@ License
#include "HashTable.H"
#include "List.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class T, class Key, class Hash>
HashTable<T, Key, Hash>::HashTable(const label size)
Foam::HashTable<T, Key, Hash>::HashTable(const label size)
:
tableSize_(size),
table_(NULL),
@ -49,16 +44,16 @@ HashTable<T, Key, Hash>::HashTable(const label size)
if (tableSize_)
{
table_ = new hashedEntry*[tableSize_];
for (label i=0; i<tableSize_; i++)
for (label hashIdx = 0; hashIdx < tableSize_; hashIdx++)
{
table_[i] = 0;
table_[hashIdx] = 0;
}
}
}
template<class T, class Key, class Hash>
HashTable<T, Key, Hash>::HashTable(const HashTable<T, Key, Hash>& ht)
Foam::HashTable<T, Key, Hash>::HashTable(const HashTable<T, Key, Hash>& ht)
:
HashTableName(),
tableSize_(ht.tableSize_),
@ -71,9 +66,9 @@ HashTable<T, Key, Hash>::HashTable(const HashTable<T, Key, Hash>& ht)
{
table_ = new hashedEntry*[tableSize_];
for (label i=0; i<tableSize_; i++)
for (label hashIdx = 0; hashIdx < tableSize_; hashIdx++)
{
table_[i] = 0;
table_[hashIdx] = 0;
}
for (const_iterator iter = ht.begin(); iter != ht.end(); ++iter)
@ -84,7 +79,10 @@ HashTable<T, Key, Hash>::HashTable(const HashTable<T, Key, Hash>& ht)
}
template<class T, class Key, class Hash>
HashTable<T, Key, Hash>::HashTable(const xfer<HashTable<T, Key, Hash> >& ht)
Foam::HashTable<T, Key, Hash>::HashTable
(
const xfer<HashTable<T, Key, Hash> >& ht
)
:
HashTableName(),
tableSize_(0),
@ -100,7 +98,7 @@ HashTable<T, Key, Hash>::HashTable(const xfer<HashTable<T, Key, Hash> >& ht)
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
template<class T, class Key, class Hash>
HashTable<T, Key, Hash>::~HashTable()
Foam::HashTable<T, Key, Hash>::~HashTable()
{
if (table_)
{
@ -113,15 +111,18 @@ HashTable<T, Key, Hash>::~HashTable()
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class T, class Key, class Hash>
bool HashTable<T, Key, Hash>::found(const Key& key) const
bool Foam::HashTable<T, Key, Hash>::found(const Key& key) const
{
if (tableSize_)
{
label ii = Hash()(key, tableSize_);
label hashIdx = Hash()(key, tableSize_);
for (hashedEntry* n=table_[ii]; n; n=n->next_)
for (hashedEntry* ep = table_[hashIdx]; ep; ep = ep->next_)
{
if (key == n->key_) return true;
if (key == ep->key_)
{
return true;
}
}
}
@ -138,20 +139,22 @@ bool HashTable<T, Key, Hash>::found(const Key& key) const
template<class T, class Key, class Hash>
typename HashTable<T, Key, Hash>::iterator HashTable<T, Key, Hash>::find
typename Foam::HashTable<T, Key, Hash>::iterator
Foam::HashTable<T, Key, Hash>::find
(
const Key& key
)
{
if (tableSize_)
{
label ii = Hash()(key, tableSize_);
hashedEntry* prev = 0;
label hashIdx = Hash()(key, tableSize_);
for (hashedEntry* n=table_[ii]; n; n=n->next_)
for (hashedEntry* ep = table_[hashIdx]; ep; ep = ep->next_)
{
if (key == n->key_) return iterator(*this, n, ii);
prev = n;
if (key == ep->key_)
{
return iterator(*this, ep, hashIdx);
}
}
}
@ -168,20 +171,22 @@ typename HashTable<T, Key, Hash>::iterator HashTable<T, Key, Hash>::find
template<class T, class Key, class Hash>
typename HashTable<T, Key, Hash>::const_iterator HashTable<T, Key, Hash>::find
typename Foam::HashTable<T, Key, Hash>::const_iterator
Foam::HashTable<T, Key, Hash>::find
(
const Key& key
) const
{
if (tableSize_)
{
label ii = Hash()(key, tableSize_);
hashedEntry* prev = 0;
label hashIdx = Hash()(key, tableSize_);
for (hashedEntry* n=table_[ii]; n; n=n->next_)
for (hashedEntry* ep = table_[hashIdx]; ep; ep = ep->next_)
{
if (key == n->key_) return const_iterator(*this, n, ii);
prev = n;
if (key == ep->key_)
{
return const_iterator(*this, ep, hashIdx);
}
}
}
@ -199,10 +204,9 @@ typename HashTable<T, Key, Hash>::const_iterator HashTable<T, Key, Hash>::find
// Return the table of contents
template<class T, class Key, class Hash>
List<Key> HashTable<T, Key, Hash>::toc() const
Foam::List<Key> Foam::HashTable<T, Key, Hash>::toc() const
{
List<Key> tofc(nElmts_);
label i = 0;
for (const_iterator iter = begin(); iter != end(); ++iter)
@ -215,7 +219,7 @@ List<Key> HashTable<T, Key, Hash>::toc() const
template<class T, class Key, class Hash>
bool HashTable<T, Key, Hash>::set
bool Foam::HashTable<T, Key, Hash>::set
(
const Key& key,
const T& newEntry,
@ -227,24 +231,24 @@ bool HashTable<T, Key, Hash>::set
resize(2);
}
label ii = Hash()(key, tableSize_);
label hashIdx = Hash()(key, tableSize_);
hashedEntry* existing = 0;
hashedEntry* prev = 0;
for (hashedEntry* curr = table_[ii]; curr; curr = curr->next_)
for (hashedEntry* ep = table_[hashIdx]; ep; ep = ep->next_)
{
if (key == curr->key_)
if (key == ep->key_)
{
existing = curr;
existing = ep;
break;
}
prev = curr;
prev = ep;
}
// not found, insert it at the head
if (!existing)
{
table_[ii] = new hashedEntry(key, table_[ii], newEntry);
table_[hashIdx] = new hashedEntry(key, table_[hashIdx], newEntry);
nElmts_++;
if (double(nElmts_)/tableSize_ > 0.8)
@ -269,7 +273,7 @@ bool HashTable<T, Key, Hash>::set
if (debug)
{
Info<< "HashTable<T, Key, Hash>::set"
"(const Key& key, T newEntry, false) : "
"(const Key& key, T newEntry, true) : "
"Cannot insert " << key << " already in hash table\n";
}
# endif
@ -279,16 +283,16 @@ bool HashTable<T, Key, Hash>::set
{
// found - overwrite existing entry
// this corresponds to the Perl convention
hashedEntry* elemPtr = new hashedEntry(key, existing->next_, newEntry);
hashedEntry* ep = new hashedEntry(key, existing->next_, newEntry);
// replace existing element - within list or insert at the head
if (prev)
{
prev->next_ = elemPtr;
prev->next_ = ep;
}
else
{
table_[ii] = elemPtr;
table_[hashIdx] = ep;
}
delete existing;
@ -299,34 +303,34 @@ bool HashTable<T, Key, Hash>::set
template<class T, class Key, class Hash>
bool HashTable<T, Key, Hash>::erase(const iterator& cit)
bool Foam::HashTable<T, Key, Hash>::erase(const iterator& cit)
{
if (cit.elmtPtr_) // note: endIter_ also has 0 elmtPtr_
{
iterator& it = const_cast<iterator&>(cit);
// Search element before elmtPtr_
hashedEntry* prevElmtPtr = 0;
hashedEntry* prev = 0;
for (hashedEntry* n=table_[it.hashIndex_]; n; n=n->next_)
for (hashedEntry* ep = table_[it.hashIndex_]; ep; ep = ep->next_)
{
if (n == it.elmtPtr_)
if (ep == it.elmtPtr_)
{
break;
}
prevElmtPtr = n;
prev = ep;
}
if (prevElmtPtr)
if (prev)
{
// Have element before elmtPtr
prevElmtPtr->next_ = it.elmtPtr_->next_;
prev->next_ = it.elmtPtr_->next_;
delete it.elmtPtr_;
it.elmtPtr_ = prevElmtPtr;
it.elmtPtr_ = prev;
}
else
{
// elmtPtr is first element on SLlist
// elmtPtr is first element on SLList
table_[it.hashIndex_] = it.elmtPtr_->next_;
delete it.elmtPtr_;
@ -382,7 +386,7 @@ bool HashTable<T, Key, Hash>::erase(const iterator& cit)
template<class T, class Key, class Hash>
bool HashTable<T, Key, Hash>::erase(const Key& key)
bool Foam::HashTable<T, Key, Hash>::erase(const Key& key)
{
iterator it = find(key);
@ -398,7 +402,7 @@ bool HashTable<T, Key, Hash>::erase(const Key& key)
template<class T, class Key, class Hash>
void HashTable<T, Key, Hash>::resize(const label newSize)
void Foam::HashTable<T, Key, Hash>::resize(const label newSize)
{
if (newSize == tableSize_)
{
@ -433,22 +437,22 @@ void HashTable<T, Key, Hash>::resize(const label newSize)
template<class T, class Key, class Hash>
void HashTable<T, Key, Hash>::clear()
void Foam::HashTable<T, Key, Hash>::clear()
{
if (nElmts_)
{
for (label i=0; i<tableSize_; i++)
for (label hashIdx = 0; hashIdx < tableSize_; hashIdx++)
{
if (table_[i])
if (table_[hashIdx])
{
hashedEntry* n = table_[i];
while(hashedEntry* next = n->next_)
hashedEntry* ep = table_[hashIdx];
while (hashedEntry* next = ep->next_)
{
delete n;
n = next;
delete ep;
ep = next;
}
delete n;
table_[i] = 0;
delete ep;
table_[hashIdx] = 0;
}
}
nElmts_ = 0;
@ -457,7 +461,7 @@ void HashTable<T, Key, Hash>::clear()
template<class T, class Key, class Hash>
void HashTable<T, Key, Hash>::clearStorage()
void Foam::HashTable<T, Key, Hash>::clearStorage()
{
clear();
resize(0);
@ -465,10 +469,14 @@ void HashTable<T, Key, Hash>::clearStorage()
template<class T, class Key, class Hash>
void HashTable<T, Key, Hash>::transfer(HashTable<T, Key, Hash>& ht)
void Foam::HashTable<T, Key, Hash>::transfer(HashTable<T, Key, Hash>& ht)
{
clear();
delete[] table_;
// as per the Destructor
if (table_)
{
clear();
delete[] table_;
}
tableSize_ = ht.tableSize_;
ht.tableSize_ = 0;
@ -484,10 +492,13 @@ void HashTable<T, Key, Hash>::transfer(HashTable<T, Key, Hash>& ht)
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
template<class T, class Key, class Hash>
void HashTable<T, Key, Hash>::operator=(const HashTable<T, Key, Hash>& ht)
void Foam::HashTable<T, Key, Hash>::operator=
(
const HashTable<T, Key, Hash>& rhs
)
{
// Check for assignment to self
if (this == &ht)
if (this == &rhs)
{
FatalErrorIn
(
@ -497,9 +508,17 @@ void HashTable<T, Key, Hash>::operator=(const HashTable<T, Key, Hash>& ht)
<< abort(FatalError);
}
clear();
// could be zero-sized from a previous transfer()
if (tableSize_ == 0)
{
resize(rhs.tableSize_);
}
else
{
clear();
}
for (const_iterator iter = ht.begin(); iter != ht.end(); ++iter)
for (const_iterator iter = rhs.begin(); iter != rhs.end(); ++iter)
{
insert(iter.key(), *iter);
}
@ -507,26 +526,28 @@ void HashTable<T, Key, Hash>::operator=(const HashTable<T, Key, Hash>& ht)
template<class T, class Key, class Hash>
bool HashTable<T, Key, Hash>::operator==(const HashTable<T, Key, Hash>& ht)
const
bool Foam::HashTable<T, Key, Hash>::operator==
(
const HashTable<T, Key, Hash>& rhs
) const
{
// Are all my elements in ht?
// Are all my elements in rhs?
for (const_iterator iter = begin(); iter != end(); ++iter)
{
const_iterator fnd = ht.find(iter.key());
const_iterator fnd = rhs.find(iter.key());
if (fnd == ht.end() || (fnd() != iter()))
if (fnd == rhs.end() || fnd() != iter())
{
return false;
}
}
// Are all ht elements in me?
for (const_iterator iter = ht.begin(); iter != ht.end(); ++iter)
// Are all rhs elements in me?
for (const_iterator iter = rhs.begin(); iter != rhs.end(); ++iter)
{
const_iterator fnd = find(iter.key());
if (fnd == end() || (fnd() != iter()))
if (fnd == end() || fnd() != iter())
{
return false;
}
@ -536,17 +557,15 @@ bool HashTable<T, Key, Hash>::operator==(const HashTable<T, Key, Hash>& ht)
template<class T, class Key, class Hash>
bool HashTable<T, Key, Hash>::operator!=(const HashTable<T, Key, Hash>& ht)
const
bool Foam::HashTable<T, Key, Hash>::operator!=
(
const HashTable<T, Key, Hash>& rhs
) const
{
return !(operator==(ht));
return !(operator==(rhs));
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
#include "HashTableIO.C"

View File

@ -50,9 +50,7 @@ namespace Foam
// Forward declaration of friend functions and operators
template<class T>
class List;
template<class T> class List;
template<class T, class Key, class Hash> class HashTable;
template<class T, class Key, class Hash> class HashPtrTable;
@ -216,6 +214,9 @@ public:
// and annull the argument table.
void transfer(HashTable<T, Key, Hash>&);
//- Transfer the contents to the xfer container
inline xfer<HashTable<T, Key, Hash> > transfer();
// Member Operators
@ -225,14 +226,13 @@ public:
//- Find and return an hashedEntry
inline const T& operator[](const Key&) const;
//- Find and return an hashedEntry and
// if it is not present create it null.
//- Find and return an hashedEntry, create it null if not present.
inline T& operator()(const Key&);
//- Assignment
void operator=(const HashTable<T, Key, Hash>&);
//- Equality. Two hashtables are equal if all contents of first are
//- 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!
bool operator==(const HashTable<T, Key, Hash>&) const;

View File

@ -26,15 +26,10 @@ License
#include "error.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * Private Member Classes * * * * * * * * * * * * //
template<class T, class Key, class Hash>
inline HashTable<T, Key, Hash>::hashedEntry::hashedEntry
inline Foam::HashTable<T, Key, Hash>::hashedEntry::hashedEntry
(
const Key& key,
hashedEntry* next,
@ -50,36 +45,55 @@ inline HashTable<T, Key, Hash>::hashedEntry::hashedEntry
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class T, class Key, class Hash>
inline label HashTable<T, Key, Hash>::size() const
inline Foam::label Foam::HashTable<T, Key, Hash>::size() const
{
return nElmts_;
}
template<class T, class Key, class Hash>
inline bool HashTable<T, Key, Hash>::insert(const Key& key, const T& newEntry)
inline bool Foam::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)
inline bool Foam::HashTable<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::HashTable<T, Key, Hash> >
Foam::HashTable<T, Key, Hash>::transfer()
{
Foam::xfer<HashTable<T, Key, Hash> > xf;
xf().transfer(*this);
return xf;
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
template<class T, class Key, class Hash>
inline T& HashTable<T, Key, Hash>::operator[](const Key& key)
inline T& Foam::HashTable<T, Key, Hash>::operator[](const Key& key)
{
iterator iter = find(key);
if (iter == end())
{
FatalErrorIn("HashTable<T, Key, Hash>::operator[](const Key&)")
<< key << " not found in table. Valid entries are "
<< key << " not found in table. Valid entries: "
<< toc()
<< exit(FatalError);
}
@ -87,15 +101,16 @@ inline T& HashTable<T, Key, Hash>::operator[](const Key& key)
return *iter;
}
template<class T, class Key, class Hash>
inline const T& HashTable<T, Key, Hash>::operator[](const Key& key) const
inline const T& Foam::HashTable<T, Key, Hash>::operator[](const Key& key) const
{
const_iterator iter = find(key);
if (iter == end())
{
FatalErrorIn("HashTable<T, Key, Hash>::operator[](const Key&) const")
<< key << " not found in table. Valid entries are "
<< key << " not found in table. Valid entries: "
<< toc()
<< exit(FatalError);
}
@ -105,7 +120,7 @@ inline const T& HashTable<T, Key, Hash>::operator[](const Key& key) const
template<class T, class Key, class Hash>
inline T& HashTable<T, Key, Hash>::operator()(const Key& key)
inline T& Foam::HashTable<T, Key, Hash>::operator()(const Key& key)
{
iterator iter = find(key);
@ -124,7 +139,7 @@ inline T& HashTable<T, Key, Hash>::operator()(const Key& key)
// * * * * * * * * * * * * * * * * STL iterator * * * * * * * * * * * * * * //
template<class T, class Key, class Hash>
inline HashTable<T, Key, Hash>::iterator::iterator
inline Foam::HashTable<T, Key, Hash>::iterator::iterator
(
HashTable<T, Key, Hash>& curHashTable,
hashedEntry* elmt,
@ -138,7 +153,10 @@ inline HashTable<T, Key, Hash>::iterator::iterator
template<class T, class Key, class Hash>
inline void HashTable<T, Key, Hash>::iterator::operator=(const iterator& iter)
inline void Foam::HashTable<T, Key, Hash>::iterator::operator=
(
const iterator& iter
)
{
elmtPtr_ = iter.elmtPtr_;
hashIndex_ = iter.hashIndex_;
@ -146,7 +164,7 @@ inline void HashTable<T, Key, Hash>::iterator::operator=(const iterator& iter)
template<class T, class Key, class Hash>
inline bool HashTable<T, Key, Hash>::iterator::operator==
inline bool Foam::HashTable<T, Key, Hash>::iterator::operator==
(
const iterator& iter
) const
@ -156,7 +174,7 @@ inline bool HashTable<T, Key, Hash>::iterator::operator==
template<class T, class Key, class Hash>
inline bool HashTable<T, Key, Hash>::iterator::operator!=
inline bool Foam::HashTable<T, Key, Hash>::iterator::operator!=
(
const iterator& iter
) const
@ -166,7 +184,7 @@ inline bool HashTable<T, Key, Hash>::iterator::operator!=
template<class T, class Key, class Hash>
inline bool HashTable<T, Key, Hash>::iterator::operator==
inline bool Foam::HashTable<T, Key, Hash>::iterator::operator==
(
const const_iterator& iter
) const
@ -176,7 +194,7 @@ inline bool HashTable<T, Key, Hash>::iterator::operator==
template<class T, class Key, class Hash>
inline bool HashTable<T, Key, Hash>::iterator::operator!=
inline bool Foam::HashTable<T, Key, Hash>::iterator::operator!=
(
const const_iterator& iter
) const
@ -186,14 +204,14 @@ inline bool HashTable<T, Key, Hash>::iterator::operator!=
template<class T, class Key, class Hash>
inline T& HashTable<T, Key, Hash>::iterator::operator*()
inline T& Foam::HashTable<T, Key, Hash>::iterator::operator*()
{
return elmtPtr_->obj_;
}
template<class T, class Key, class Hash>
inline T& HashTable<T, Key, Hash>::iterator::operator()()
inline T& Foam::HashTable<T, Key, Hash>::iterator::operator()()
{
return operator*();
}
@ -201,13 +219,13 @@ inline T& HashTable<T, Key, Hash>::iterator::operator()()
template<class T, class Key, class Hash>
inline
typename HashTable<T, Key, Hash>::iterator&
HashTable<T, Key, Hash>::iterator::operator++()
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 singly linked list?
// Do we have additional elements on the SLList?
if (elmtPtr_ && elmtPtr_->next_)
{
elmtPtr_ = elmtPtr_->next_;
@ -226,16 +244,16 @@ HashTable<T, Key, Hash>::iterator::operator++()
if (hashIndex_ == curHashTable_.tableSize_)
{
// make end iterator
hashIndex_ = 0;
elmtPtr_ = 0;
hashIndex_ = 0;
}
return *this;
}
template<class T, class Key, class Hash>
inline typename HashTable<T, Key, Hash>::iterator
HashTable<T, Key, Hash>::iterator::operator++
inline typename Foam::HashTable<T, Key, Hash>::iterator
Foam::HashTable<T, Key, Hash>::iterator::operator++
(
int
)
@ -248,15 +266,15 @@ HashTable<T, Key, Hash>::iterator::operator++
template<class T, class Key, class Hash>
inline
const Key& HashTable<T, Key, Hash>::iterator::key()
const Key& Foam::HashTable<T, Key, Hash>::iterator::key()
{
return elmtPtr_->key_;
}
template<class T, class Key, class Hash>
inline typename HashTable<T, Key, Hash>::iterator
HashTable<T, Key, Hash>::begin()
inline typename Foam::HashTable<T, Key, Hash>::iterator
Foam::HashTable<T, Key, Hash>::begin()
{
label i = 0;
@ -282,8 +300,8 @@ HashTable<T, Key, Hash>::begin()
template<class T, class Key, class Hash>
inline const typename HashTable<T, Key, Hash>::iterator&
HashTable<T, Key, Hash>::end()
inline const typename Foam::HashTable<T, Key, Hash>::iterator&
Foam::HashTable<T, Key, Hash>::end()
{
return HashTable<T, Key, Hash>::endIter_;
}
@ -292,7 +310,7 @@ HashTable<T, Key, Hash>::end()
// * * * * * * * * * * * * * * * STL const_iterator * * * * * * * * * * * * * //
template<class T, class Key, class Hash>
inline HashTable<T, Key, Hash>::const_iterator::const_iterator
inline Foam::HashTable<T, Key, Hash>::const_iterator::const_iterator
(
const HashTable<T, Key, Hash>& curHashTable,
const hashedEntry* elmt,
@ -306,7 +324,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
inline Foam::HashTable<T, Key, Hash>::const_iterator::const_iterator
(
const iterator& iter
)
@ -318,7 +336,7 @@ inline HashTable<T, Key, Hash>::const_iterator::const_iterator
template<class T, class Key, class Hash>
inline void HashTable<T, Key, Hash>::const_iterator::operator=
inline void Foam::HashTable<T, Key, Hash>::const_iterator::operator=
(
const const_iterator& iter
)
@ -329,7 +347,7 @@ inline void HashTable<T, Key, Hash>::const_iterator::operator=
template<class T, class Key, class Hash>
inline bool HashTable<T, Key, Hash>::const_iterator::operator==
inline bool Foam::HashTable<T, Key, Hash>::const_iterator::operator==
(
const const_iterator& iter
) const
@ -339,7 +357,7 @@ inline bool HashTable<T, Key, Hash>::const_iterator::operator==
template<class T, class Key, class Hash>
inline bool HashTable<T, Key, Hash>::const_iterator::operator!=
inline bool Foam::HashTable<T, Key, Hash>::const_iterator::operator!=
(
const const_iterator& iter
) const
@ -349,7 +367,7 @@ inline bool HashTable<T, Key, Hash>::const_iterator::operator!=
template<class T, class Key, class Hash>
inline bool HashTable<T, Key, Hash>::const_iterator::operator==
inline bool Foam::HashTable<T, Key, Hash>::const_iterator::operator==
(
const iterator& iter
) const
@ -359,7 +377,7 @@ inline bool HashTable<T, Key, Hash>::const_iterator::operator==
template<class T, class Key, class Hash>
inline bool HashTable<T, Key, Hash>::const_iterator::operator!=
inline bool Foam::HashTable<T, Key, Hash>::const_iterator::operator!=
(
const iterator& iter
) const
@ -369,14 +387,14 @@ inline bool HashTable<T, Key, Hash>::const_iterator::operator!=
template<class T, class Key, class Hash>
inline const T& HashTable<T, Key, Hash>::const_iterator::operator*()
inline const T& Foam::HashTable<T, Key, Hash>::const_iterator::operator*()
{
return elmtPtr_->obj_;
}
#ifndef __CINT__
template<class T, class Key, class Hash>
inline const T& HashTable<T, Key, Hash>::const_iterator::operator()()
inline const T& Foam::HashTable<T, Key, Hash>::const_iterator::operator()()
{
return operator*();
}
@ -384,8 +402,8 @@ inline const T& HashTable<T, Key, Hash>::const_iterator::operator()()
template<class T, class Key, class Hash>
inline
typename HashTable<T, Key, Hash>::const_iterator&
HashTable<T, Key, Hash>::const_iterator::operator++()
typename Foam::HashTable<T, Key, Hash>::const_iterator&
Foam::HashTable<T, Key, Hash>::const_iterator::operator++()
{
if
(
@ -407,8 +425,8 @@ HashTable<T, Key, Hash>::const_iterator::operator++()
template<class T, class Key, class Hash>
inline typename HashTable<T, Key, Hash>::const_iterator
HashTable<T, Key, Hash>::const_iterator::operator++
inline typename Foam::HashTable<T, Key, Hash>::const_iterator
Foam::HashTable<T, Key, Hash>::const_iterator::operator++
(
int
)
@ -421,15 +439,15 @@ HashTable<T, Key, Hash>::const_iterator::operator++
template<class T, class Key, class Hash>
inline
const Key& HashTable<T, Key, Hash>::const_iterator::key()
const Key& Foam::HashTable<T, Key, Hash>::const_iterator::key()
{
return elmtPtr_->key_;
}
template<class T, class Key, class Hash>
inline typename HashTable<T, Key, Hash>::const_iterator
HashTable<T, Key, Hash>::begin() const
inline typename Foam::HashTable<T, Key, Hash>::const_iterator
Foam::HashTable<T, Key, Hash>::begin() const
{
label i = 0;
@ -455,15 +473,11 @@ HashTable<T, Key, Hash>::begin() const
template<class T, class Key, class Hash>
inline const typename HashTable<T, Key, Hash>::const_iterator&
HashTable<T, Key, Hash>::end() const
inline const typename Foam::HashTable<T, Key, Hash>::const_iterator&
Foam::HashTable<T, Key, Hash>::end() const
{
return HashTable<T, Key, Hash>::endConstIter_;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -58,13 +58,13 @@ Foam::Istream& Foam::operator>>(Istream& is, HashTable<T, Key, Hash>& L)
// Anull list
L.clear();
is.fatalCheck("operator>>(Istream& is, HashTable<T, Key, Hash>& L)");
is.fatalCheck("operator>>(Istream&, HashTable<T, Key, Hash>&)");
token firstToken(is);
is.fatalCheck
(
"operator>>(Istream& is, HashTable<T, Key, Hash>& L) : "
"operator>>(Istream&, HashTable<T, Key, Hash>&) : "
"reading first token"
);
@ -101,7 +101,7 @@ Foam::Istream& Foam::operator>>(Istream& is, HashTable<T, Key, Hash>& L)
{
FatalIOErrorIn
(
"operator>>(Istream& is, HashTable<T, Key, Hash>& L)",
"operator>>(Istream&, HashTable<T, Key, Hash>&)",
is
) << "incorrect first token, '(', found " << firstToken.info()
<< exit(FatalIOError);
@ -117,7 +117,7 @@ Foam::Istream& Foam::operator>>(Istream& is, HashTable<T, Key, Hash>& L)
{
FatalIOErrorIn
(
"operator>>(Istream& is, HashTable<T, Key, Hash>& L)",
"operator>>(Istream&, HashTable<T, Key, Hash>&)",
is
) << "incorrect first token, '(', found " << firstToken.info()
<< exit(FatalIOError);
@ -152,7 +152,7 @@ Foam::Istream& Foam::operator>>(Istream& is, HashTable<T, Key, Hash>& L)
{
FatalIOErrorIn
(
"operator>>(Istream& is, HashTable<T, Key, Hash>& L)",
"operator>>(Istream&, HashTable<T, Key, Hash>&)",
is
) << "incorrect first token, expected <int> or '(', found "
<< firstToken.info()
@ -168,13 +168,10 @@ Foam::Istream& Foam::operator>>(Istream& is, HashTable<T, Key, Hash>& L)
template<class T, class Key, class Hash>
Foam::Ostream& Foam::operator<<(Ostream& os, const HashTable<T, Key, Hash>& L)
{
// Write size of HashTable
os << nl << L.size();
// Write size of HashTable and start contents delimiter
os << nl << L.size() << nl << token::BEGIN_LIST << nl;
// Write beginning of contents
os << nl << token::BEGIN_LIST << nl;
// Write HashTable contents
// Write contents
for
(
typename HashTable<T, Key, Hash>::const_iterator iter = L.begin();
@ -185,7 +182,7 @@ Foam::Ostream& Foam::operator<<(Ostream& os, const HashTable<T, Key, Hash>& L)
os << iter.key() << token::SPACE << iter() << nl;
}
// Write end of contents
// Write end of contents delimiter
os << token::END_LIST;
// Check state of IOstream

View File

@ -86,6 +86,12 @@ public:
HashTable<T, label, Hash<label> >(map)
{}
//- Construct by transferring the parameter contents
Map(const xfer<HashTable<T, label, Hash<label> > >& map)
:
HashTable<T, label, Hash<label> >(map)
{}
//- Return a null Map
static const Map<T>& null()

View File

@ -31,16 +31,11 @@ License
#include "List.H"
#include "IOstreams.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Construct given initial table size
template<class T, class Key, class Hash>
StaticHashTable<T, Key, Hash>::StaticHashTable(const label size)
Foam::StaticHashTable<T, Key, Hash>::StaticHashTable(const label size)
:
StaticHashTableName(),
keys_(size),
@ -62,7 +57,7 @@ StaticHashTable<T, Key, Hash>::StaticHashTable(const label size)
// Construct as copy
template<class T, class Key, class Hash>
StaticHashTable<T, Key, Hash>::StaticHashTable
Foam::StaticHashTable<T, Key, Hash>::StaticHashTable
(
const StaticHashTable<T, Key, Hash>& ht
)
@ -78,7 +73,7 @@ StaticHashTable<T, Key, Hash>::StaticHashTable
template<class T, class Key, class Hash>
StaticHashTable<T, Key, Hash>::StaticHashTable
Foam::StaticHashTable<T, Key, Hash>::StaticHashTable
(
const xfer<StaticHashTable<T, Key, Hash> >& ht
)
@ -97,22 +92,21 @@ StaticHashTable<T, Key, Hash>::StaticHashTable
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
template<class T, class Key, class Hash>
StaticHashTable<T, Key, Hash>::~StaticHashTable()
Foam::StaticHashTable<T, Key, Hash>::~StaticHashTable()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class T, class Key, class Hash>
bool StaticHashTable<T, Key, Hash>::found(const Key& key) const
bool Foam::StaticHashTable<T, Key, Hash>::found(const Key& key) const
{
label ii = Hash()(key, keys_.size());
label hashIdx = Hash()(key, keys_.size());
const List<Key>& localKeys = keys_[hashIdx];
const List<Key>& localKeys = keys_[ii];
forAll(localKeys, n)
forAll(localKeys, elemIdx)
{
if (localKeys[n] == key)
if (key == localKeys[elemIdx])
{
return true;
}
@ -121,7 +115,7 @@ bool StaticHashTable<T, Key, Hash>::found(const Key& key) const
# ifdef FULLDEBUG
if (debug)
{
Pout<< "StaticHashTable<T, Key, Hash>::found(const Key& key) : "
Info<< "StaticHashTable<T, Key, Hash>::found(const Key&) : "
<< "Entry " << key << " not found in hash table\n";
}
# endif
@ -131,28 +125,27 @@ bool StaticHashTable<T, Key, Hash>::found(const Key& key) const
template<class T, class Key, class Hash>
typename StaticHashTable<T, Key, Hash>::iterator
StaticHashTable<T, Key, Hash>::find
typename Foam::StaticHashTable<T, Key, Hash>::iterator
Foam::StaticHashTable<T, Key, Hash>::find
(
const Key& key
)
{
label ii = Hash()(key, keys_.size());
label hashIdx = Hash()(key, keys_.size());
const List<Key>& localKeys = keys_[hashIdx];
const List<Key>& localKeys = keys_[ii];
forAll(localKeys, n)
forAll(localKeys, elemIdx)
{
if (localKeys[n] == key)
if (key == localKeys[elemIdx])
{
return iterator(*this, ii, n);
return iterator(*this, hashIdx, elemIdx);
}
}
# ifdef FULLDEBUG
if (debug)
{
Pout<< "StaticHashTable<T, Key, Hash>::find(const Key& key) : "
Info<< "StaticHashTable<T, Key, Hash>::find(const Key&) : "
<< "Entry " << key << " not found in hash table\n";
}
# endif
@ -162,28 +155,27 @@ StaticHashTable<T, Key, Hash>::find
template<class T, class Key, class Hash>
typename StaticHashTable<T, Key, Hash>::const_iterator
StaticHashTable<T, Key, Hash>::find
typename Foam::StaticHashTable<T, Key, Hash>::const_iterator
Foam::StaticHashTable<T, Key, Hash>::find
(
const Key& key
) const
{
label ii = Hash()(key, keys_.size());
label hashIdx = Hash()(key, keys_.size());
const List<Key>& localKeys = keys_[hashIdx];
const List<Key>& localKeys = keys_[ii];
forAll(localKeys, n)
forAll(localKeys, elemIdx)
{
if (localKeys[n] == key)
if (key == localKeys[elemIdx])
{
return const_iterator(*this, ii, n);
return const_iterator(*this, hashIdx, elemIdx);
}
}
# ifdef FULLDEBUG
if (debug)
{
Pout<< "StaticHashTable<T, Key, Hash>::find(const Key& key) const : "
Info<< "StaticHashTable<T, Key, Hash>::find(const Key&) const : "
<< "Entry " << key << " not found in hash table\n";
}
# endif
@ -194,10 +186,9 @@ StaticHashTable<T, Key, Hash>::find
// Return the table of contents
template<class T, class Key, class Hash>
List<Key> StaticHashTable<T, Key, Hash>::toc() const
Foam::List<Key> Foam::StaticHashTable<T, Key, Hash>::toc() const
{
List<Key> tofc(nElmts_);
label i = 0;
for (const_iterator iter = begin(); iter != end(); ++iter)
@ -210,57 +201,74 @@ List<Key> StaticHashTable<T, Key, Hash>::toc() const
template<class T, class Key, class Hash>
bool StaticHashTable<T, Key, Hash>::insert(const Key& key, const T& newEntry)
bool Foam::StaticHashTable<T, Key, Hash>::set
(
const Key& key,
const T& newEntry,
const bool protect
)
{
label ii = Hash()(key, keys_.size());
label hashIdx = Hash()(key, keys_.size());
List<Key>& localKeys = keys_[hashIdx];
List<Key>& localKeys = keys_[ii];
forAll(localKeys, n)
label existing = localKeys.size();
forAll(localKeys, elemIdx)
{
if (localKeys[n] == key)
if (key == localKeys[elemIdx])
{
# ifdef FULLDEBUG
if (debug)
{
Pout<< "StaticHashTable<T, Key, Hash>::insert"
"(const Key& key, T newEntry) : "
"Cannot insert " << key << " already in hash table\n";
}
# endif
return false;
existing = elemIdx;
break;
}
}
if (existing == localKeys.size())
{
// not found, append
List<T>& localObjects = objects_[hashIdx];
// Append.
List<T>& localObjects = objects_[ii];
localKeys.setSize(existing+1);
localObjects.setSize(existing+1);
label sz = localKeys.size();
localKeys[existing] = key;
localObjects[existing] = newEntry;
localKeys.setSize(sz+1);
localObjects.setSize(sz+1);
localKeys[sz] = key;
localObjects[sz] = newEntry;
nElmts_++;
nElmts_++;
}
else if (protect)
{
// found - but protected from overwriting
// this corresponds to the STL 'insert' convention
# ifdef FULLDEBUG
if (debug)
{
Info<< "StaticHashTable<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
objects_[hashIdx][existing] = newEntry;
}
return true;
}
template<class T, class Key, class Hash>
bool StaticHashTable<T, Key, Hash>::erase(const iterator& it)
bool Foam::StaticHashTable<T, Key, Hash>::erase(const iterator& cit)
{
if (it != end())
if (cit != end())
{
List<Key>& localKeys = keys_[it.hashIndex_];
List<T>& localObjects = objects_[it.hashIndex_];
List<Key>& localKeys = keys_[cit.hashIndex_];
List<T>& localObjects = objects_[cit.hashIndex_];
// Copy down
for (label i = it.elementIndex_+1; i < localKeys.size(); i++)
for (label i = cit.elementIndex_+1; i < localKeys.size(); i++)
{
localKeys[i-1] = localKeys[i];
localObjects[i-1] = localObjects[i];
@ -268,12 +276,39 @@ bool StaticHashTable<T, Key, Hash>::erase(const iterator& it)
localKeys.setSize(localKeys.size()-1);
localObjects.setSize(localObjects.size()-1);
// adjust iterator after erase
iterator& it = const_cast<iterator&>(cit);
it.elementIndex_--;
if (it.elementIndex_ < 0)
{
// No previous element in the local list
// Search back for previous non-zero table entry
while (--it.hashIndex_ >= 0 && !objects_[it.hashIndex_].size())
{}
if (it.hashIndex_ >= 0)
{
// The last element in the local list
it.elementIndex_ = objects_[it.hashIndex_].size() - 1;
}
else
{
// No previous found. Mark with special value which is
// - not end()
// - handled by operator++
it.hashIndex_ = -1;
it.elementIndex_ = 0;
}
}
nElmts_--;
# ifdef FULLDEBUG
if (debug)
{
Pout<< "StaticHashTable<T, Key, Hash>::erase(iterator&) : "
Info<< "StaticHashTable<T, Key, Hash>::erase(iterator&) : "
<< "hashedEntry removed.\n";
}
# endif
@ -285,7 +320,7 @@ bool StaticHashTable<T, Key, Hash>::erase(const iterator& it)
# ifdef FULLDEBUG
if (debug)
{
Pout<< "StaticHashTable<T, Key, Hash>::erase(iterator&) : "
Info<< "StaticHashTable<T, Key, Hash>::erase(iterator&) : "
<< "cannot remove hashedEntry from hash table\n";
}
# endif
@ -296,7 +331,7 @@ bool StaticHashTable<T, Key, Hash>::erase(const iterator& it)
template<class T, class Key, class Hash>
bool StaticHashTable<T, Key, Hash>::erase(const Key& key)
bool Foam::StaticHashTable<T, Key, Hash>::erase(const Key& key)
{
iterator it = find(key);
@ -312,14 +347,14 @@ bool StaticHashTable<T, Key, Hash>::erase(const Key& key)
template<class T, class Key, class Hash>
void StaticHashTable<T, Key, Hash>::resize(const label newSize)
void Foam::StaticHashTable<T, Key, Hash>::resize(const label newSize)
{
if (newSize == keys_.size())
{
# ifdef FULLDEBUG
if (debug)
{
Pout<< "StaticHashTable<T, Key, Hash>::resize(const label) : "
Info<< "StaticHashTable<T, Key, Hash>::resize(const label) : "
<< "new table size == old table size\n";
}
# endif
@ -353,46 +388,62 @@ void StaticHashTable<T, Key, Hash>::resize(const label newSize)
template<class T, class Key, class Hash>
void StaticHashTable<T, Key, Hash>::clear()
void Foam::StaticHashTable<T, Key, Hash>::clear()
{
forAll(keys_, ii)
forAll(keys_, hashIdx)
{
keys_[ii].clear();
objects_[ii].clear();
keys_[hashIdx].clear();
objects_[hashIdx].clear();
}
nElmts_ = 0;
}
template<class T, class Key, class Hash>
void StaticHashTable<T, Key, Hash>::transfer(StaticHashTable<T, Key, Hash>& ht)
void Foam::StaticHashTable<T, Key, Hash>::clearStorage()
{
// Remove my existing elements
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();
// Clear ht
ht.nElmts_ = 0;
ht.endIter_.hashIndex_ = 0;
ht.endConstIter_.hashIndex_ = 0;
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
template<class T, class Key, class Hash>
void StaticHashTable<T, Key, Hash>::operator=
void Foam::StaticHashTable<T, Key, Hash>::operator=
(
const StaticHashTable<T, Key, Hash>& ht
const StaticHashTable<T, Key, Hash>& rhs
)
{
// Check for assignment to self
if (this == &ht)
if (this == &rhs)
{
FatalErrorIn
(
@ -402,20 +453,70 @@ void StaticHashTable<T, Key, Hash>::operator=
<< abort(FatalError);
}
clear();
for (const_iterator iter = ht.begin(); iter != ht.end(); ++iter)
// could be zero-sized from a previous transfer()
if (keys_.size() == 0)
{
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.begin(); iter != rhs.end(); ++iter)
{
insert(iter.key(), *iter);
}
}
// keys_.size() does not change so neither does end() iterator.
template<class T, class Key, class Hash>
bool Foam::StaticHashTable<T, Key, Hash>::operator==
(
const StaticHashTable<T, Key, Hash>& rhs
) const
{
// Are all my elements in rhs?
for (const_iterator iter = begin(); iter != end(); ++iter)
{
const_iterator fnd = rhs.find(iter.key());
if (fnd == rhs.end() || fnd() != iter())
{
return false;
}
}
// Are all rhs elements in me?
for (const_iterator iter = rhs.begin(); iter != rhs.end(); ++iter)
{
const_iterator fnd = find(iter.key());
if (fnd == end() || 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));
}
} // End namespace Foam
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //

View File

@ -28,6 +28,7 @@ Class
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.
@ -55,9 +56,7 @@ namespace Foam
// Forward declaration of friend functions and operators
template<class T>
class List;
template<class T> class List;
template<class T, class Key, class Hash> class StaticHashTable;
template<class T, class Key, class Hash> Istream& operator>>
@ -74,14 +73,14 @@ template<class T, class Key, class Hash> Ostream& operator<<
/*---------------------------------------------------------------------------*\
Class StaticHashTableName Declaration
Class StaticHashTableName Declaration
\*---------------------------------------------------------------------------*/
TemplateName(StaticHashTable);
/*---------------------------------------------------------------------------*\
Class StaticHashTable Declaration
Class StaticHashTable Declaration
\*---------------------------------------------------------------------------*/
template<class T, class Key=word, class Hash=string::hash>
@ -100,6 +99,9 @@ class StaticHashTable
//- The current number of elements in table
label nElmts_;
//- Assign a new hashed entry to a possibly already existing key
bool set(const Key&, const T& newElmt, bool protect);
public:
@ -147,7 +149,7 @@ public:
//- Construct as copy
StaticHashTable(const StaticHashTable<T, Key, Hash>&);
//- Construct as copy
//- Construct by transferring the parameter contents
StaticHashTable(const xfer<StaticHashTable<T, Key, Hash> >&);
// Destructor
@ -162,14 +164,14 @@ public:
//- Return number of elements in table.
inline label size() const;
//- Return true if hashedEntry is found in table
//- Return true if hashed entry is found in table
bool found(const Key& key) const;
//- Find and return an iterator set at the hashedEntry
//- 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 hashedEntry
//- Find and return an const_iterator set at the hashed entry
// If not found iterator = end()
const_iterator find(const Key& key) const;
@ -179,13 +181,16 @@ public:
// Edit
//- Insert a new hashedEntry
//- Insert a new hashed entry
bool insert(const Key& key, const T& newElmt);
//- Erase an hashedEntry specified by given iterator
//- 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 hashedEntry specified by given key if in table
//- Erase an hashed entry specified by given key if in table
bool erase(const Key& key);
//- Resize the hash table for efficiency
@ -194,22 +199,38 @@ public:
//- 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 annull the argument table.
void transfer(StaticHashTable<T, Key, Hash>&);
//- Transfer the contents to the xfer container
inline xfer<StaticHashTable<T, Key, Hash> > transfer();
// Member Operators
//- Find and return an hashedEntry
inline T& operator[](const Key& key);
//- Find and return an hashed entry
inline T& operator[](const Key&);
//- Find and return an hashedEntry
inline const T& operator[](const Key& key) const;
//- 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
@ -245,7 +266,7 @@ public:
// Private data
//- Reference to the StaticHashTable this is an iterator for
TableRef curStaticHashTable_;
TableRef curHashTable_;
//- Current hash index
label hashIndex_;
@ -257,10 +278,10 @@ public:
// Constructors
//- Construct from hash table, element and hash index
//- Construct from hash table, hash index and element index
inline Iterator
(
TableRef curStaticHashTable,
TableRef curHashTable,
label hashIndex_,
label elementIndex_
);

View File

@ -27,34 +27,60 @@ License
#include "error.H"
#include "IOstreams.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * Private Member Classes * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class T, class Key, class Hash>
inline label StaticHashTable<T, Key, Hash>::size() const
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>::insert
(
const Key& key,
const T& newEntry
)
{
return set(key, newEntry, true);
}
template<class T, class Key, class Hash>
inline bool Foam::StaticHashTable<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::StaticHashTable<T, Key, Hash> >
Foam::StaticHashTable<T, Key, Hash>::transfer()
{
Foam::xfer<StaticHashTable<T, Key, Hash> > xf;
xf().transfer(*this);
return xf;
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
template<class T, class Key, class Hash>
inline T& StaticHashTable<T, Key, Hash>::operator[](const Key& key)
inline T& Foam::StaticHashTable<T, Key, Hash>::operator[](const Key& key)
{
iterator iter = find(key);
if (iter == end())
{
FatalErrorIn("StaticHashTable<T, Key, Hash>::operator[](const Key&)")
<< key << " not found in table. Valid entries are "
<< key << " not found in table. Valid entries: "
<< toc()
<< exit(FatalError);
}
@ -62,8 +88,12 @@ inline T& StaticHashTable<T, Key, Hash>::operator[](const Key& key)
return *iter;
}
template<class T, class Key, class Hash>
inline const T& StaticHashTable<T, Key, Hash>::operator[](const Key& key) const
inline const T& Foam::StaticHashTable<T, Key, Hash>::operator[]
(
const Key& key
) const
{
const_iterator iter = find(key);
@ -72,7 +102,7 @@ inline const T& StaticHashTable<T, Key, Hash>::operator[](const Key& key) const
FatalErrorIn
(
"StaticHashTable<T, Key, Hash>::operator[](const Key&) const"
) << key << " not found in table. Valid entries are "
) << key << " not found in table. Valid entries: "
<< toc()
<< exit(FatalError);
}
@ -81,19 +111,35 @@ inline const T& StaticHashTable<T, Key, Hash>::operator[](const Key& key) const
}
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 StaticHashTable<T, Key, Hash>::Iterator<TRef, TableRef>::
Iterator
inline Foam::StaticHashTable<T, Key, Hash>::Iterator<TRef, TableRef>::Iterator
(
TableRef curStaticHashTable,
TableRef curHashTable,
label hashIndex,
label elementIndex
)
:
curStaticHashTable_(curStaticHashTable),
curHashTable_(curHashTable),
hashIndex_(hashIndex),
elementIndex_(elementIndex)
{}
@ -101,10 +147,12 @@ Iterator
template<class T, class Key, class Hash>
template<class TRef, class TableRef>
inline StaticHashTable<T, Key, Hash>::Iterator<TRef, TableRef>::
Iterator(const iterator& iter)
inline Foam::StaticHashTable<T, Key, Hash>::Iterator<TRef, TableRef>::Iterator
(
const iterator& iter
)
:
curStaticHashTable_(iter.curStaticHashTable_),
curHashTable_(iter.curHashTable_),
hashIndex_(iter.hashIndex_),
elementIndex_(iter.elementIndex_)
{}
@ -112,8 +160,11 @@ Iterator(const iterator& iter)
template<class T, class Key, class Hash>
template<class TRef, class TableRef>
inline void StaticHashTable<T, Key, Hash>::Iterator<TRef, TableRef>::
operator=(const iterator& iter)
inline void
Foam::StaticHashTable<T, Key, Hash>::Iterator<TRef, TableRef>::operator=
(
const iterator& iter
)
{
this->hashIndex_ = iter.hashIndex_;
this->elementIndex_ = iter.elementIndex_;
@ -122,16 +173,11 @@ operator=(const iterator& iter)
template<class T, class Key, class Hash>
template<class TRef, class TableRef>
inline bool StaticHashTable<T, Key, Hash>::Iterator<TRef, TableRef>::
operator==(const iterator& iter) const
{
return hashIndex_ == iter.hashIndex_ && elementIndex_ == iter.elementIndex_;
}
template<class T, class Key, class Hash>
template<class TRef, class TableRef>
inline bool StaticHashTable<T, Key, Hash>::Iterator<TRef, TableRef>::
operator==(const const_iterator& iter) const
inline bool
Foam::StaticHashTable<T, Key, Hash>::Iterator<TRef, TableRef>::operator==
(
const iterator& iter
) const
{
return hashIndex_ == iter.hashIndex_ && elementIndex_ == iter.elementIndex_;
}
@ -139,16 +185,23 @@ operator==(const const_iterator& iter) const
template<class T, class Key, class Hash>
template<class TRef, class TableRef>
inline bool StaticHashTable<T, Key, Hash>::Iterator<TRef, TableRef>::
operator!=(const iterator& iter) const
inline bool
Foam::StaticHashTable<T, Key, Hash>::Iterator<TRef, TableRef>::operator==
(
const const_iterator& iter
) const
{
return !operator==(iter);
return hashIndex_ == iter.hashIndex_ && elementIndex_ == iter.elementIndex_;
}
template<class T, class Key, class Hash>
template<class TRef, class TableRef>
inline bool StaticHashTable<T, Key, Hash>::Iterator<TRef, TableRef>::
operator!=(const const_iterator& iter) const
inline bool
Foam::StaticHashTable<T, Key, Hash>::Iterator<TRef, TableRef>::operator!=
(
const iterator& iter
) const
{
return !operator==(iter);
}
@ -156,17 +209,29 @@ operator!=(const const_iterator& iter) const
template<class T, class Key, class Hash>
template<class TRef, class TableRef>
inline TRef StaticHashTable<T, Key, Hash>::Iterator<TRef, TableRef>::
operator*()
inline bool
Foam::StaticHashTable<T, Key, Hash>::Iterator<TRef, TableRef>::operator!=
(
const const_iterator& iter
) const
{
return curStaticHashTable_.objects_[hashIndex_][elementIndex_];
return !operator==(iter);
}
template<class T, class Key, class Hash>
template<class TRef, class TableRef>
inline TRef StaticHashTable<T, Key, Hash>::Iterator<TRef, TableRef>::
operator()()
inline TRef
Foam::StaticHashTable<T, Key, Hash>::Iterator<TRef, TableRef>::operator*()
{
return curHashTable_.objects_[hashIndex_][elementIndex_];
}
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*();
}
@ -175,40 +240,44 @@ operator()()
template<class T, class Key, class Hash>
template<class TRef, class TableRef>
inline
typename StaticHashTable<T, Key, Hash>::template Iterator
typename Foam::StaticHashTable<T, Key, Hash>::template Iterator
<
TRef,
TableRef
>&
StaticHashTable<T, Key, Hash>::Iterator
Foam::StaticHashTable<T, Key, Hash>::Iterator
<
TRef,
TableRef
>::operator++()
{
const List<T>& localObjects = curStaticHashTable_.objects_[hashIndex_];
if (elementIndex_ == localObjects.size()-1)
// Check for special value from erase. (sets hashIndex to -1)
if (hashIndex_ >= 0)
{
elementIndex_ = 0;
// Try the next element on the local list
elementIndex_++;
// Find first non-zero entry
for
(
hashIndex_++;
hashIndex_ < curStaticHashTable_.objects_.size();
hashIndex_++
)
if (elementIndex_ < curHashTable_.objects_[hashIndex_].size())
{
if (curStaticHashTable_.objects_[hashIndex_].size() > 0)
{
break;
}
return *this;
}
}
else
// Step to the next table entry
elementIndex_ = 0;
while
(
++hashIndex_ < curHashTable_.objects_.size()
&& !curHashTable_.objects_[hashIndex_].size()
)
{}
if (hashIndex_ >= curHashTable_.objects_.size())
{
elementIndex_++;
// make end iterator
hashIndex_ = curHashTable_.keys_.size();
}
return *this;
@ -218,12 +287,12 @@ StaticHashTable<T, Key, Hash>::Iterator
template<class T, class Key, class Hash>
template<class TRef, class TableRef>
inline
typename StaticHashTable<T, Key, Hash>::template Iterator
typename Foam::StaticHashTable<T, Key, Hash>::template Iterator
<
TRef,
TableRef
>
StaticHashTable<T, Key, Hash>::Iterator
Foam::StaticHashTable<T, Key, Hash>::Iterator
<
TRef,
TableRef
@ -240,24 +309,23 @@ StaticHashTable<T, Key, Hash>::Iterator
template<class T, class Key, class Hash>
template<class TRef, class TableRef>
inline
const Key& StaticHashTable<T, Key, Hash>::Iterator<TRef, TableRef>::
key()
inline const Key&
Foam::StaticHashTable<T, Key, Hash>::Iterator<TRef, TableRef>::key()
{
return curStaticHashTable_.keys_[hashIndex_][elementIndex_];
return curHashTable_.keys_[hashIndex_][elementIndex_];
}
template<class T, class Key, class Hash>
inline typename StaticHashTable<T, Key, Hash>::iterator
StaticHashTable<T, Key, Hash>::begin()
inline typename Foam::StaticHashTable<T, Key, Hash>::iterator
Foam::StaticHashTable<T, Key, Hash>::begin()
{
// Find first non-empty entry
forAll(keys_, i)
forAll(keys_, hashIdx)
{
if (keys_[i].size() > 0)
if (keys_[hashIdx].size() > 0)
{
return iterator(*this, i, 0);
return iterator(*this, hashIdx, 0);
}
}
@ -273,23 +341,23 @@ StaticHashTable<T, Key, Hash>::begin()
template<class T, class Key, class Hash>
inline const typename StaticHashTable<T, Key, Hash>::iterator&
StaticHashTable<T, Key, Hash>::end()
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 StaticHashTable<T, Key, Hash>::const_iterator
StaticHashTable<T, Key, Hash>::begin() const
inline typename Foam::StaticHashTable<T, Key, Hash>::const_iterator
Foam::StaticHashTable<T, Key, Hash>::begin() const
{
// Find first non-empty entry
forAll(keys_, i)
forAll(keys_, hashIdx)
{
if (keys_[i].size() > 0)
if (keys_[hashIdx].size() > 0)
{
return const_iterator(*this, i, 0);
return const_iterator(*this, hashIdx, 0);
}
}
@ -305,8 +373,8 @@ StaticHashTable<T, Key, Hash>::begin() const
template<class T, class Key, class Hash>
inline const typename StaticHashTable<T, Key, Hash>::const_iterator&
StaticHashTable<T, Key, Hash>::end() const
inline const typename Foam::StaticHashTable<T, Key, Hash>::const_iterator&
Foam::StaticHashTable<T, Key, Hash>::end() const
{
return StaticHashTable<T, Key, Hash>::endConstIter_;
}
@ -314,6 +382,4 @@ StaticHashTable<T, Key, Hash>::end() const
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -28,16 +28,14 @@ License
#include "Istream.H"
#include "Ostream.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Construct from Istream
template<class T, class Key, class Hash>
StaticHashTable<T, Key, Hash>::StaticHashTable(Istream& is, const label size)
Foam::StaticHashTable<T, Key, Hash>::StaticHashTable
(
Istream& is,
const label size
)
:
StaticHashTableName(),
keys_(size),
@ -62,20 +60,20 @@ StaticHashTable<T, Key, Hash>::StaticHashTable(Istream& is, const label size)
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
template<class T, class Key, class Hash>
Istream& operator>>(Istream& is, StaticHashTable<T, Key, Hash>& L)
Foam::Istream& Foam::operator>>(Istream& is, StaticHashTable<T, Key, Hash>& L)
{
is.fatalCheck("operator>>(Istream&, StaticHashTable<T, Key, Hash>&)");
// Anull list
L.clear();
is.fatalCheck("operator>>(Istream& is, StaticHashTable<T, Key, Hash>& L)");
is.fatalCheck("operator>>(Istream&, StaticHashTable<T, Key, Hash>&)");
token firstToken(is);
is.fatalCheck
(
"operator>>(Istream& is, StaticHashTable<T, Key, Hash>& L) : "
"operator>>(Istream&, StaticHashTable<T, Key, Hash>&) : "
"reading first token"
);
@ -112,7 +110,7 @@ Istream& operator>>(Istream& is, StaticHashTable<T, Key, Hash>& L)
{
FatalIOErrorIn
(
"operator>>(Istream& is, StaticHashTable<T, Key, Hash>& L)",
"operator>>(Istream&, StaticHashTable<T, Key, Hash>&)",
is
) << "incorrect first token, '(', found " << firstToken.info()
<< exit(FatalIOError);
@ -128,7 +126,7 @@ Istream& operator>>(Istream& is, StaticHashTable<T, Key, Hash>& L)
{
FatalIOErrorIn
(
"operator>>(Istream& is, StaticHashTable<T, Key, Hash>& L)",
"operator>>(Istream&, StaticHashTable<T, Key, Hash>&)",
is
) << "incorrect first token, '(', found " << firstToken.info()
<< exit(FatalIOError);
@ -163,7 +161,7 @@ Istream& operator>>(Istream& is, StaticHashTable<T, Key, Hash>& L)
{
FatalIOErrorIn
(
"operator>>(Istream& is, StaticHashTable<T, Key, Hash>& L)",
"operator>>(Istream&, StaticHashTable<T, Key, Hash>&)",
is
) << "incorrect first token, expected <int> or '(', found "
<< firstToken.info()
@ -177,15 +175,15 @@ Istream& operator>>(Istream& is, StaticHashTable<T, Key, Hash>& L)
template<class T, class Key, class Hash>
Ostream& operator<<(Ostream& os, const StaticHashTable<T, Key, Hash>& L)
Foam::Ostream& Foam::operator<<
(
Ostream& os,
const StaticHashTable<T, Key, Hash>& L)
{
// Write size of StaticHashTable
os << nl << L.size();
// Write size of HashTable and start contents delimiter
os << nl << L.size() << nl << token::BEGIN_LIST << nl;
// Write beginning of contents
os << nl << token::BEGIN_LIST << nl;
// Write StaticHashTable contents
// Write contents
for
(
typename StaticHashTable<T, Key, Hash>::const_iterator iter = L.begin();
@ -196,7 +194,7 @@ Ostream& operator<<(Ostream& os, const StaticHashTable<T, Key, Hash>& L)
os << iter.key() << token::SPACE << iter() << nl;
}
// Write end of contents
// Write end of contents delimiter
os << token::END_LIST;
// Check state of IOstream
@ -206,8 +204,4 @@ Ostream& operator<<(Ostream& os, const StaticHashTable<T, Key, Hash>& L)
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //