2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 // Licensed under the Apache License, Version 2.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
8 // http://www.apache.org/licenses/LICENSE-2.0
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
18 * @file FBaseColMultiHashMap.cpp
19 * @brief This is the implementation for MultiHashMap class.
23 #include <unique_ptr.h>
24 #include <FBaseColMultiHashMap.h>
25 #include <FBaseColArrayList.h>
26 #include <FBaseColMapEntry.h>
27 #include <FBaseResult.h>
28 #include <FBaseFloat.h>
29 #include <FBaseSysLog.h>
32 namespace Tizen { namespace Base { namespace Collection
37 * @brief This is a node for MultiHashMap.
43 __Node(Object* pKey, Object* pValue);
44 virtual ~__Node(void);
46 virtual Object* GetKey(void) const;
47 virtual Object* GetValue(void) const;
50 __Node(const __Node& node);
51 __Node& operator =(const __Node& rhs);
55 friend class MultiHashMap;
56 friend class _MultiHashMapEnumerator;
57 friend class _EntryValueEnumerator;
60 __Node::__Node(Object* pKey, Object* pValue)
61 : MapEntry(*pKey, *pValue)
71 __Node::GetKey(void) const
77 __Node::GetValue(void) const
83 * @class _MultiHashMapEntry
84 * @brief This is an entry for MultiHashMap class.
86 class _MultiHashMapEntry
89 _MultiHashMapEntry(Object* key, __Node* list, _MultiHashMapEntry* next, int h);
90 virtual ~_MultiHashMapEntry(void);
94 _MultiHashMapEntry* pNext;
99 _MultiHashMapEntry(const _MultiHashMapEntry& entry);
100 _MultiHashMapEntry& operator =(const _MultiHashMapEntry& rhs);
102 friend class MultiHashMap;
103 friend class _MultiHashMapEnumerator;
104 friend class _EntryValueEnumerator;
108 _MultiHashMapEntry::_MultiHashMapEntry(Object* key, __Node* list, _MultiHashMapEntry* next, int h)
117 _MultiHashMapEntry::~_MultiHashMapEntry(void)
122 * @class _MultiHashMapDefaultComparer
123 * @brief This is an implementation of IComparer for MultiHashMap.
125 class _MultiHashMapDefaultComparer
130 _MultiHashMapDefaultComparer(void);
131 virtual ~_MultiHashMapDefaultComparer(void);
133 virtual result Compare(const Object& obj1, const Object& obj2, int& cmp) const;
137 _MultiHashMapDefaultComparer::_MultiHashMapDefaultComparer(void)
141 _MultiHashMapDefaultComparer::~_MultiHashMapDefaultComparer(void)
146 _MultiHashMapDefaultComparer::Compare(const Object& obj1, const Object& obj2, int& cmp) const
148 if (obj1.Equals(obj2))
161 * @class _MultiHashMapDefaultProvider
162 * @brief This is an implementation of IHashCodeProvider for MultiHashMap.
164 class _MultiHashMapDefaultProvider
165 : public IHashCodeProvider
169 _MultiHashMapDefaultProvider(void) {}
170 virtual ~_MultiHashMapDefaultProvider(void) {}
172 using Object::GetHashCode;
173 virtual int GetHashCode(const Object& obj) const
175 return obj.GetHashCode();
181 * @class _MultiHashMapEnumerator
182 * @brief This is an implementation of IMapEnumerator for MultiHashMap.
184 class _MultiHashMapEnumerator
185 : public IMapEnumerator
189 _MultiHashMapEnumerator(const MultiHashMap& map, int modCount);
190 virtual ~_MultiHashMapEnumerator(void);
192 virtual Object* GetCurrent(void) const;
193 virtual result MoveNext(void);
194 virtual result Reset(void);
195 virtual Object* GetKey(void) const;
196 virtual Object* GetValue(void) const;
199 const MultiHashMap& __map;
201 _MultiHashMapEntry* __pEntry;
207 _MultiHashMapEnumerator::_MultiHashMapEnumerator(const MultiHashMap& map, int modCount)
209 , __modCount(modCount)
216 _MultiHashMapEnumerator::~_MultiHashMapEnumerator(void)
221 _MultiHashMapEnumerator::GetCurrent(void) const
223 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));
224 SysTryReturn(NID_BASE_COL, (__pEntry != null && __pNode != null), null, E_INVALID_OPERATION, "[%s] Invalid position(pEntry or pNode is null).", GetErrorMessage(E_INVALID_OPERATION));
226 SetLastResult(E_SUCCESS);
231 _MultiHashMapEnumerator::MoveNext(void)
233 SysTryReturnResult(NID_BASE_COL, (__modCount == __map.__modCount), E_INVALID_OPERATION, "The source collection was modified after the creation of this enumerator.");
235 if ((null != __pNode) && (__pNode->pNext != null))
237 __pNode = __pNode->pNext;
240 else if ((null != __pEntry) && (__pEntry->pNext != null))
242 __pEntry = __pEntry->pNext;
243 __pNode = __pEntry->pList;
248 while (++__index < __map.__capacity)
250 __pEntry = __map.__pTable[__index];
251 if (null != __pEntry)
253 __pNode = __pEntry->pList;
259 return E_OUT_OF_RANGE;
263 _MultiHashMapEnumerator::Reset(void)
265 SysTryReturnResult(NID_BASE_COL, (__modCount == __map.__modCount), E_INVALID_OPERATION, "The source collection was modified after the creation of this enumerator.");
275 _MultiHashMapEnumerator::GetKey(void) const
277 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));
278 SysTryReturn(NID_BASE_COL, (__pEntry != null && __pNode != null), null, E_INVALID_OPERATION, "[%s] Invalid position(pEntry or pNode is null).", GetErrorMessage(E_INVALID_OPERATION));
280 SetLastResult(E_SUCCESS);
281 return __pEntry->pKey;
285 _MultiHashMapEnumerator::GetValue(void) const
287 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));
288 SysTryReturn(NID_BASE_COL, (__pEntry != null && __pNode != null), null, E_INVALID_OPERATION, "[%s] Invalid position(pEntry or pNode is null).", GetErrorMessage(E_INVALID_OPERATION));
290 SetLastResult(E_SUCCESS);
291 return __pNode->GetValue();
295 * @class _EntryValueEnumerator
296 * @brief This is an implementation of IEnumerator to enumerate values whose key is the same.
298 class _EntryValueEnumerator
303 _EntryValueEnumerator(const _MultiHashMapEntry& entry, int modCount);
304 virtual ~_EntryValueEnumerator(void);
306 virtual Object* GetCurrent(void) const;
307 virtual result MoveNext(void);
308 virtual result Reset(void);
311 const _MultiHashMapEntry& __entry;
317 _EntryValueEnumerator::_EntryValueEnumerator(const _MultiHashMapEntry& entry, int modCount)
319 , __modCount(modCount)
324 _EntryValueEnumerator::~_EntryValueEnumerator(void)
329 _EntryValueEnumerator::GetCurrent(void) const
331 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));
332 SysTryReturn(NID_BASE_COL, __pNode != null, null, E_INVALID_OPERATION, "[%s] Invalid position(pNode is null).", GetErrorMessage(E_INVALID_OPERATION));
334 SetLastResult(E_SUCCESS);
335 return __pNode->GetValue();
339 _EntryValueEnumerator::MoveNext(void)
341 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));
345 __pNode = __entry.pList;
346 SysAssert(null != __pNode);
348 else if (__pNode->pNext != null)
350 __pNode = __pNode->pNext;
354 // Do not log the E_OUT_OF_RANGE, because it's normal or trivial in most cases.
355 return E_OUT_OF_RANGE;
362 _EntryValueEnumerator::Reset(void)
364 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));
370 const float MultiHashMap::DEFAULT_LOAD_FACTOR = 0.75;
372 MultiHashMap::MultiHashMap(DeleterFunctionType deleter)
380 , __needToRemoveProviderComparer(false)
383 , __pMultiHashMapImpl(null)
387 MultiHashMap::~MultiHashMap(void)
390 if (__pTable != null)
396 if (__needToRemoveProviderComparer)
404 MultiHashMap::Construct(int capacity, float loadFactor)
406 SysTryReturnResult(NID_BASE_COL, capacity >= 0, E_INVALID_ARG, "The capacity(%d) MUST be greater than or equal to 0.", capacity);
407 SysTryReturnResult(NID_BASE_COL, loadFactor >= 0, E_INVALID_ARG, "The loadFactor(%f) MUST be greater than or equal to 0.0.", loadFactor);
409 std::unique_ptr< IHashCodeProvider > pProvider(new (std::nothrow) _MultiHashMapDefaultProvider());
410 SysTryReturnResult(NID_BASE_COL, pProvider != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
412 std::unique_ptr< IComparer > pComparer(new (std::nothrow) _MultiHashMapDefaultComparer());
413 SysTryReturnResult(NID_BASE_COL, pComparer != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
415 __needToRemoveProviderComparer = true;
417 result r = Construct(capacity, loadFactor, *(pProvider.release()), *(pComparer.release()));
418 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, r, "Propagating.");
424 MultiHashMap::Construct(const IMultiMap& map, float loadFactor)
426 SysTryReturnResult(NID_BASE_COL, loadFactor >= 0, E_INVALID_ARG, "The loadFactor(%f) MUST be greater than or equal to 0.0.", loadFactor);
428 std::unique_ptr< IHashCodeProvider > pProvider(new (std::nothrow) _MultiHashMapDefaultProvider());
429 SysTryReturnResult(NID_BASE_COL, pProvider != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
431 std::unique_ptr< IComparer > pComparer(new (std::nothrow) _MultiHashMapDefaultComparer());
432 SysTryReturnResult(NID_BASE_COL, pComparer != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
434 __needToRemoveProviderComparer = true;
436 result r = Construct(map, loadFactor, *(pProvider.release()), *(pComparer.release()));
437 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, r, "Propagating.");
443 MultiHashMap::Construct(int capacity, float loadFactor, const IHashCodeProvider& provider, const IComparer& comparer)
445 SysTryReturnResult(NID_BASE_COL, capacity >= 0, E_INVALID_ARG, "The capacity(%d) MUST be greater than or equal to 0.", capacity);
446 SysTryReturnResult(NID_BASE_COL, loadFactor >= 0, E_INVALID_ARG, "The loadFactor(%f) MUST be greater than or equal to 0.0.", loadFactor);
451 newCapacity = DEFAULT_CAPACITY;
456 while (newCapacity < capacity)
462 float newLoadFactor = 0;
463 if (Float::Compare(loadFactor, 0) == 0)
465 newLoadFactor = DEFAULT_LOAD_FACTOR;
469 newLoadFactor = loadFactor;
472 int newThreshold = static_cast< int >(newCapacity * newLoadFactor);
473 std::unique_ptr< IHashCodeProvider > pProvider(const_cast< IHashCodeProvider* >(&provider));
474 std::unique_ptr< IComparer > pComparer(const_cast< IComparer* >(&comparer));
475 std::unique_ptr< _MultiHashMapEntry*[] > pTable(new (std::nothrow) _MultiHashMapEntry*[newCapacity]);
476 SysTryReturnResult(NID_BASE_COL, pTable != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
478 memset(pTable.get(), null, sizeof(*(pTable.get())) * newCapacity);
480 __capacity = newCapacity;
481 __loadFactor = newLoadFactor;
482 __threshold = newThreshold;
483 __pProvider = pProvider.release();
484 __pComparer = pComparer.release();
485 __pTable = pTable.release();
491 MultiHashMap::Construct(const IMultiMap& map, float loadFactor, const IHashCodeProvider& provider, const IComparer& comparer)
493 SysTryReturnResult(NID_BASE_COL, (loadFactor >= 0), E_INVALID_ARG, "The loadFactor(%f) MUST be greater than or equal to 0.0.", loadFactor);
495 result r = E_SUCCESS;
496 if (Float::Compare(loadFactor, 0) == 0)
498 loadFactor = DEFAULT_LOAD_FACTOR;
501 int capacity = static_cast< int >(map.GetCount() / loadFactor) + 1;
503 r = Construct(capacity, loadFactor, provider, comparer);
504 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, r, "Propagating.");
507 SysTryCatch(NID_BASE_COL, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
511 DeleterFunctionType deleter = GetDeleter();
512 SetDeleter(SingleObjectDeleter);
519 if (__needToRemoveProviderComparer)
533 MultiHashMap::Add(Object* pKey, Object* pValue)
535 SysTryReturnResult(NID_BASE_COL, pKey != null , E_INVALID_ARG, "Invalid argument used. The pKey is null");
536 SysTryReturnResult(NID_BASE_COL, pValue != null, E_INVALID_ARG, "Invalid argument used. The pValue is null");
538 __Node* pNewNode = null;
540 result r = E_SUCCESS;
541 int hash = Hash(*pKey);
542 int i = hash & (__capacity - 1);
543 __Node* pNode = null;
544 _MultiHashMapEntry* pEntry = null;
546 if (__pTable != null)
548 pEntry = __pTable[i];
550 while (pEntry != null)
552 if (hash == pEntry->hash)
555 r = __pComparer->Compare(*pKey, *(pEntry->pKey), cmpResult);
556 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, E_INVALID_ARG, "Translating [%s] into [%s]", GetErrorMessage(r), GetErrorMessage(E_INVALID_ARG));
560 pNode = pEntry->pList;
563 SysTryReturnResult(NID_BASE_COL, !(pNode->_pValue->Equals(*pValue)), E_OBJ_ALREADY_EXIST, "The value is already exist for the key.");
565 if (pNode->pNext != null)
567 pNode = pNode->pNext;
578 pEntry = pEntry->pNext;
581 pNewNode = new (std::nothrow) __Node(pKey, pValue);
582 SysTryReturnResult(NID_BASE_COL, pNewNode != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
584 // pKey is not exist in this map.
587 _MultiHashMapEntry* pNewEntry = new (std::nothrow) _MultiHashMapEntry(pKey, pNewNode, __pTable[i], hash);
588 SysTryReturnResult(NID_BASE_COL, pNewEntry != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
589 __pTable[i] = pNewEntry;
591 // pKey is already exist in this map, but value is not.
594 // pNode is the last value associated to the pKey
595 pNode->pNext = pNewNode;
600 if (__count++ >= __threshold)
602 r = Resize(__capacity * 2);
603 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, r, "Propagating.");
610 MultiHashMap::GetEnumeratorN(void) const
612 std::unique_ptr< _MultiHashMapEnumerator > pEnum(new (std::nothrow) _MultiHashMapEnumerator(*this, __modCount));
613 SysTryReturn(NID_BASE_COL, pEnum != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
615 SetLastResult(E_SUCCESS);
616 return pEnum.release();
620 MultiHashMap::GetMapEnumeratorN(void) const
622 return dynamic_cast< IMapEnumerator* >(GetEnumeratorN());
626 MultiHashMap::GetValuesN(const Object& key) const
628 int hash = Hash(key);
629 int i = hash & (__capacity - 1);
631 for (_MultiHashMapEntry* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
633 if (hash == pEntry->hash)
636 result r = __pComparer->Compare(key, *(pEntry->pKey), cmpResult);
637 SysTryReturn(NID_BASE_COL, r == E_SUCCESS, null, E_INVALID_ARG, "[%s] Propagating.", GetErrorMessage(r));
641 std::unique_ptr< IEnumerator > pEnum(new (std::nothrow) _EntryValueEnumerator(*pEntry, pEntry->modCount));
642 SysTryReturn(NID_BASE_COL, pEnum != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
644 SetLastResult(E_SUCCESS);
645 return pEnum.release();
650 SetLastResult(E_OBJ_NOT_FOUND);
655 MultiHashMap::GetKeysN(void) const
657 result r = E_SUCCESS;
660 std::unique_ptr< ArrayList > pList(new (std::nothrow) ArrayList());
661 SysTryReturn(NID_BASE_COL, pList != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
663 r = pList->Construct(__count);
664 SysTryReturn(NID_BASE_COL, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
666 for (int i = 0; i < __capacity; i++)
668 for (_MultiHashMapEntry* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
670 r = pList->Add(pEntry->pKey);
671 SysTryReturn(NID_BASE_COL, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
676 SetLastResult(E_SUCCESS);
677 return pList.release();
681 MultiHashMap::GetValuesN(void) const
683 result r = E_SUCCESS;
685 std::unique_ptr< ArrayList > pList(new (std::nothrow) ArrayList());
686 SysTryReturn(NID_BASE_COL, pList != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
688 r = pList->Construct(__count);
689 SysTryReturn(NID_BASE_COL, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
691 for (int i = 0; i < __capacity; i++)
693 for (_MultiHashMapEntry* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
695 for (__Node* pNode = pEntry->pList; null != pNode; pNode = pNode->pNext)
697 r = pList->Add(pNode->_pValue);
698 SysTryReturn(NID_BASE_COL, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
703 SetLastResult(E_SUCCESS);
704 return pList.release();
708 MultiHashMap::Remove(const Object& key)
710 int hash = Hash(key);
711 int i = hash & (__capacity - 1);
713 _MultiHashMapEntry* pPrev = __pTable[i];
714 for (_MultiHashMapEntry* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
716 if (hash == pEntry->hash)
719 result r = __pComparer->Compare(key, *(pEntry->pKey), cmpResult);
720 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, E_INVALID_ARG, "The input argument is invalid");
727 __pTable[i] = pEntry->pNext;
731 pPrev->pNext = pEntry->pNext;
734 __Node* pNode = pEntry->pList;
735 while (pNode != null)
737 __Node* pTemp = pNode;
738 pNode = pNode->pNext;
740 __deleter(pTemp->_pValue);
746 __deleter(pEntry->pKey);
756 return E_OBJ_NOT_FOUND;
760 MultiHashMap::Remove(const Object& key, const Object& value)
762 int hash = Hash(key);
763 int i = hash & (__capacity - 1);
765 _MultiHashMapEntry* pPrev = __pTable[i];
766 for (_MultiHashMapEntry* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
768 if (hash == pEntry->hash)
771 result r = __pComparer->Compare(key, *(pEntry->pKey), cmpResult);
772 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, E_INVALID_ARG, "The input argument is invalid");
776 __Node* pPrevNode = pEntry->pList;
777 for (__Node* pNode = pEntry->pList; null != pNode; pNode = pNode->pNext)
779 if (value.Equals(*(pNode->_pValue)))
783 if (pPrevNode == pNode)
785 pEntry->pList = pNode->pNext;
789 pPrevNode->pNext = pNode->pNext;
792 __deleter(pNode->_pValue);
793 pNode->_pValue = null;
800 if (pEntry->pList == null)
804 __pTable[i] = pEntry->pNext;
808 pPrev->pNext = pEntry->pNext;
811 __deleter(pEntry->pKey);
830 return E_OBJ_NOT_FOUND;
834 MultiHashMap::RemoveAll(void)
845 MultiHashMap::SetValue(const Object& key, const Object& value, Object* pNewValue)
847 SysTryReturnResult(NID_BASE_COL, pNewValue != null , E_INVALID_ARG, "Invalid argument used. The pNewValue is null");
849 result r = E_SUCCESS;
850 int hash = Hash(key);
851 int i = hash & (__capacity - 1);
852 __Node* pNode = null;
853 _MultiHashMapEntry* pEntry = __pTable[i];
854 bool pairExist = false;
855 while (null != pEntry)
857 if (hash == pEntry->hash)
860 r = __pComparer->Compare(key, *(pEntry->pKey), cmpResult);
861 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, E_INVALID_ARG, "The input argument is invalid");
865 pNode = pEntry->pList;
868 if (pNode->_pValue->Equals(value))
871 __deleter(pNode->_pValue);
872 pNode->_pValue = pNewValue;
876 if (pNode->pNext != null)
878 pNode = pNode->pNext;
889 pEntry = pEntry->pNext;
902 MultiHashMap::GetCount(void) const
908 MultiHashMap::GetCount(const Object& key, int& count) const
912 result r = E_OBJ_NOT_FOUND;
913 int hash = Hash(key);
914 int i = hash & (__capacity - 1);
916 for (_MultiHashMapEntry* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
918 if (hash == pEntry->hash)
921 r = __pComparer->Compare(key, *(pEntry->pKey), cmpResult);
922 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, E_INVALID_ARG, "The input argument is invalid");
927 for (__Node* pNode = pEntry->pList; null != pNode; pNode = pNode->pNext)
942 MultiHashMap::Contains(const Object& key, const Object& value) const
944 result r = E_SUCCESS;
945 int hash = Hash(key);
946 int i = hash & (__capacity - 1);
948 SetLastResult(E_SUCCESS);
950 for (_MultiHashMapEntry* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
952 if (hash == pEntry->hash)
955 r = __pComparer->Compare(key, *(pEntry->pKey), cmpResult);
956 SysTryReturn(NID_BASE_COL, r == E_SUCCESS, false, E_INVALID_ARG, "Translating [%s] into [%s]", GetErrorMessage(r), GetErrorMessage(E_INVALID_ARG));
960 for (__Node* pNode = pEntry->pList; null != pNode; pNode = pNode->pNext)
962 if (value.Equals(*(pNode->_pValue)))
975 MultiHashMap::ContainsKey(const Object& key) const
977 result r = E_SUCCESS;
978 int hash = Hash(key);
979 int i = hash & (__capacity - 1);
981 SetLastResult(E_SUCCESS);
983 for (_MultiHashMapEntry* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
985 if (hash == pEntry->hash)
988 r = __pComparer->Compare(key, *(pEntry->pKey), cmpResult);
989 SysTryReturn(NID_BASE_COL, r == E_SUCCESS, false, E_INVALID_ARG, "[%s] Propagating.", GetErrorMessage(r));
1002 MultiHashMap::ContainsValue(const Object& value) const
1004 for (int i = 0; i < __capacity; i++)
1006 for (_MultiHashMapEntry* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
1008 for (__Node* pNode = pEntry->pList; null != pNode; pNode = pNode->pNext)
1010 if (value.Equals(*(pNode->_pValue)))
1021 MultiHashMap::Equals(const Object& obj) const
1023 const MultiHashMap* pOther = dynamic_cast< const MultiHashMap* >(&obj);
1028 else if (pOther == this)
1032 else if (__count != pOther->__count)
1038 bool contain = true;
1039 for (int i = 0; i < __capacity; i++)
1041 for (_MultiHashMapEntry* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
1043 for (__Node* pNode = pEntry->pList; null != pNode; pNode = pNode->pNext)
1045 contain = pOther->Contains(*(pEntry->pKey), *(pNode->_pValue));
1046 result r = GetLastResult();
1047 SysTryReturn(NID_BASE_COL, !IsFailed(r), false, r, "[%s] Propagating", GetErrorMessage(r));
1066 MultiHashMap::GetHashCode(void) const
1069 _MultiHashMapEntry* pEntry = null;
1070 _MultiHashMapEntry* pNext = null;
1071 __Node* pNode = null;
1072 for (int i = 0; i < __capacity; i++)
1074 pEntry = __pTable[i];
1075 while (pEntry != null)
1077 pNext = pEntry->pNext;
1078 pNode = pEntry->pList;
1079 while (pNode != null)
1081 hash += pNode->_pValue->GetHashCode();
1082 pNode = pNode->pNext;
1085 hash += pEntry->pKey->GetHashCode();
1093 MultiHashMap::GetDeleter(void) const
1099 MultiHashMap::AddAll(const IMultiMap& map)
1101 result r = E_SUCCESS;
1102 std::unique_ptr< IMapEnumerator > pMapEnum(map.GetMapEnumeratorN());
1103 SysTryReturnResult(NID_BASE_COL, pMapEnum != null, GetLastResult(), "Propagating.");
1105 while ((r = pMapEnum->MoveNext()) != E_OUT_OF_RANGE)
1107 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, r, "Propagating.");
1109 Object* pKey = pMapEnum->GetKey();
1110 SysTryReturnResult(NID_BASE_COL, pKey != null, GetLastResult(), "Propagating.");
1112 Object* pValue = pMapEnum->GetValue();
1113 SysTryReturnResult(NID_BASE_COL, pValue != null, GetLastResult(), "Propagating.");
1115 r = Add(pKey, pValue);
1116 SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, r, "Propagating.");
1123 MultiHashMap::Hash(const Object& obj) const
1125 int h = __pProvider->GetHashCode(obj);
1127 h ^= (h >> 20) ^ (h >> 12);
1129 return h ^ (h >> 7) ^ (h >> 4);
1133 MultiHashMap::Resize(int newCapacity)
1135 _MultiHashMapEntry** pNewTable = new (std::nothrow) _MultiHashMapEntry*[newCapacity];
1136 SysTryReturnResult(NID_BASE_COL, pNewTable != null, E_OUT_OF_MEMORY, "");
1137 memset(pNewTable, null, sizeof(*pNewTable) * newCapacity);
1139 for (int i = 0; i < __capacity; i++)
1141 _MultiHashMapEntry* pNext = null;
1143 for (_MultiHashMapEntry* pEntry = __pTable[i]; null != pEntry; pEntry = pNext)
1145 pNext = pEntry->pNext;
1146 index = pEntry->hash & (newCapacity - 1);
1147 pEntry->pNext = pNewTable[index];
1148 pNewTable[index] = pEntry;
1153 __pTable = pNewTable;
1154 __capacity = newCapacity;
1155 __threshold = static_cast< int >(__capacity * __loadFactor);
1161 MultiHashMap::Reset(void)
1163 for (int i = 0; i < __capacity; i++)
1165 _MultiHashMapEntry* pEntry = __pTable[i];
1166 while (pEntry != null)
1168 _MultiHashMapEntry* pNext = pEntry->pNext;
1169 __Node* pNode = pEntry->pList;
1171 while (pNode != null)
1173 std::unique_ptr< __Node > pTemp(pNode);
1174 pNode = pNode->pNext;
1176 __deleter(pTemp->_pValue);
1179 __deleter(pEntry->pKey);
1188 MultiHashMap::SetDeleter(DeleterFunctionType deleter)
1190 __deleter = deleter;
1192 } } } // Tizen::Base::Collectionn