diff --git a/src/xercesc/util/RefHashTableOf.c b/src/xercesc/util/RefHashTableOf.c index e72d2a318fb485fe3aa1d81df892da90c371fef7..7215f34ebe098c6a2489b3cd2514316b66e6df67 100644 --- a/src/xercesc/util/RefHashTableOf.c +++ b/src/xercesc/util/RefHashTableOf.c @@ -56,6 +56,9 @@ /** * $Log$ + * Revision 1.3 2002/07/04 15:24:57 tng + * DOM L3: add transferElement and removeBucketElemSafe for use in DOMDocument::renameNode. + * * Revision 1.2 2002/06/12 17:14:03 tng * Add function cleanup, reinitialize and nextElementKey for ease of use. * @@ -253,6 +256,26 @@ template <class TElem> void RefHashTableOf<TElem>::reinitialize(HashBase* hashBa } + +// this function transfer the data from key1 to key2 +// this is equivalent to calling +// 1. get(key1) to retrieve the data, +// 2. removeKey(key1), +// 3. and then put(key2, data) +// except that the data is not deleted in "removeKey" even it is adopted so that it +// can be transferred to key2. +// whatever key2 has originally will be purged (if adopted) +template <class TElem> void RefHashTableOf<TElem>::transferElement(const void* const key1, void* key2) +{ + TVal* data = get(key1); + + unsigned int hashVal; + removeBucketElemSafe(key1, hashVal); + + put(key2, data); +} + + // --------------------------------------------------------------------------- // RefHashTableOf: Getters // --------------------------------------------------------------------------- @@ -399,6 +422,58 @@ removeBucketElem(const void* const key, unsigned int& hashVal) } +// This is same as removeBucketElem except that it does not delete the data +// even it is adopted +// This function is called by transferElement so that the undeleted data can be transferred +// the key2 will own this data. +template <class TVal> void RefHashTableOf<TVal>:: +removeBucketElemSafe(const void* const key, unsigned int& hashVal) +{ + // Hash the key + hashVal = fHash->getHashVal(key, 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. + // + RefHashTableBucketElem<TVal>* curElem = fBucketList[hashVal]; + RefHashTableBucketElem<TVal>* lastElem = 0; + + while (curElem) + { + if (fHash->equals(key, curElem->fKey)) + { + if (!lastElem) + { + // It was the first in the bucket + fBucketList[hashVal] = curElem->fNext; + } + else + { + // Patch around the current element + lastElem->fNext = curElem->fNext; + } + + // even if we adopted the elements, do not 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); +} // --------------------------------------------------------------------------- diff --git a/src/xercesc/util/RefHashTableOf.hpp b/src/xercesc/util/RefHashTableOf.hpp index 73be74671a43a9cf9277e6f449fcf93d21ad50d6..34c7653c3b0c446a9248f3980d36326348dfeb8a 100644 --- a/src/xercesc/util/RefHashTableOf.hpp +++ b/src/xercesc/util/RefHashTableOf.hpp @@ -56,6 +56,9 @@ /* * $Log$ + * Revision 1.3 2002/07/04 15:24:57 tng + * DOM L3: add transferElement and removeBucketElemSafe for use in DOMDocument::renameNode. + * * Revision 1.2 2002/06/12 17:14:03 tng * Add function cleanup, reinitialize and nextElementKey for ease of use. * @@ -140,7 +143,7 @@ template <class TVal> struct RefHashTableBucketElem TVal* fData; RefHashTableBucketElem<TVal>* fNext; - void* fKey; + void* fKey; }; @@ -150,13 +153,13 @@ public: // ----------------------------------------------------------------------- // Constructors and Destructor // ----------------------------------------------------------------------- - // backwards compatability - default hasher is HashXMLCh + // backwards compatability - default hasher is HashXMLCh RefHashTableOf(const unsigned int modulus); - // backwards compatability - default hasher is HashXMLCh + // backwards compatability - default hasher is HashXMLCh RefHashTableOf(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. + // 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. RefHashTableOf(const unsigned int modulus, const bool adoptElems, HashBase* hashBase); ~RefHashTableOf(); @@ -170,6 +173,7 @@ public: void removeAll(); void cleanup(); void reinitialize(HashBase* hashBase); + void transferElement(const void* const key1, void* key2); // ----------------------------------------------------------------------- // Getters @@ -181,7 +185,7 @@ public: // ----------------------------------------------------------------------- // Putters // ----------------------------------------------------------------------- - void put(void* key, TVal* const valueToAdopt); + void put(void* key, TVal* const valueToAdopt); private : @@ -198,7 +202,8 @@ private: RefHashTableBucketElem<TVal>* findBucketElem(const void* const key, unsigned int& hashVal); const RefHashTableBucketElem<TVal>* findBucketElem(const void* const key, unsigned int& hashVal) const; void removeBucketElem(const void* const key, unsigned int& hashVal); - void initialize(const unsigned int modulus); + void removeBucketElemSafe(const void* const key, unsigned int& hashVal); + void initialize(const unsigned int modulus); // ----------------------------------------------------------------------- @@ -216,14 +221,14 @@ private: // 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 key data type. + // + // fHash + // The hasher for the key data type. // ----------------------------------------------------------------------- bool fAdoptedElems; RefHashTableBucketElem<TVal>** fBucketList; unsigned int fHashModulus; - HashBase* fHash; + HashBase* fHash; };