You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xerces.apache.org by tn...@apache.org on 2001/02/27 19:24:03 UTC

cvs commit: xml-xerces/c/src/util RefHash2KeysTableOf.c RefHash2KeysTableOf.hpp Makefile.in

tng         01/02/27 10:24:03

  Modified:    c/Projects/Win32/VC6/xerces-all/XercesLib XercesLib.dsp
               c/src/util Makefile.in
  Added:       c/src/util RefHash2KeysTableOf.c RefHash2KeysTableOf.hpp
  Log:
  Schema: Add utility RefHash2KeysTableOf.
  
  Revision  Changes    Path
  1.50      +4 -0      xml-xerces/c/Projects/Win32/VC6/xerces-all/XercesLib/XercesLib.dsp
  
  Index: XercesLib.dsp
  ===================================================================
  RCS file: /home/cvs/xml-xerces/c/Projects/Win32/VC6/xerces-all/XercesLib/XercesLib.dsp,v
  retrieving revision 1.49
  retrieving revision 1.50
  diff -u -r1.49 -r1.50
  --- XercesLib.dsp	2001/02/27 14:48:25	1.49
  +++ XercesLib.dsp	2001/02/27 18:23:55	1.50
  @@ -324,6 +324,10 @@
   # End Source File
   # Begin Source File
   
  +SOURCE=..\..\..\..\..\src\util\RefHash2KeysTableOf.hpp
  +# End Source File
  +# Begin Source File
  +
   SOURCE=..\..\..\..\..\src\util\RefStackOf.hpp
   # End Source File
   # Begin Source File
  
  
  
  1.28      +5 -0      xml-xerces/c/src/util/Makefile.in
  
  Index: Makefile.in
  ===================================================================
  RCS file: /home/cvs/xml-xerces/c/src/util/Makefile.in,v
  retrieving revision 1.27
  retrieving revision 1.28
  diff -u -r1.27 -r1.28
  --- Makefile.in	2001/02/26 19:44:23	1.27
  +++ Makefile.in	2001/02/27 18:23:59	1.28
  @@ -55,6 +55,9 @@
   #
   #
   # $Log: Makefile.in,v $
  +# Revision 1.28  2001/02/27 18:23:59  tng
  +# Schema: Add utility RefHash2KeysTableOf.
  +#
   # Revision 1.27  2001/02/26 19:44:23  tng
   # Schema: add utility class QName, by Pei Yong Zhang.
   #
  @@ -239,6 +242,7 @@
       PlatformUtils.hpp \
       QName.hpp \
       RefArrayOf.hpp \
  +    RefHash2KeysTableOf.hpp \
       RefHashTableOf.hpp \
       RefStackOf.hpp \
       RefVectorOf.hpp \
  @@ -284,6 +288,7 @@
       KeyValuePair.c \
       NameIdPool.c \
       RefArrayOf.c \
  +    RefHash2KeysTableOf.c \
       RefHashTableOf.c \
       RefStackOf.c \
       RefVectorOf.c \
  
  
  
  1.1                  xml-xerces/c/src/util/RefHash2KeysTableOf.c
  
  Index: RefHash2KeysTableOf.c
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xerces" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache\@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation, and was
   * originally based on software copyright (c) 1999, International
   * Business Machines, Inc., http://www.ibm.com .  For more information
   * on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  /**
   * $Log: RefHash2KeysTableOf.c,v $
   * Revision 1.1  2001/02/27 18:24:00  tng
   * Schema: Add utility RefHash2KeysTableOf.
   *
   */
  
  
  // ---------------------------------------------------------------------------
  //  Include
  // ---------------------------------------------------------------------------
  #if defined(XERCES_TMPLSINC)
  #include <util/RefHash2KeysTableOf.hpp>
  #endif
  
  
  // ---------------------------------------------------------------------------
  //  RefHash2KeysTableOf: Constructors and Destructor
  // ---------------------------------------------------------------------------
  template <class TVal> RefHash2KeysTableOf<TVal>::RefHash2KeysTableOf(const unsigned int modulus, const bool adoptElems)
  	: fAdoptedElems(adoptElems), fBucketList(0), fHashModulus(modulus)
  {
      initialize(modulus);
  	
  	// create default hasher
  	fHash = new HashXMLCh();
  }
  
  template <class TVal> RefHash2KeysTableOf<TVal>::RefHash2KeysTableOf(const unsigned int modulus, const bool adoptElems, HashBase* hash)
  	: fAdoptedElems(adoptElems), fBucketList(0), fHashModulus(modulus)
  {
  	initialize(modulus);
  	// set hasher
  	fHash = hash;
  }
  
  template <class TVal> RefHash2KeysTableOf<TVal>::RefHash2KeysTableOf(const unsigned int modulus)
  	: fAdoptedElems(true), fBucketList(0), fHashModulus(modulus)
  {
  	initialize(modulus);
  
  	// create default hasher
  	fHash = new HashXMLCh();
  }
  
  template <class TVal> void RefHash2KeysTableOf<TVal>::initialize(const unsigned int modulus)
  {
  	if (modulus == 0)
          ThrowXML(IllegalArgumentException, XMLExcepts::HshTbl_ZeroModulus);
  
      // Allocate the bucket list and zero them
      fBucketList = new RefHash2KeysTableBucketElem<TVal>*[fHashModulus];
      for (unsigned int index = 0; index < fHashModulus; index++)
          fBucketList[index] = 0;
  }
  
  template <class TVal> RefHash2KeysTableOf<TVal>::~RefHash2KeysTableOf()
  {
      removeAll();
  
      // Then delete the bucket list & hasher
      delete [] fBucketList;
  	delete fHash;
  }
  
  
  // ---------------------------------------------------------------------------
  //  RefHash2KeysTableOf: Element management
  // ---------------------------------------------------------------------------
  template <class TVal> bool RefHash2KeysTableOf<TVal>::isEmpty() const
  {
      // Just check the bucket list for non-empty elements
      for (unsigned int buckInd = 0; buckInd < fHashModulus; buckInd++)
      {
          if (fBucketList[buckInd] != 0)
              return false;
      }
      return true;
  }
  
  template <class TVal> bool RefHash2KeysTableOf<TVal>::
  containsKey(const void* const key1, const int key2) const
  {
      unsigned int hashVal;
      const RefHash2KeysTableBucketElem<TVal>* findIt = findBucketElem(key1, key2, hashVal);
      return (findIt != 0);
  }
  
  template <class TVal> void RefHash2KeysTableOf<TVal>::
  removeKey(const void* const key1, const int key2)
  {
      unsigned int hashVal;
      removeBucketElem(key1, key2, hashVal);
  }
  
  template <class TVal> void RefHash2KeysTableOf<TVal>::removeAll()
  {
      // Clean up the buckets first
      for (unsigned int buckInd = 0; buckInd < fHashModulus; buckInd++)
      {
          // Get the bucket list head for this entry
          RefHash2KeysTableBucketElem<TVal>* curElem = fBucketList[buckInd];
          RefHash2KeysTableBucketElem<TVal>* nextElem;
          while (curElem)
          {
              // Save the next element before we hose this one
              nextElem = curElem->fNext;
  
              // If we adopted the data, then delete it too
              //    (Note:  the userdata hash table instance has data type of void *.
              //    This will generate compiler warnings here on some platforms, but they
              //    can be ignored since fAdoptedElements is false.
              if (fAdoptedElems)
                  delete curElem->fData;
  
              // Then delete the current element and move forward
              delete curElem;
              curElem = nextElem;
          }
  
          // Clean out this entry
          fBucketList[buckInd] = 0;
      }
  }
  
  
  // ---------------------------------------------------------------------------
  //  RefHash2KeysTableOf: Getters
  // ---------------------------------------------------------------------------
  template <class TVal> TVal* RefHash2KeysTableOf<TVal>::get(const void* const key1, const int key2)
  {
      unsigned int hashVal;
      RefHash2KeysTableBucketElem<TVal>* findIt = findBucketElem(key1, key2, hashVal);
      if (!findIt)
          return 0;
      return findIt->fData;
  }
  
  template <class TVal> const TVal* RefHash2KeysTableOf<TVal>::
  get(const void* const key1, const int key2) const
  {
      unsigned int hashVal;
      const RefHash2KeysTableBucketElem<TVal>* findIt = findBucketElem(key1, key2, hashVal);
      if (!findIt)
          return 0;
      return findIt->fData;
  }
  
  
  // ---------------------------------------------------------------------------
  //  RefHash2KeysTableOf: Putters
  // ---------------------------------------------------------------------------
  template <class TVal> void RefHash2KeysTableOf<TVal>::put(void* key1, int key2, TVal* const valueToAdopt)
  {
      // First see if the key exists already
      unsigned int hashVal;
      RefHash2KeysTableBucketElem<TVal>* newBucket = findBucketElem(key1, key2, hashVal);
  
      //
      //  If so,then update its value. If not, then we need to add it to
      //  the right bucket
      //
      if (newBucket)
      {
          if (fAdoptedElems)
              delete newBucket->fData;
          newBucket->fData = valueToAdopt;
  		newBucket->fKey1 = key1;
  		newBucket->fKey2 = key2;
      }
       else
      {
          newBucket = new RefHash2KeysTableBucketElem<TVal>(key1, key2, valueToAdopt, fBucketList[hashVal]);
          fBucketList[hashVal] = newBucket;
      }
  }
  
  
  
  // ---------------------------------------------------------------------------
  //  RefHash2KeysTableOf: Private methods
  // ---------------------------------------------------------------------------
  template <class TVal> RefHash2KeysTableBucketElem<TVal>* RefHash2KeysTableOf<TVal>::
  findBucketElem(const void* const key1, const int key2, unsigned int& hashVal)
  {
      // Hash the key
      hashVal = fHash->getHashVal(key1, fHashModulus);
      if (hashVal > fHashModulus)
          ThrowXML(RuntimeException, XMLExcepts::HshTbl_BadHashFromKey);
  
      // Search that bucket for the key
      RefHash2KeysTableBucketElem<TVal>* curElem = fBucketList[hashVal];
      while (curElem)
      {
  		if (fHash->equals(key1, curElem->fKey1) && (key2==curElem->fKey2))
              return curElem;
  
          curElem = curElem->fNext;
      }
      return 0;
  }
  
  template <class TVal> const RefHash2KeysTableBucketElem<TVal>* RefHash2KeysTableOf<TVal>::
  findBucketElem(const void* const key1, const int key2, unsigned int& hashVal) const
  {
      // Hash the key
      hashVal = fHash->getHashVal(key1, fHashModulus);
      if (hashVal > fHashModulus)
          ThrowXML(RuntimeException, XMLExcepts::HshTbl_BadHashFromKey);
  
      // Search that bucket for the key
      const RefHash2KeysTableBucketElem<TVal>* curElem = fBucketList[hashVal];
      while (curElem)
      {
          if (fHash->equals(key1, curElem->fKey1) && (key2==curElem->fKey2))
              return curElem;
  
          curElem = curElem->fNext;
      }
      return 0;
  }
  
  
  template <class TVal> void RefHash2KeysTableOf<TVal>::
  removeBucketElem(const void* const key1, const int key2, unsigned int& hashVal)
  {
      // Hash the key
      hashVal = fHash->getHashVal(key1, fHashModulus);
      if (hashVal > fHashModulus)
          ThrowXML(RuntimeException, XMLExcepts::HshTbl_BadHashFromKey);
  
      //
      //  Search the given bucket for this key. Keep up with the previous
      //  element so we can patch around it.
      //
      RefHash2KeysTableBucketElem<TVal>* curElem = fBucketList[hashVal];
      RefHash2KeysTableBucketElem<TVal>* lastElem = 0;
  
      while (curElem)
      {
          if (fHash->equals(key1, curElem->fKey) && (key2==curElem->fKey2))
          {
              if (!lastElem)
              {
                  // It was the first in the bucket
                  fBucketList[hashVal] = curElem->fNext;
              }
               else
              {
                  // Patch around the current element
                  lastElem->fNext = curElem->fNext;
              }
  
              // If we adopted the elements, then delete the data
              if (fAdoptedElems)
                  delete curElem->fData;
  
              // Delete the current element
              delete curElem;
  
              return;
          }
  
          // Move both pointers upwards
          lastElem = curElem;
          curElem = curElem->fNext;
      }
  
      // We never found that key
      ThrowXML(NoSuchElementException, XMLExcepts::HshTbl_NoSuchKeyExists);
  }
  
  
  
  
  // ---------------------------------------------------------------------------
  //  RefHash2KeysTableOfEnumerator: Constructors and Destructor
  // ---------------------------------------------------------------------------
  template <class TVal> RefHash2KeysTableOfEnumerator<TVal>::
  RefHash2KeysTableOfEnumerator(RefHash2KeysTableOf<TVal>* const toEnum, const bool adopt)
  	: fAdopted(adopt), fCurElem(0), fCurHash((unsigned int)-1), fToEnum(toEnum)
  {
      //
      //  Find the next available bucket element in the hash table. If it
      //  comes back zero, that just means the table is empty.
      //
      //  Note that the -1 in the current hash tells it to start from the
      //  beginning.
      //
      findNext();
  }
  
  template <class TVal> RefHash2KeysTableOfEnumerator<TVal>::~RefHash2KeysTableOfEnumerator()
  {
      if (fAdopted)
          delete fToEnum;
  }
  
  
  // ---------------------------------------------------------------------------
  //  RefHash2KeysTableOfEnumerator: Enum interface
  // ---------------------------------------------------------------------------
  template <class TVal> bool RefHash2KeysTableOfEnumerator<TVal>::hasMoreElements() const
  {
      //
      //  If our current has is at the max and there are no more elements
      //  in the current bucket, then no more elements.
      //
      if (!fCurElem && (fCurHash == fToEnum->fHashModulus))
          return false;
      return true;
  }
  
  template <class TVal> TVal& RefHash2KeysTableOfEnumerator<TVal>::nextElement()
  {
      // Make sure we have an element to return
      if (!hasMoreElements())
          ThrowXML(NoSuchElementException, XMLExcepts::Enum_NoMoreElements);
  
      //
      //  Save the current element, then move up to the next one for the
      //  next time around.
      //
      RefHash2KeysTableBucketElem<TVal>* saveElem = fCurElem;
      findNext();
  
      return *saveElem->fData;
  }
  
  
  template <class TVal> void RefHash2KeysTableOfEnumerator<TVal>::Reset()
  {
      fCurHash = (unsigned int)-1;
      fCurElem = 0;
      findNext();
  }
  
  
  
  // ---------------------------------------------------------------------------
  //  RefHash2KeysTableOfEnumerator: Private helper methods
  // ---------------------------------------------------------------------------
  template <class TVal> void RefHash2KeysTableOfEnumerator<TVal>::findNext()
  {
      //
      //  If there is a current element, move to its next element. If this
      //  hits the end of the bucket, the next block will handle the rest.
      //
      if (fCurElem)
          fCurElem = fCurElem->fNext;
  
      //
      //  If the current element is null, then we have to move up to the
      //  next hash value. If that is the hash modulus, then we cannot
      //  go further.
      //
      if (!fCurElem)
      {
          fCurHash++;
          if (fCurHash == fToEnum->fHashModulus)
              return;
  
          // Else find the next non-empty bucket
          while (true)
          {
              if (fToEnum->fBucketList[fCurHash])
                  break;
  
              // Bump to the next hash value. If we max out return
              fCurHash++;
              if (fCurHash == fToEnum->fHashModulus)
                  return;
          }
          fCurElem = fToEnum->fBucketList[fCurHash];
      }
  }
  
  
  
  1.1                  xml-xerces/c/src/util/RefHash2KeysTableOf.hpp
  
  Index: RefHash2KeysTableOf.hpp
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xerces" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache\@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation, and was
   * originally based on software copyright (c) 1999, International
   * Business Machines, Inc., http://www.ibm.com .  For more information
   * on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  /*
   * $Log: RefHash2KeysTableOf.hpp,v $
   * Revision 1.1  2001/02/27 18:24:01  tng
   * Schema: Add utility RefHash2KeysTableOf.
   *
   */
  
  
  #if !defined(REFHASH2KEYSTABLEOF_HPP)
  #define REFHASH2KEYSTABLEOF_HPP
  
  
  #include <util/XercesDefs.hpp>
  #include <util/KeyValuePair.hpp>
  #include <util/HashBase.hpp>
  #include <util/IllegalArgumentException.hpp>
  #include <util/NoSuchElementException.hpp>
  #include <util/RuntimeException.hpp>
  #include <util/XMLExceptMsgs.hpp>
  #include <util/XMLEnumerator.hpp>
  #include <util/XMLString.hpp>
  #include <util/HashBase.hpp>
  #include <util/HashXMLCh.hpp>
  
  // This hash table is similar to RefHashTableOf with an additional integer as key2
  
  //
  //  Forward declare the enumerator so he can be our friend. Can you say
  //  friend? Sure...
  //
  template <class TVal> class RefHash2KeysTableOfEnumerator;
  template <class TVal> struct RefHash2KeysTableBucketElem;
  
  
  //
  //  This should really be a nested class, but some of the compilers we
  //  have to support cannot deal with that!
  //
  template <class TVal> struct RefHash2KeysTableBucketElem
  {
      RefHash2KeysTableBucketElem(void* key1, int key2, TVal* const value, RefHash2KeysTableBucketElem<TVal>* next)
  		: fData(value), fNext(next), fKey1(key1), fKey2(key2)
          {
          }
  
      TVal*                           fData;
      RefHash2KeysTableBucketElem<TVal>*   fNext;
  	void*							fKey1;
  	int							fKey2;
  };
  
  
  template <class TVal> class RefHash2KeysTableOf
  {
  public:
      // -----------------------------------------------------------------------
      //  Constructors and Destructor
      // -----------------------------------------------------------------------
  	// backwards compatability - default hasher is HashXMLCh
      RefHash2KeysTableOf(const unsigned int modulus);
  	// backwards compatability - default hasher is HashXMLCh
      RefHash2KeysTableOf(const unsigned int modulus, const bool adoptElems);
  	// if a hash function is passed in, it will be deleted when the hashtable is deleted.
  	// use a new instance of the hasher class for each hashtable, otherwise one hashtable
  	// may delete the hasher of a different hashtable if both use the same hasher.
      RefHash2KeysTableOf(const unsigned int modulus, const bool adoptElems, HashBase* hash);
      ~RefHash2KeysTableOf();
  
  
      // -----------------------------------------------------------------------
      //  Element management
      // -----------------------------------------------------------------------
      bool isEmpty() const;
      bool containsKey(const void* const key1, const int key2) const;
      void removeKey(const void* const key1, const int key2);
      void removeAll();
  
  
      // -----------------------------------------------------------------------
      //  Getters
      // -----------------------------------------------------------------------
      TVal* get(const void* const key1, const int key2);
      const TVal* get(const void* const key1, const int key2) const;
  
  
      // -----------------------------------------------------------------------
      //  Putters
      // -----------------------------------------------------------------------
  	void put(void* key1, int key2, TVal* const valueToAdopt);
  
  
  private :
      // -----------------------------------------------------------------------
      //  Declare our friends
      // -----------------------------------------------------------------------
      friend class RefHash2KeysTableOfEnumerator<TVal>;
  
  private:
  
      // -----------------------------------------------------------------------
      //  Private methods
      // -----------------------------------------------------------------------
      RefHash2KeysTableBucketElem<TVal>* findBucketElem(const void* const key1, const int key2, unsigned int& hashVal);
      const RefHash2KeysTableBucketElem<TVal>* findBucketElem(const void* const key1, const int key2, unsigned int& hashVal) const;
      void removeBucketElem(const void* const key1, const int key2, unsigned int& hashVal);
  	void initialize(const unsigned int modulus);
  
  
      // -----------------------------------------------------------------------
      //  Data members
      //
      //  fAdoptedElems
      //      Indicates whether the values added are adopted or just referenced.
      //      If adopted, then they are deleted when they are removed from the
      //      hash table.
      //
      //  fBucketList
      //      This is the array that contains the heads of all of the list
      //      buckets, one for each possible hash value.
      //
      //  fHashModulus
      //      The modulus used for this hash table, to hash the keys. This is
      //      also the number of elements in the bucket list.
  	//
  	//  fHash
  	//      The hasher for the key1 data type.
      // -----------------------------------------------------------------------
      bool                                fAdoptedElems;
      RefHash2KeysTableBucketElem<TVal>**      fBucketList;
      unsigned int                        fHashModulus;
  	HashBase*							fHash;
  };
  
  
  
  //
  //  An enumerator for a value array. It derives from the basic enumerator
  //  class, so that value vectors can be generically enumerated.
  //
  template <class TVal> class RefHash2KeysTableOfEnumerator : public XMLEnumerator<TVal>
  {
  public :
      // -----------------------------------------------------------------------
      //  Constructors and Destructor
      // -----------------------------------------------------------------------
      RefHash2KeysTableOfEnumerator(RefHash2KeysTableOf<TVal>* const toEnum, const bool adopt = false);
      ~RefHash2KeysTableOfEnumerator();
  
  
      // -----------------------------------------------------------------------
      //  Enum interface
      // -----------------------------------------------------------------------
      bool hasMoreElements() const;
      TVal& nextElement();
      void Reset();
  
  
  private :
      // -----------------------------------------------------------------------
      //  Private methods
      // -----------------------------------------------------------------------
      void findNext();
  
  
      // -----------------------------------------------------------------------
      //  Data Members
      //
      //  fAdopted
      //      Indicates whether we have adopted the passed vector. If so then
      //      we delete the vector when we are destroyed.
      //
      //  fCurElem
      //      This is the current bucket bucket element that we are on.
      //
      //  fCurHash
      //      The is the current hash buck that we are working on. Once we hit
      //      the end of the bucket that fCurElem is in, then we have to start
      //      working this one up to the next non-empty bucket.
      //
      //  fToEnum
      //      The value array being enumerated.
      // -----------------------------------------------------------------------
      bool                                  fAdopted;
      RefHash2KeysTableBucketElem<TVal>*         fCurElem;
      unsigned int                          fCurHash;
      RefHash2KeysTableOf<TVal>*                 fToEnum;
  };
  
  #if !defined(XERCES_TMPLSINC)
  #include <util/RefHash2KeysTableOf.c>
  #endif
  
  #endif