home *** CD-ROM | disk | FTP | other *** search
- #ifndef __RWTVHASHT_H__
- #define __RWTVHASHT_H__
- pragma push_align_members(64);
-
- /*
- * RWTValHashTable<T>: A Bag of values T, implemented using a hashed lookup
- *
- * $Header: E:/vcs/rw/tvhasht.h_v 1.2 17 Mar 1992 11:31:38 KEFFER $
- *
- ****************************************************************************
- *
- * Rogue Wave Software, Inc.
- * P.O. Box 2328
- * Corvallis, OR 97339
- *
- * Copyright (C) 1992. This software is subject to copyright
- * protection under the laws of the United States and other countries.
- *
- ***************************************************************************
- *
- * This class implements a parameterized hash table of types T.
- * It uses chaining to resolve hash collisions.
- *
- * Example use of this class:
- *
- * #include <rw/cstring.h>
- * #include <rw/tvhasht.h>
- *
- * unsigned myHash(const RWCString& s){ return s.hash(); }
- *
- * RWTValHashTable<RWCString> bag(myHash); // A bag of RWCStrings
- *
- * bag.insert("a string"); // Type conversion: char* to RWCString happens
- * bag.insert("another string");
- * bag.contains("a string"); // Returns true.
- *
- *
- * Note that the constructor for RWTValHashTable<T> takes a function with
- * prototype
- *
- * unsigned hashFun(const T&);
- *
- * It should return a suitable hashing value for an instance of class T.
- * Usually, the definition for such a function is trivial because hashing
- * functions have been defined for all Rogue Wave supplied classes.
- *
- ***************************************************************************
- *
- * $Log: E:/vcs/rw/tvhasht.h_v $
- *
- * Rev 1.2 17 Mar 1992 11:31:38 KEFFER
- *
- * Rev 1.1 04 Mar 1992 10:22:04 KEFFER
- *
- * Rev 1.0 02 Mar 1992 16:10:52 KEFFER
- * Initial revision.
- */
-
- //$DECLARE_TEMPLATE
-
- #include "rw/tvslist.h"
- #include "rw/tvvector.h"
-
- /****************************************************************
- * *
- * Declarations for RWTValHashTable<T> *
- * *
- ****************************************************************/
-
- template <class T> class RWTValHashTable {
-
- protected:
-
- typedef RWTValSlist<T> CHAIN;
- typedef RWTValVector<CHAIN*> CHAINVEC;
- typedef RWTValSlistIterator<T> CHAINITERATOR;
- friend class RWTValHashTableIterator<T>;
-
- CHAINVEC _table;
- unsigned _nitems;
- unsigned (*_hashFun)(const T&); // User-supplied hashing function
-
- int hashIndex(const T& val) const {return (int)((*_hashFun)(val) % _table.length());}
-
- public:
-
- RWTValHashTable(unsigned (*hashFun)(const T&), unsigned size = RWDEFAULT_CAPACITY);
- RWTValHashTable(const RWTValHashTable<T>&);
- ~RWTValHashTable() {clear();}
-
- RWTValHashTable& operator=(const RWTValHashTable<T>&);
-
- // Member functions:
- void apply(void (*applyFun)(T, void*), void*);
- void clear();
- RWBoolean contains(T val) const;
- unsigned entries() const {return _nitems;}
- RWBoolean find(T a, T& k) const; // Find first occurrence
- void insert(T val);
- RWBoolean isEmpty() const {return _nitems==0;}
- unsigned occurrencesOf(T val) const;
- RWBoolean remove(T val);
- unsigned removeAll(T val);
- void resize(unsigned);
-
- };
-
-
- /****************************************************************
- * *
- * Declarations for RWTValHashTableIterator<T> *
- * *
- ****************************************************************/
-
- template <class T> class RWTValHashTableIterator {
-
- typedef RWTValSlist<T> CHAIN;
- typedef RWTValSlistIterator<T> CHAINITERATOR;
- typedef RWTValHashTable<T> HASHTABLE;
-
- HASHTABLE* _myHash;
- int _idx;
- CHAINITERATOR* _iterator;
-
- void nextIterator();
-
- public:
-
- RWTValHashTableIterator(HASHTABLE& t);
-
- RWBoolean operator++(); // Advance and test
- HASHTABLE* container() const {return _myHash;}
- T key() const {return _iterator->key();}
- void reset();
- void reset(HASHTABLE& t);
- };
-
-
-
- //$IMPLEMENT_TEMPLATE
-
- /****************************************************************
- * *
- * Definitions for RWTValHashTable<T> *
- * *
- ****************************************************************/
-
- template <class T>
- RWTValHashTable<T>::RWTValHashTable(unsigned (*hashFun)(const T&), unsigned size) :
- _table(size, rwnil),
- _nitems(0),
- _hashFun(hashFun)
- {
- }
-
- template <class T>
- RWTValHashTable<T>::RWTValHashTable(const RWTValHashTable<T>& v) :
- _table(v._table.length(), rwnil),
- _nitems(v._nitems),
- _hashFun(v._hashFun)
- {
- int N = _table.length();
- for (int i=0; i<N; i++){
- if (v._table(i)) _table(i) = new CHAIN(*v._table(i));
- }
- }
-
- template <class T> RWTValHashTable<T>&
- RWTValHashTable<T>::operator=(const RWTValHashTable<T>& v)
- {
- int N;
- clear();
- _table.reshape(N=v._table.length());
- _hashFun = v._hashFun;
- for (int i=0; i<N; i++){
- _table(i) = v._table(i) ? new CHAIN(*v._table(i)) : rwnil;
- }
- _nitems = v._nitems;
- return *this;
- }
-
- template <class T> void
- RWTValHashTable<T>::apply(void (*applyFun)(T, void*), void* a)
- {
- int N = _table.length();
- for (int i=0; i<N; i++) {
- if (_table(i)) _table(i)->apply(applyFun,a);
- }
- }
-
- template <class T> void
- RWTValHashTable<T>::clear()
- {
- int i = _table.length();
- while (i--) { delete _table(i); _table(i) = rwnil; }
-
- _nitems = 0;
- }
-
- template <class T> RWBoolean
- RWTValHashTable<T>::contains(T val) const
- {
- CHAIN* p = _table(hashIndex(val));
- return p ? p->contains(val) : FALSE;
- }
-
- template <class T> RWBoolean
- RWTValHashTable<T>::find(T val, T& retVal) const
- {
- CHAIN* p = _table(hashIndex(val));
- return p ? p->find(val, retVal) : FALSE;
- }
-
- template <class T> void
- RWTValHashTable<T>::insert(T val)
- {
- int idx = (int)hashIndex(val);
- if (_table(idx)==rwnil) _table(idx) = new CHAIN;
- _table(idx)->insert(val);
- _nitems++;
- }
-
- template <class T> unsigned
- RWTValHashTable<T>::occurrencesOf(T val) const
- {
- CHAIN* p = _table(hashIndex(val));
- return p ? p->occurrencesOf(val) : 0;
- }
-
- template <class T> RWBoolean
- RWTValHashTable<T>::remove(T val)
- {
- CHAIN* p = _table(hashIndex(val));
- RWBoolean ret = p ? p->remove(val) : FALSE;
- if (ret) _nitems--;
- return ret;
- }
-
- template <class T> unsigned
- RWTValHashTable<T>::removeAll(T val)
- {
- CHAIN* p = _table(hashIndex(val));
- unsigned count = p ? p->removeAll(val) : 0;
- _nitems -= count;
- return count;
- }
-
- template <class T> void
- RWTValHashTable<T>::resize(unsigned N)
- {
- CHAINVEC tempTable =_table; // Save old values
- _table.reshape(N); // Resize internal table
- _table = rwnil; // Zero it
- _nitems = 0;
-
- // Now iterate through the old collection, inserting each item
- for (int i=0; i<tempTable.length(); i++){
- if (tempTable(i)) {
- CHAINITERATOR next(*tempTable(i));
- while ( ++next ) insert(next.key());
- delete tempTable(i);
- }
- }
- }
-
- /****************************************************************
- * *
- * Definitions for RWTValHashTableIterator<T> *
- * *
- ****************************************************************/
-
- template <class T>
- RWTValHashTableIterator<T>::RWTValHashTableIterator(RWTValHashTable<T>& t) :
- _myHash(&t),
- _idx(-1),
- _iterator(rwnil)
- {
- nextIterator(); // Advance to the next iterator
- }
-
- template <class T> RWBoolean
- RWTValHashTableIterator<T>::operator++()
- {
- while ( _iterator && ++(*_iterator)==FALSE ) {
- nextIterator();
- }
- return _iterator!=rwnil;
- }
-
- template <class T> void
- RWTValHashTableIterator<T>::reset()
- {
- _idx = -1;
- nextIterator();
- }
-
- template <class T> void
- RWTValHashTableIterator<T>::reset(RWTValHashTable<T>& t)
- {
- _myHash = &t;
- _idx = -1;
- nextIterator();
- }
-
- template <class T> void
- RWTValHashTableIterator<T>::nextIterator()
- {
- while (++_idx < _myHash->_table.length()) {
- if (_myHash->_table(_idx)) {
- if (_iterator) _iterator->reset(*_myHash->_table(_idx));
- else _iterator = new CHAINITERATOR(*_myHash->_table(_idx));
- return;
- }
- }
- delete _iterator;
- _iterator = rwnil;
- }
-
- pragma pop_align_members();
- #endif /* __RWTVHASHT_H__ */
-