2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
19 * @file FBaseColMultiHashMap.cpp
20 * @brief This is the implementation for MultiHashMap class.
24 #include <unique_ptr.h>
25 #include <FBaseColMultiHashMap.h>
26 #include <FBaseColArrayList.h>
27 #include <FBaseColMapEntry.h>
28 #include <FBaseResult.h>
29 #include <FBaseFloat.h>
30 #include <FBaseSysLog.h>
33 namespace Tizen { namespace Base { namespace Collection
38 * @brief This is a node for MultiHashMap.
44 __Node(Object* pKey, Object* pValue);
45 virtual ~__Node(void);
47 virtual Object* GetKey(void) const;
48 virtual Object* GetValue(void) const;
51 __Node(const __Node& node);
52 __Node& operator =(const __Node& rhs);
56 friend class MultiHashMap;
57 friend class _MultiHashMapEnumerator;
58 friend class _EntryValueEnumerator;
61 __Node::__Node(Object* pKey, Object* pValue)
62 : MapEntry(*pKey, *pValue)
72 __Node::GetKey(void) const
78 __Node::GetValue(void) const
84 * @class _MultiHashMapEntry
85 * @brief This is an entry for MultiHashMap class.
87 class _MultiHashMapEntry
90 _MultiHashMapEntry(Object* key, __Node* list, _MultiHashMapEntry* next, int h);
91 virtual ~_MultiHashMapEntry(void);
95 _MultiHashMapEntry* pNext;
100 _MultiHashMapEntry(const _MultiHashMapEntry& entry);
101 _MultiHashMapEntry& operator =(const _MultiHashMapEntry& rhs);
103 friend class MultiHashMap;
104 friend class _MultiHashMapEnumerator;
105 friend class _EntryValueEnumerator;
109 _MultiHashMapEntry::_MultiHashMapEntry(Object* key, __Node* list, _MultiHashMapEntry* next, int h)
118 _MultiHashMapEntry::~_MultiHashMapEntry(void)
123 * @class _MultiHashMapDefaultComparer
124 * @brief This is an implementation of IComparer for MultiHashMap.
126 class _MultiHashMapDefaultComparer
131 _MultiHashMapDefaultComparer(void);
132 virtual ~_MultiHashMapDefaultComparer(void);
134 virtual result Compare(const Object& obj1, const Object& obj2, int& cmp) const;
138 _MultiHashMapDefaultComparer::_MultiHashMapDefaultComparer(void)
142 _MultiHashMapDefaultComparer::~_MultiHashMapDefaultComparer(void)
147 _MultiHashMapDefaultComparer::Compare(const Object& obj1, const Object& obj2, int& cmp) const
149 if (obj1.Equals(obj2))
162 * @class _MultiHashMapDefaultProvider
163 * @brief This is an implementation of IHashCodeProvider for MultiHashMap.
165 class _MultiHashMapDefaultProvider
166 : public IHashCodeProvider
170 _MultiHashMapDefaultProvider(void) {}
171 virtual ~_MultiHashMapDefaultProvider(void) {}
173 using Object::GetHashCode;
174 virtual int GetHashCode(const Object& obj) const
176 return obj.GetHashCode();
182 * @class _MultiHashMapEnumerator
183 * @brief This is an implementation of IMapEnumerator for MultiHashMap.
185 class _MultiHashMapEnumerator
186 : public IMapEnumerator
190 _MultiHashMapEnumerator(const MultiHashMap& map, int modCount);
191 virtual ~_MultiHashMapEnumerator(void);
193 virtual Object* GetCurrent(void) const;
194 virtual result MoveNext(void);
195 virtual result Reset(void);
196 virtual Object* GetKey(void) const;
197 virtual Object* GetValue(void) const;
200 const MultiHashMap& __map;
202 _MultiHashMapEntry* __pEntry;
208 _MultiHashMapEnumerator::_MultiHashMapEnumerator(const MultiHashMap& map, int modCount)
210 , __modCount(modCount)
217 _MultiHashMapEnumerator::~_MultiHashMapEnumerator(void)
222 _MultiHashMapEnumerator::GetCurrent(void) const
224 SysTryReturn(NID_BASE_COL, (__modCount == __map.__modCount), null, E_INVALID_OPERATION, "[%s] The source collection was modified after the creation of this enumerator.", GetErrorMessage(E_INVALID_OPERATION));
225 SysTryReturn(NID_BASE_COL, (__pEntry != null && __pNode != null), null, E_INVALID_OPERATION, "[%s] Invalid position(pEntry or pNode is null).", GetErrorMessage(E_INVALID_OPERATION));
227 SetLastResult(E_SUCCESS);
232 _MultiHashMapEnumerator::MoveNext(void)
234 SysTryReturnResult(NID_BASE_COL, (__modCount == __map.__modCount), E_INVALID_OPERATION, "The source collection was modified after the creation of this enumerator.");
236 if ((null != __pNode) && (__pNode->pNext != null))
238 __pNode = __pNode->pNext;
241 else if ((null != __pEntry) && (__pEntry->pNext != null))
243 __pEntry = __pEntry->pNext;
244 __pNode = __pEntry->pList;
249 while (++__index < __map.__capacity)
251 __pEntry = __map.__pTable[__index];
252 if (null != __pEntry)
254 __pNode = __pEntry->pList;
260 return E_OUT_OF_RANGE;
264 _MultiHashMapEnumerator::Reset(void)
266 SysTryReturnResult(NID_BASE_COL, (__modCount == __map.__modCount), E_INVALID_OPERATION, "The source collection was modified after the creation of this enumerator.");
276 _MultiHashMapEnumerator::GetKey(void) const
278 SysTryReturn(NID_BASE_COL, (__modCount == __map.__modCount), null, E_INVALID_OPERATION, "[%s] The source collection was modified after the creation of this enumerator.", GetErrorMessage(E_INVALID_OPERATION));
279 SysTryReturn(NID_BASE_COL, (__pEntry != null && __pNode != null), null, E_INVALID_OPERATION, "[%s] Invalid position(pEntry or pNode is null).", GetErrorMessage(E_INVALID_OPERATION));
281 SetLastResult(E_SUCCESS);
282 return __pEntry->pKey;
286 _MultiHashMapEnumerator::GetValue(void) const
288 SysTryReturn(NID_BASE_COL, (__modCount == __map.__modCount), null, E_INVALID_OPERATION, "[%s] The source collection was modified after the creation of this enumerator.", GetErrorMessage(E_INVALID_OPERATION));
289 SysTryReturn(NID_BASE_COL, (__pEntry != null && __pNode != null), null, E_INVALID_OPERATION, "[%s] Invalid position(pEntry or pNode is null).", GetErrorMessage(E_INVALID_OPERATION));
291 SetLastResult(E_SUCCESS);
292 return __pNode->GetValue();
296 * @class _EntryValueEnumerator
297 * @brief This is an implementation of IEnumerator to enumerate values whose key is the same.
299 class _EntryValueEnumerator
304 _EntryValueEnumerator(const _MultiHashMapEntry& entry, int modCount);
305 virtual ~_EntryValueEnumerator(void);
307 virtual Object* GetCurrent(void) const;
308 virtual result MoveNext(void);
309 virtual result Reset(void);
312 const _MultiHashMapEntry& __entry;
318 _EntryValueEnumerator::_EntryValueEnumerator(const _MultiHashMapEntry& entry, int modCount)
320 , __modCount(modCount)
325 _EntryValueEnumerator::~_EntryValueEnumerator(void)
330 _EntryValueEnumerator::GetCurrent(void) const
332 SysTryReturn(NID_BASE_COL, __modCount == __entry.modCount, null, E_INVALID_OPERATION, "[%s] The source collection was modified after the creation of this enumerator.", GetErrorMessage(E_INVALID_OPERATION));
333 SysTryReturn(NID_BASE_COL, __pNode != null, null, E_INVALID_OPERATION, "[%s] Invalid position(pNode is null).", GetErrorMessage(E_INVALID_OPERATION));
335 SetLastResult(E_SUCCESS);
336 return __pNode->GetValue();
340 _EntryValueEnumerator::MoveNext(void)
342 SysTryReturn(NID_BASE_COL, (__modCount == __entry.modCount), E_INVALID_OPERATION, E_INVALID_OPERATION, "[%s] The source collection was modified after the creation of this enumerator.", GetErrorMessage(E_INVALID_OPERATION));
346 __pNode = __entry.pList;
347 SysAssert(null != __pNode);
349 else if (__pNode->pNext != null)
351 __pNode = __pNode->pNext;
355 // Do not log the E_OUT_OF_RANGE, because it's normal or trivial in most cases.
356 return E_OUT_OF_RANGE;
363 _EntryValueEnumerator::Reset(void)
365 SysTryReturn(NID_BASE_COL, (__modCount == __entry.modCount), E_INVALID_OPERATION, E_INVALID_OPERATION, "[%s] The source collection was modified after the creation of this enumerator.", GetErrorMessage(E_INVALID_OPERATION));
371 const float MultiHashMap::DEFAULT_LOAD_FACTOR = 0.75;
373 MultiHashMap::MultiHashMap(DeleterFunctionType deleter)
381 , __needToRemoveProviderComparer(false)
384 , __pMultiHashMapImpl(null)
388 MultiHashMap::~MultiHashMap(void)
391 if (__pTable != null)
397 if (__needToRemoveProviderComparer)
405 MultiHashMap::Construct(int capacity, float loadFactor)
407 SysTryReturnResult(NID_BASE_COL, capacity >= 0, E_INVALID_ARG, "The capacity(%d) MUST be greater than or equal to 0.", capacity);
408 SysTryReturnResult(NID_BASE_COL, loadFactor >= 0, E_INVALID_ARG, "The loadFactor(%f) MUST be greater than or equal to 0.0.", loadFactor);
410 std::unique_ptr< IHashCodeProvider > pProvider(new (std::nothrow) _MultiHashMapDefaultProvider());
411 SysTryReturnResult(NID_BASE_COL, pProvider != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
413 std::unique_ptr< IComparer > pComparer(new (std::nothrow) _MultiHashMapDefaultComparer());
414 SysTryReturnResult(NID_BASE_COL, pComparer != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
416 __needToRemoveProviderComparer = true;
418 result r = Construct(capacity, loadFactor, *(pProvider.release()), *(pComparer.release()));
419 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, r, "Propagating.");
425 MultiHashMap::Construct(const IMultiMap& map, float loadFactor)
427 SysTryReturnResult(NID_BASE_COL, loadFactor >= 0, E_INVALID_ARG, "The loadFactor(%f) MUST be greater than or equal to 0.0.", loadFactor);
429 std::unique_ptr< IHashCodeProvider > pProvider(new (std::nothrow) _MultiHashMapDefaultProvider());
430 SysTryReturnResult(NID_BASE_COL, pProvider != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
432 std::unique_ptr< IComparer > pComparer(new (std::nothrow) _MultiHashMapDefaultComparer());
433 SysTryReturnResult(NID_BASE_COL, pComparer != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
435 __needToRemoveProviderComparer = true;
437 result r = Construct(map, loadFactor, *(pProvider.release()), *(pComparer.release()));
438 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, r, "Propagating.");
444 MultiHashMap::Construct(int capacity, float loadFactor, const IHashCodeProvider& provider, const IComparer& comparer)
446 SysTryReturnResult(NID_BASE_COL, capacity >= 0, E_INVALID_ARG, "The capacity(%d) MUST be greater than or equal to 0.", capacity);
447 SysTryReturnResult(NID_BASE_COL, loadFactor >= 0, E_INVALID_ARG, "The loadFactor(%f) MUST be greater than or equal to 0.0.", loadFactor);
452 newCapacity = DEFAULT_CAPACITY;
457 while (newCapacity < capacity)
463 float newLoadFactor = 0;
464 if (Float::Compare(loadFactor, 0) == 0)
466 newLoadFactor = DEFAULT_LOAD_FACTOR;
470 newLoadFactor = loadFactor;
473 int newThreshold = static_cast< int >(newCapacity * newLoadFactor);
474 std::unique_ptr< IHashCodeProvider > pProvider(const_cast< IHashCodeProvider* >(&provider));
475 std::unique_ptr< IComparer > pComparer(const_cast< IComparer* >(&comparer));
476 std::unique_ptr< _MultiHashMapEntry*[] > pTable(new (std::nothrow) _MultiHashMapEntry*[newCapacity]);
477 SysTryReturnResult(NID_BASE_COL, pTable != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
479 memset(pTable.get(), null, sizeof(*(pTable.get())) * newCapacity);
481 __capacity = newCapacity;
482 __loadFactor = newLoadFactor;
483 __threshold = newThreshold;
484 __pProvider = pProvider.release();
485 __pComparer = pComparer.release();
486 __pTable = pTable.release();
492 MultiHashMap::Construct(const IMultiMap& map, float loadFactor, const IHashCodeProvider& provider, const IComparer& comparer)
494 SysTryReturnResult(NID_BASE_COL, (loadFactor >= 0), E_INVALID_ARG, "The loadFactor(%f) MUST be greater than or equal to 0.0.", loadFactor);
496 result r = E_SUCCESS;
497 if (Float::Compare(loadFactor, 0) == 0)
499 loadFactor = DEFAULT_LOAD_FACTOR;
502 int capacity = static_cast< int >(map.GetCount() / loadFactor) + 1;
504 r = Construct(capacity, loadFactor, provider, comparer);
505 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, r, "Propagating.");
508 SysTryCatch(NID_BASE_COL, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
512 DeleterFunctionType deleter = GetDeleter();
513 SetDeleter(SingleObjectDeleter);
520 if (__needToRemoveProviderComparer)
534 MultiHashMap::Add(Object* pKey, Object* pValue)
536 SysTryReturnResult(NID_BASE_COL, pKey != null , E_INVALID_ARG, "Invalid argument used. The pKey is null");
537 SysTryReturnResult(NID_BASE_COL, pValue != null, E_INVALID_ARG, "Invalid argument used. The pValue is null");
539 __Node* pNewNode = null;
541 result r = E_SUCCESS;
542 int hash = Hash(*pKey);
543 int i = hash & (__capacity - 1);
544 __Node* pNode = null;
545 _MultiHashMapEntry* pEntry = null;
547 if (__pTable != null)
549 pEntry = __pTable[i];
551 while (pEntry != null)
553 if (hash == pEntry->hash)
556 r = __pComparer->Compare(*pKey, *(pEntry->pKey), cmpResult);
557 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, E_INVALID_ARG, "Translating [%s] into [%s]", GetErrorMessage(r), GetErrorMessage(E_INVALID_ARG));
561 pNode = pEntry->pList;
564 SysTryReturnResult(NID_BASE_COL, !(pNode->_pValue->Equals(*pValue)), E_OBJ_ALREADY_EXIST, "The value is already exist for the key.");
566 if (pNode->pNext != null)
568 pNode = pNode->pNext;
579 pEntry = pEntry->pNext;
582 pNewNode = new (std::nothrow) __Node(pKey, pValue);
583 SysTryReturnResult(NID_BASE_COL, pNewNode != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
585 // pKey is not exist in this map.
588 _MultiHashMapEntry* pNewEntry = new (std::nothrow) _MultiHashMapEntry(pKey, pNewNode, __pTable[i], hash);
589 SysTryReturnResult(NID_BASE_COL, pNewEntry != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
590 __pTable[i] = pNewEntry;
592 // pKey is already exist in this map, but value is not.
595 // pNode is the last value associated to the pKey
596 pNode->pNext = pNewNode;
601 if (__count++ >= __threshold)
603 r = Resize(__capacity * 2);
604 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, r, "Propagating.");
611 MultiHashMap::GetEnumeratorN(void) const
613 std::unique_ptr< _MultiHashMapEnumerator > pEnum(new (std::nothrow) _MultiHashMapEnumerator(*this, __modCount));
614 SysTryReturn(NID_BASE_COL, pEnum != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
616 SetLastResult(E_SUCCESS);
617 return pEnum.release();
621 MultiHashMap::GetMapEnumeratorN(void) const
623 return dynamic_cast< IMapEnumerator* >(GetEnumeratorN());
627 MultiHashMap::GetValuesN(const Object& key) const
629 int hash = Hash(key);
630 int i = hash & (__capacity - 1);
632 for (_MultiHashMapEntry* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
634 if (hash == pEntry->hash)
637 result r = __pComparer->Compare(key, *(pEntry->pKey), cmpResult);
638 SysTryReturn(NID_BASE_COL, r == E_SUCCESS, null, E_INVALID_ARG, "[%s] Propagating.", GetErrorMessage(r));
642 std::unique_ptr< IEnumerator > pEnum(new (std::nothrow) _EntryValueEnumerator(*pEntry, pEntry->modCount));
643 SysTryReturn(NID_BASE_COL, pEnum != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
645 SetLastResult(E_SUCCESS);
646 return pEnum.release();
651 SetLastResult(E_OBJ_NOT_FOUND);
656 MultiHashMap::GetKeysN(void) const
658 result r = E_SUCCESS;
661 std::unique_ptr< ArrayList > pList(new (std::nothrow) ArrayList());
662 SysTryReturn(NID_BASE_COL, pList != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
664 r = pList->Construct(__count);
665 SysTryReturn(NID_BASE_COL, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
667 for (int i = 0; i < __capacity; i++)
669 for (_MultiHashMapEntry* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
671 r = pList->Add(pEntry->pKey);
672 SysTryReturn(NID_BASE_COL, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
677 SetLastResult(E_SUCCESS);
678 return pList.release();
682 MultiHashMap::GetValuesN(void) const
684 result r = E_SUCCESS;
686 std::unique_ptr< ArrayList > pList(new (std::nothrow) ArrayList());
687 SysTryReturn(NID_BASE_COL, pList != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
689 r = pList->Construct(__count);
690 SysTryReturn(NID_BASE_COL, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
692 for (int i = 0; i < __capacity; i++)
694 for (_MultiHashMapEntry* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
696 for (__Node* pNode = pEntry->pList; null != pNode; pNode = pNode->pNext)
698 r = pList->Add(pNode->_pValue);
699 SysTryReturn(NID_BASE_COL, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
704 SetLastResult(E_SUCCESS);
705 return pList.release();
709 MultiHashMap::Remove(const Object& key)
711 int hash = Hash(key);
712 int i = hash & (__capacity - 1);
714 _MultiHashMapEntry* pPrev = __pTable[i];
715 for (_MultiHashMapEntry* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
717 if (hash == pEntry->hash)
720 result r = __pComparer->Compare(key, *(pEntry->pKey), cmpResult);
721 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, E_INVALID_ARG, "The input argument is invalid");
728 __pTable[i] = pEntry->pNext;
732 pPrev->pNext = pEntry->pNext;
735 __Node* pNode = pEntry->pList;
736 while (pNode != null)
738 __Node* pTemp = pNode;
739 pNode = pNode->pNext;
741 __deleter(pTemp->_pValue);
747 __deleter(pEntry->pKey);
757 return E_OBJ_NOT_FOUND;
761 MultiHashMap::Remove(const Object& key, const Object& value)
763 int hash = Hash(key);
764 int i = hash & (__capacity - 1);
766 _MultiHashMapEntry* pPrev = __pTable[i];
767 for (_MultiHashMapEntry* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
769 if (hash == pEntry->hash)
772 result r = __pComparer->Compare(key, *(pEntry->pKey), cmpResult);
773 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, E_INVALID_ARG, "The input argument is invalid");
777 __Node* pPrevNode = pEntry->pList;
778 for (__Node* pNode = pEntry->pList; null != pNode; pNode = pNode->pNext)
780 if (value.Equals(*(pNode->_pValue)))
784 if (pPrevNode == pNode)
786 pEntry->pList = pNode->pNext;
790 pPrevNode->pNext = pNode->pNext;
793 __deleter(pNode->_pValue);
794 pNode->_pValue = null;
801 if (pEntry->pList == null)
805 __pTable[i] = pEntry->pNext;
809 pPrev->pNext = pEntry->pNext;
812 __deleter(pEntry->pKey);
831 return E_OBJ_NOT_FOUND;
835 MultiHashMap::RemoveAll(void)
846 MultiHashMap::SetValue(const Object& key, const Object& value, Object* pNewValue)
848 SysTryReturnResult(NID_BASE_COL, pNewValue != null , E_INVALID_ARG, "Invalid argument used. The pNewValue is null");
850 result r = E_SUCCESS;
851 int hash = Hash(key);
852 int i = hash & (__capacity - 1);
853 __Node* pNode = null;
854 _MultiHashMapEntry* pEntry = __pTable[i];
855 bool pairExist = false;
856 while (null != pEntry)
858 if (hash == pEntry->hash)
861 r = __pComparer->Compare(key, *(pEntry->pKey), cmpResult);
862 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, E_INVALID_ARG, "The input argument is invalid");
866 pNode = pEntry->pList;
869 if (pNode->_pValue->Equals(value))
872 __deleter(pNode->_pValue);
873 pNode->_pValue = pNewValue;
877 if (pNode->pNext != null)
879 pNode = pNode->pNext;
890 pEntry = pEntry->pNext;
903 MultiHashMap::GetCount(void) const
909 MultiHashMap::GetCount(const Object& key, int& count) const
913 result r = E_OBJ_NOT_FOUND;
914 int hash = Hash(key);
915 int i = hash & (__capacity - 1);
917 for (_MultiHashMapEntry* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
919 if (hash == pEntry->hash)
922 r = __pComparer->Compare(key, *(pEntry->pKey), cmpResult);
923 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, E_INVALID_ARG, "The input argument is invalid");
928 for (__Node* pNode = pEntry->pList; null != pNode; pNode = pNode->pNext)
943 MultiHashMap::Contains(const Object& key, const Object& value) const
945 result r = E_SUCCESS;
946 int hash = Hash(key);
947 int i = hash & (__capacity - 1);
949 SetLastResult(E_SUCCESS);
951 for (_MultiHashMapEntry* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
953 if (hash == pEntry->hash)
956 r = __pComparer->Compare(key, *(pEntry->pKey), cmpResult);
957 SysTryReturn(NID_BASE_COL, r == E_SUCCESS, false, E_INVALID_ARG, "Translating [%s] into [%s]", GetErrorMessage(r), GetErrorMessage(E_INVALID_ARG));
961 for (__Node* pNode = pEntry->pList; null != pNode; pNode = pNode->pNext)
963 if (value.Equals(*(pNode->_pValue)))
976 MultiHashMap::ContainsKey(const Object& key) const
978 result r = E_SUCCESS;
979 int hash = Hash(key);
980 int i = hash & (__capacity - 1);
982 SetLastResult(E_SUCCESS);
984 for (_MultiHashMapEntry* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
986 if (hash == pEntry->hash)
989 r = __pComparer->Compare(key, *(pEntry->pKey), cmpResult);
990 SysTryReturn(NID_BASE_COL, r == E_SUCCESS, false, E_INVALID_ARG, "[%s] Propagating.", GetErrorMessage(r));
1003 MultiHashMap::ContainsValue(const Object& value) const
1005 for (int i = 0; i < __capacity; i++)
1007 for (_MultiHashMapEntry* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
1009 for (__Node* pNode = pEntry->pList; null != pNode; pNode = pNode->pNext)
1011 if (value.Equals(*(pNode->_pValue)))
1022 MultiHashMap::Equals(const Object& obj) const
1024 const MultiHashMap* pOther = dynamic_cast< const MultiHashMap* >(&obj);
1029 else if (pOther == this)
1033 else if (__count != pOther->__count)
1039 bool contain = true;
1040 for (int i = 0; i < __capacity; i++)
1042 for (_MultiHashMapEntry* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
1044 for (__Node* pNode = pEntry->pList; null != pNode; pNode = pNode->pNext)
1046 contain = pOther->Contains(*(pEntry->pKey), *(pNode->_pValue));
1047 result r = GetLastResult();
1048 SysTryReturn(NID_BASE_COL, !IsFailed(r), false, r, "[%s] Propagating", GetErrorMessage(r));
1067 MultiHashMap::GetHashCode(void) const
1070 _MultiHashMapEntry* pEntry = null;
1071 _MultiHashMapEntry* pNext = null;
1072 __Node* pNode = null;
1073 for (int i = 0; i < __capacity; i++)
1075 pEntry = __pTable[i];
1076 while (pEntry != null)
1078 pNext = pEntry->pNext;
1079 pNode = pEntry->pList;
1080 while (pNode != null)
1082 hash += pNode->_pValue->GetHashCode();
1083 pNode = pNode->pNext;
1086 hash += pEntry->pKey->GetHashCode();
1094 MultiHashMap::GetDeleter(void) const
1100 MultiHashMap::AddAll(const IMultiMap& map)
1102 result r = E_SUCCESS;
1103 std::unique_ptr< IMapEnumerator > pMapEnum(map.GetMapEnumeratorN());
1104 SysTryReturnResult(NID_BASE_COL, pMapEnum != null, GetLastResult(), "Propagating.");
1106 while ((r = pMapEnum->MoveNext()) != E_OUT_OF_RANGE)
1108 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, r, "Propagating.");
1110 Object* pKey = pMapEnum->GetKey();
1111 SysTryReturnResult(NID_BASE_COL, pKey != null, GetLastResult(), "Propagating.");
1113 Object* pValue = pMapEnum->GetValue();
1114 SysTryReturnResult(NID_BASE_COL, pValue != null, GetLastResult(), "Propagating.");
1116 r = Add(pKey, pValue);
1117 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, r, "Propagating.");
1124 MultiHashMap::Hash(const Object& obj) const
1126 int h = __pProvider->GetHashCode(obj);
1128 h ^= (h >> 20) ^ (h >> 12);
1130 return h ^ (h >> 7) ^ (h >> 4);
1134 MultiHashMap::Resize(int newCapacity)
1136 _MultiHashMapEntry** pNewTable = new (std::nothrow) _MultiHashMapEntry*[newCapacity];
1137 SysTryReturnResult(NID_BASE_COL, pNewTable != null, E_OUT_OF_MEMORY, "");
1138 memset(pNewTable, null, sizeof(*pNewTable) * newCapacity);
1140 for (int i = 0; i < __capacity; i++)
1142 _MultiHashMapEntry* pNext = null;
1144 for (_MultiHashMapEntry* pEntry = __pTable[i]; null != pEntry; pEntry = pNext)
1146 pNext = pEntry->pNext;
1147 index = pEntry->hash & (newCapacity - 1);
1148 pEntry->pNext = pNewTable[index];
1149 pNewTable[index] = pEntry;
1154 __pTable = pNewTable;
1155 __capacity = newCapacity;
1156 __threshold = static_cast< int >(__capacity * __loadFactor);
1162 MultiHashMap::Reset(void)
1164 for (int i = 0; i < __capacity; i++)
1166 _MultiHashMapEntry* pEntry = __pTable[i];
1167 while (pEntry != null)
1169 _MultiHashMapEntry* pNext = pEntry->pNext;
1170 __Node* pNode = pEntry->pList;
1172 while (pNode != null)
1174 std::unique_ptr< __Node > pTemp(pNode);
1175 pNode = pNode->pNext;
1177 __deleter(pTemp->_pValue);
1180 __deleter(pEntry->pKey);
1189 MultiHashMap::SetDeleter(DeleterFunctionType deleter)
1191 __deleter = deleter;
1193 } } } // Tizen::Base::Collectionn