diff --git a/src/xercesc/util/RefHash2KeysTableOf.c b/src/xercesc/util/RefHash2KeysTableOf.c index 700dcf22aa44467f8f6f8022e57b0c145f980e41..83c6a01200d43251aaae8f8b473a7714ac772a9d 100644 --- a/src/xercesc/util/RefHash2KeysTableOf.c +++ b/src/xercesc/util/RefHash2KeysTableOf.c @@ -56,6 +56,10 @@ /** * $Log$ + * Revision 1.8 2004/08/30 15:18:35 amassari + * - Added transferElement API + * - The iterator class now can iterate over the items having the same primary key + * * Revision 1.7 2004/03/01 15:03:08 peiyongz * new getter: getHashModulus * @@ -240,6 +244,57 @@ template <class TVal> void RefHash2KeysTableOf<TVal>::removeAll() } } +// this function transfer the data from key1 to key2 +template <class TVal> void RefHash2KeysTableOf<TVal>::transferElement(const void* const key1, void* key2) +{ + // Hash the key + unsigned int hashVal = fHash->getHashVal(key1, fHashModulus); + if (hashVal > fHashModulus) + ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::HshTbl_BadHashFromKey, fMemoryManager); + + // + // 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 this element has the same primary key, remove it and add it using the new primary key + if (fHash->equals(key1, curElem->fKey1)) + { + if (!lastElem) + { + // It was the first in the bucket + fBucketList[hashVal] = curElem->fNext; + } + else + { + // Patch around the current element + lastElem->fNext = curElem->fNext; + } + + put(key2, curElem->fKey2, curElem->fData); + + RefHash2KeysTableBucketElem<TVal>* elemToDelete = curElem; + + // Update just curElem; lastElem must stay the same + curElem = curElem->fNext; + + // Delete the current element + delete elemToDelete; + } + else + { + // Move both pointers upwards + lastElem = curElem; + curElem = curElem->fNext; + } + } +} + + // --------------------------------------------------------------------------- // RefHash2KeysTableOf: Getters @@ -408,7 +463,7 @@ template <class TVal> RefHash2KeysTableOfEnumerator<TVal>:: RefHash2KeysTableOfEnumerator(RefHash2KeysTableOf<TVal>* const toEnum , const bool adopt , MemoryManager* const manager) - : fAdopted(adopt), fCurElem(0), fCurHash((unsigned int)-1), fToEnum(toEnum) + : fAdopted(adopt), fCurElem(0), fCurHash((unsigned int)-1), fToEnum(toEnum), fLockPrimaryKey(0) , fMemoryManager(manager) { if (!toEnum) @@ -482,18 +537,40 @@ template <class TVal> void RefHash2KeysTableOfEnumerator<TVal>::nextElementKey(v template <class TVal> void RefHash2KeysTableOfEnumerator<TVal>::Reset() { - fCurHash = (unsigned int)-1; + if(fLockPrimaryKey) + fCurHash=fToEnum->fHash->getHashVal(fLockPrimaryKey, fToEnum->fHashModulus, fMemoryManager); + else + fCurHash = (unsigned int)-1; fCurElem = 0; findNext(); } +template <class TVal> void RefHash2KeysTableOfEnumerator<TVal>::setPrimaryKey(const void* key) +{ + fLockPrimaryKey=key; + Reset(); +} // --------------------------------------------------------------------------- // RefHash2KeysTableOfEnumerator: Private helper methods // --------------------------------------------------------------------------- template <class TVal> void RefHash2KeysTableOfEnumerator<TVal>::findNext() { + // Code to execute if we have to return only values with the primary key + if(fLockPrimaryKey) + { + if(!fCurElem) + fCurElem = fToEnum->fBucketList[fCurHash]; + else + fCurElem = fCurElem->fNext; + while (fCurElem && !fToEnum->fHash->equals(fLockPrimaryKey, fCurElem->fKey1) ) + fCurElem = fCurElem->fNext; + // if we didn't found it, make so hasMoreElements() returns false + if(!fCurElem) + fCurHash = fToEnum->fHashModulus; + return; + } // // 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. diff --git a/src/xercesc/util/RefHash2KeysTableOf.hpp b/src/xercesc/util/RefHash2KeysTableOf.hpp index 147c1f9ddf192cb3c903206a5b5f205bb6265b61..ae53c67e6754d417611b809fe9bcb828bb408a5b 100644 --- a/src/xercesc/util/RefHash2KeysTableOf.hpp +++ b/src/xercesc/util/RefHash2KeysTableOf.hpp @@ -56,6 +56,10 @@ /* * $Log$ + * Revision 1.11 2004/08/30 15:18:35 amassari + * - Added transferElement API + * - The iterator class now can iterate over the items having the same primary key + * * Revision 1.10 2004/03/01 15:03:08 peiyongz * new getter: getHashModulus * @@ -195,7 +199,7 @@ public: bool containsKey(const void* const key1, const int key2) const; void removeKey(const void* const key1, const int key2); void removeAll(); - + void transferElement(const void* const key1, void* key2); // ----------------------------------------------------------------------- // Getters @@ -211,7 +215,6 @@ public: // ----------------------------------------------------------------------- void put(void* key1, int key2, TVal* const valueToAdopt); - private : // ----------------------------------------------------------------------- // Declare our friends @@ -290,6 +293,7 @@ public : // New interface // ----------------------------------------------------------------------- void nextElementKey(void*&, int&); + void setPrimaryKey(const void* key); private : // ----------------------------------------------------------------------- @@ -321,12 +325,18 @@ private : // // fToEnum // The value array being enumerated. + // + // fLockPrimaryKey + // Indicates that we are requested to iterate over the secondary keys + // associated with the given primary key + // // ----------------------------------------------------------------------- bool fAdopted; RefHash2KeysTableBucketElem<TVal>* fCurElem; unsigned int fCurHash; RefHash2KeysTableOf<TVal>* fToEnum; MemoryManager* const fMemoryManager; + const void* fLockPrimaryKey; }; XERCES_CPP_NAMESPACE_END