Commit 946aac50 authored by Mark Olesen's avatar Mark Olesen
Browse files

HashTbl changes

- iterators store pointers instead of references to the HashTbl.
  This lets us use the default bitwise copy/assignment

- add empty constructor for iterators. It returns the equivalent to end().
  This lets us do this:
      HashTbl<label>::iterator iter;
      // some time later
      iter = find(Value);

- erase(const HashTbl<AnyType, Key, AnyHash>&) is now more generous.
  Only the Key type matters, not the hashing function.
parent 1fbcb6e2
......@@ -40,6 +40,7 @@ using namespace Foam;
int main()
{
HASHTABLE_CLASS<double> table1(13);
HASHTABLE_CLASS<double>::iterator iter;
table1.insert("aaa", 1.0);
table1.insert("aba", 2.0);
......@@ -52,8 +53,12 @@ int main()
table1.insert("adx", 9.0);
table1.insert("aec", 10.0);
// erase by key
table1.erase("aaw");
table1.erase("abs");
// erase by iterator
iter = table1.find("abs");
table1.erase(iter);
Info<< "\ntable1 toc: " << table1.toc() << endl;
Info<< "\ntable1 sortedToc: " << table1.sortedToc() << endl;
......
......@@ -66,8 +66,8 @@ Foam::HashTbl<T, Key, Hash>::HashTbl(const label size)
nElmts_(0),
tableSize_(canonicalSize(size)),
table_(NULL),
endIter_(*this, NULL, 0),
endConstIter_(*this, NULL, 0)
endIter_(),
endConstIter_()
{
if (tableSize_)
{
......@@ -88,8 +88,8 @@ Foam::HashTbl<T, Key, Hash>::HashTbl(const HashTbl<T, Key, Hash>& ht)
nElmts_(0),
tableSize_(ht.tableSize_),
table_(NULL),
endIter_(*this, NULL, 0),
endConstIter_(*this, NULL, 0)
endIter_(),
endConstIter_()
{
if (tableSize_)
{
......@@ -117,8 +117,8 @@ Foam::HashTbl<T, Key, Hash>::HashTbl
nElmts_(0),
tableSize_(0),
table_(NULL),
endIter_(*this, NULL, 0),
endConstIter_(*this, NULL, 0)
endIter_(),
endConstIter_()
{
transfer(ht());
}
......@@ -182,7 +182,7 @@ Foam::HashTbl<T, Key, Hash>::find
{
if (key == ep->key_)
{
return iterator(*this, ep, hashIdx);
return iterator(this, ep, hashIdx);
}
}
}
......@@ -214,7 +214,7 @@ Foam::HashTbl<T, Key, Hash>::find
{
if (key == ep->key_)
{
return const_iterator(*this, ep, hashIdx);
return const_iterator(this, ep, hashIdx);
}
}
}
......@@ -344,7 +344,8 @@ bool Foam::HashTbl<T, Key, Hash>::set
template<class T, class Key, class Hash>
bool Foam::HashTbl<T, Key, Hash>::erase(const iterator& cit)
{
if (cit.elmtPtr_) // note: endIter_ also has 0 elmtPtr_
// note: endIter_ has NULL elmtPtr_, so this also catches that
if (cit.elmtPtr_)
{
// Search element before elmtPtr_
hashedEntry* prev = 0;
......@@ -377,9 +378,8 @@ bool Foam::HashTbl<T, Key, Hash>::erase(const iterator& cit)
// assign an non-NULL value so it doesn't look like end()/cend()
iter.elmtPtr_ = reinterpret_cast<hashedEntry*>(this);
// mark with special hashIndex value
// to signal that it has been rewound
// the next increment will bring it bach to the present location
// mark with special hashIndex value to signal it has been rewound
// the next increment will bring it back to the present location
iter.hashIndex_ = -iter.hashIndex_ - 1;
}
......@@ -400,7 +400,7 @@ bool Foam::HashTbl<T, Key, Hash>::erase(const iterator& cit)
# ifdef FULLDEBUG
if (debug)
{
Info<< "HashTbl<T, Key, Hash>::erase(iterator&) : "
Info<< "HashTbl<T, Key, Hash>::erase(const iterator&) : "
<< "cannot remove hashedEntry from hash table\n";
}
# endif
......@@ -448,10 +448,10 @@ Foam::label Foam::HashTbl<T, Key, Hash>::erase(const UList<Key>& keys)
template<class T, class Key, class Hash>
template<class AnyType>
template<class AnyType, class AnyHash>
Foam::label Foam::HashTbl<T, Key, Hash>::erase
(
const HashTbl<AnyType, Key, Hash>& rhs
const HashTbl<AnyType, Key, AnyHash>& rhs
)
{
label count = 0;
......
......@@ -119,7 +119,7 @@ class HashTbl
//- The current number of elements in table
label nElmts_;
//- Number of primary entries allocated in table (not necessarily used)
//- Number of primary entries allocated in table
label tableSize_;
//- The table of primary entries
......@@ -140,17 +140,18 @@ class HashTbl
public:
// Forward declaration of STL iterators
class iterator;
class const_iterator;
//- Declare friendship with the HashPtrTable class
template<class T2, class Key2, class Hash2>
friend class HashPtrTable;
// Forward declaration of STL iterators
class iterator;
//- Declare friendship with the iterator
friend class iterator;
class const_iterator;
//- Declare friendship with the const_iterator
friend class const_iterator;
......@@ -181,7 +182,7 @@ public:
//- The size of the underlying table
inline label capacity() const;
//- Return number of elements in table.
//- Return number of elements in table
inline label size() const;
//- Return true if the hash table is empty
......@@ -215,10 +216,11 @@ public:
//- Assign a new hashedEntry, overwriting existing entries
inline bool set(const Key&, const T& newElmt);
//- Erase an hashedEntry specified by given iterator
//- Erase a hashedEntry specified by given iterator
// This invalidates the iterator until the operator++
bool erase(const iterator&);
//- Erase an hashedEntry specified by given key if in table
//- Erase a hashedEntry specified by the given key
bool erase(const Key&);
//- Remove entries given by the listed keys from this HashTbl
......@@ -227,10 +229,10 @@ public:
//- Remove entries given by the given keys from this HashTbl
// Return the number of elements removed.
// The parameter HashTbl needs the same type of keys, but
// but the type of values held is arbitrary.
template<class AnyType>
label erase(const HashTbl<AnyType, Key, Hash>&);
// The parameter HashTbl needs the same type of key, but the
// type of values held and the hashing function is arbitrary.
template<class AnyType, class AnyHash>
label erase(const HashTbl<AnyType, Key, AnyHash>&);
//- Resize the hash table for efficiency
void resize(const label newSize);
......@@ -255,13 +257,13 @@ public:
// Member Operators
//- Find and return an hashedEntry
//- Find and return a hashedEntry
inline T& operator[](const Key&);
//- Find and return an hashedEntry
//- Find and return a hashedEntry
inline const T& operator[](const Key&) const;
//- Find and return an hashedEntry, create it null if not present.
//- Find and return a hashedEntry, create it null if not present
inline T& operator()(const Key&);
//- Assignment
......@@ -295,7 +297,7 @@ public:
typedef label size_type;
// STL iterator
// Iterators and helpers
//- An STL-conforming iterator
class iterator
......@@ -305,8 +307,9 @@ public:
// Private data
//- Reference to the HashTbl this is an iterator for
HashTbl<T, Key, Hash>& hashTable_;
//- Pointer to the HashTbl for which this is an iterator
// This also lets us use the default bitwise copy/assignment
HashTbl<T, Key, Hash>* hashTable_;
//- Current element
hashedEntry* elmtPtr_;
......@@ -318,34 +321,43 @@ public:
// Constructors
//- Construct null (end iterator)
inline iterator();
//- Construct from hash table, element and hash index
inline iterator
(
HashTbl<T, Key, Hash>& curHashTbl,
HashTbl<T, Key, Hash>* curHashTbl,
hashedEntry* elmt,
label hashIndex
const label hashIndex
);
// Member operators
inline void operator=(const iterator&);
// Access
//- Return the Key corresponding to the iterator
inline const Key& key() const;
//- Compare hashedEntry element pointers
inline bool operator==(const iterator&) const;
inline bool operator!=(const iterator&) const;
//- Compare hashedEntry element pointers
inline bool operator==(const const_iterator&) const;
inline bool operator!=(const const_iterator&) const;
//- Return referenced hash value
inline T& operator*();
inline T& operator()();
//- Return referenced hash value
inline const T& operator*() const;
inline const T& operator()() const;
inline iterator& operator++();
inline iterator operator++(int);
inline const Key& key() const;
};
......@@ -365,8 +377,9 @@ public:
// Private data
//- Reference to the HashTbl this is an iterator for
const HashTbl<T, Key, Hash>& hashTable_;
//- Pointer to the HashTbl for which this is an iterator
// This also lets us use the default bitwise copy/assignment
const HashTbl<T, Key, Hash>* hashTable_;
//- Current element
const hashedEntry* elmtPtr_;
......@@ -374,17 +387,19 @@ public:
//- Current hash index
label hashIndex_;
public:
// Constructors
//- Construct null (end iterator)
inline const_iterator();
//- Construct from hash table, element and hash index
inline const_iterator
(
const HashTbl<T, Key, Hash>& curHashTbl,
const HashTbl<T, Key, Hash>* curHashTbl,
const hashedEntry* elmt,
label hashIndex
const label hashIndex
);
//- Construct from the non-const iterator
......@@ -393,21 +408,26 @@ public:
// Member operators
inline void operator=(const const_iterator&);
// Access
//- Return the Key corresponding to the iterator
inline const Key& key() const;
//- Compare hashedEntry element pointers
inline bool operator==(const const_iterator&) const;
inline bool operator!=(const const_iterator&) const;
//- Compare hashedEntry element pointers
inline bool operator==(const iterator&) const;
inline bool operator!=(const iterator&) const;
//- Return referenced hash value
inline const T& operator*() const;
inline const T& operator()() const;
inline const_iterator& operator++();
inline const_iterator operator++(int);
inline const Key& key() const;
};
......
......@@ -164,9 +164,9 @@ inline T& Foam::HashTbl<T, Key, Hash>::operator()(const Key& key)
template<class T, class Key, class Hash>
inline Foam::HashTbl<T, Key, Hash>::iterator::iterator
(
HashTbl<T, Key, Hash>& hashTbl,
HashTbl<T, Key, Hash>* hashTbl,
hashedEntry* elmt,
label hashIndex
const label hashIndex
)
:
hashTable_(hashTbl),
......@@ -176,14 +176,12 @@ inline Foam::HashTbl<T, Key, Hash>::iterator::iterator
template<class T, class Key, class Hash>
inline void Foam::HashTbl<T, Key, Hash>::iterator::operator=
(
const iterator& iter
)
{
elmtPtr_ = iter.elmtPtr_;
hashIndex_ = iter.hashIndex_;
}
inline Foam::HashTbl<T, Key, Hash>::iterator::iterator()
:
hashTable_(0),
elmtPtr_(0),
hashIndex_(0)
{}
template<class T, class Key, class Hash>
......@@ -278,12 +276,12 @@ Foam::HashTbl<T, Key, Hash>::iterator::operator++()
// Step to the next table entry
while
(
++hashIndex_ < hashTable_.tableSize_
&& !(elmtPtr_ = hashTable_.table_[hashIndex_])
++hashIndex_ < hashTable_->tableSize_
&& !(elmtPtr_ = hashTable_->table_[hashIndex_])
)
{}
if (hashIndex_ >= hashTable_.tableSize_)
if (hashIndex_ >= hashTable_->tableSize_)
{
// make an end iterator
elmtPtr_ = 0;
......@@ -318,19 +316,19 @@ template<class T, class Key, class Hash>
inline typename Foam::HashTbl<T, Key, Hash>::iterator
Foam::HashTbl<T, Key, Hash>::begin()
{
label i = 0;
label hashIdx = 0;
if (nElmts_)
{
while (table_ && !table_[i] && ++i < tableSize_)
while (table_ && !table_[hashIdx] && ++hashIdx < tableSize_)
{}
}
else
{
i = tableSize_;
hashIdx = tableSize_;
}
if (i == tableSize_)
if (hashIdx >= tableSize_)
{
# ifdef FULLDEBUG
if (debug)
......@@ -343,7 +341,7 @@ Foam::HashTbl<T, Key, Hash>::begin()
}
else
{
return iterator(*this, table_[i], i);
return iterator(this, table_[hashIdx], hashIdx);
}
}
......@@ -358,12 +356,21 @@ Foam::HashTbl<T, Key, Hash>::end()
// * * * * * * * * * * * * * * * STL const_iterator * * * * * * * * * * * * * //
template<class T, class Key, class Hash>
inline Foam::HashTbl<T, Key, Hash>::const_iterator::const_iterator()
:
hashTable_(0),
elmtPtr_(0),
hashIndex_(0)
{}
template<class T, class Key, class Hash>
inline Foam::HashTbl<T, Key, Hash>::const_iterator::const_iterator
(
const HashTbl<T, Key, Hash>& hashTbl,
const HashTbl<T, Key, Hash>* hashTbl,
const hashedEntry* elmt,
label hashIndex
const label hashIndex
)
:
hashTable_(hashTbl),
......@@ -384,17 +391,6 @@ inline Foam::HashTbl<T, Key, Hash>::const_iterator::const_iterator
{}
template<class T, class Key, class Hash>
inline void Foam::HashTbl<T, Key, Hash>::const_iterator::operator=
(
const const_iterator& iter
)
{
elmtPtr_ = iter.elmtPtr_;
hashIndex_ = iter.hashIndex_;
}
template<class T, class Key, class Hash>
inline bool Foam::HashTbl<T, Key, Hash>::const_iterator::operator==
(
......@@ -458,14 +454,14 @@ Foam::HashTbl<T, Key, Hash>::const_iterator::operator++()
if
(
!(elmtPtr_ = elmtPtr_->next_)
&& ++hashIndex_ < hashTable_.tableSize_
&& !(elmtPtr_ = hashTable_.table_[hashIndex_])
&& ++hashIndex_ < hashTable_->tableSize_
&& !(elmtPtr_ = hashTable_->table_[hashIndex_])
)
{
while
(
++hashIndex_ < hashTable_.tableSize_
&& !(elmtPtr_ = hashTable_.table_[hashIndex_])
++hashIndex_ < hashTable_->tableSize_
&& !(elmtPtr_ = hashTable_->table_[hashIndex_])
)
{}
}
......@@ -499,19 +495,19 @@ template<class T, class Key, class Hash>
inline typename Foam::HashTbl<T, Key, Hash>::const_iterator
Foam::HashTbl<T, Key, Hash>::cbegin() const
{
label i = 0;
label hashIdx = 0;
if (nElmts_)
{
while (table_ && !table_[i] && ++i < tableSize_)
while (table_ && !table_[hashIdx] && ++hashIdx < tableSize_)
{}
}
else
{
i = tableSize_;
hashIdx = tableSize_;
}
if (i == tableSize_)
if (hashIdx >= tableSize_)
{
# ifdef FULLDEBUG
if (debug)
......@@ -524,7 +520,7 @@ Foam::HashTbl<T, Key, Hash>::cbegin() const
}
else
{
return const_iterator(*this, table_[i], i);
return const_iterator(this, table_[hashIdx], hashIdx);
}
}
......
......@@ -37,8 +37,8 @@ Foam::HashTbl<T, Key, Hash>::HashTbl(Istream& is, const label size)
nElmts_(0),
tableSize_(canonicalSize(size)),
table_(new hashedEntry*[tableSize_]),
endIter_(*this, NULL, 0),
endConstIter_(*this, NULL, 0)
endIter_(),
endConstIter_()
{
for (label hashIdx = 0; hashIdx < tableSize_; hashIdx++)
{
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment