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 FBaseColMultiHashMapT.h
20 * @brief This is the header file for the %MultiHashMapT class.
22 * This header file contains the declarations of the %MultiHashMapT class.
24 #ifndef _FBASE_COL_MULTI_HASH_MAP_T_H_
25 #define _FBASE_COL_MULTI_HASH_MAP_T_H_
27 #include <FBaseObject.h>
28 #include <FBaseResult.h>
29 #include <FBaseColIComparerT.h>
30 #include <FBaseColIHashCodeProviderT.h>
31 #include <FBaseColIListT.h>
32 #include <FBaseColIMultiMapT.h>
33 #include <FBaseColMapEntryT.h>
34 #include <FBaseComparerT.h>
35 #include <FBaseFloat.h>
38 namespace Tizen { namespace Base { namespace Collection
41 template< class KeyType, class ValueType > class __MultiHashMapEntryT;
42 template< class KeyType, class ValueType > class __MultiHashMapEnumeratorT;
43 template< class KeyType, class ValueType > class __EntryValueEnumeratorT;
44 template< class KeyType > class __MultiHashMapDefaultProviderT;
46 template< class ValueType > class __ValueNodeT;
49 * @class MultiHashMapT
50 * @brief This class represents a template-based collection of associated keys and values that are organized based on the hash code of the key.
54 * The %MultiHashMapT class represents a template-based collection of associated keys and values that are organized based on the hash code of the key.
55 * There is no limit on the number of elements with the same key, but duplicated elements with the same key are not allowed.
56 * The key and value cannot be null. Several methods in the %MultiHashMapT class need an assignment(=) operator of KeyType, and assignment(=) and equivalent(==) operators of ValueType.
58 * For more information on the class features, see <a href="../org.tizen.native.appprogramming/html/guide/base/hashmap_multihashmap.htm">HashMap and MultiHashMap</a>.
60 * The following example demonstrates how to use the %MultiHashMapT class.
67 * using namespace Tizen::Base;
68 * using namespace Tizen::Base::Collection;
71 * MyClass::MultiHashMapTSample(void)
73 * MultiHashMapT< int, int > map;
75 * // Constructs a MultiHashMap instance with default capacity, load factor, hash code provider, and comparer
81 * map.Add(1, 1000); // map.GetCount() : 1, map : (1 -> 1000)
82 * map.Add(2, 2000); // map.GetCount() : 2, map : (1 -> 1000), (2 -> 2000)
83 * map.Add(3, 3000); // map.GetCount() : 3, map : (1 -> 1000), (2 -> 2000), (3 -> 3000)
84 * map.Add(3, 30); // map.GetCount() : 4, map : (1 -> 1000), (2 -> 2000), (3 -> 3000, 30)
86 * // Gets values with the specified key
88 * IEnumeratorT< int >* pValueEnum = map.GetValuesN(key);
89 * while (pValueEnum->MoveNext() == E_SUCCESS)
91 * pValueEnum->GetCurrent(value);
96 * // Removes the values with the specified key
98 * map.Remove(key); // 30, 3000 removed
100 * // Uses an enumerator to access elements in the map
101 * IMapEnumeratorT< int, int >* pMapEnum = map.GetMapEnumeratorN();
102 * while (pMapEnum->MoveNext() == E_SUCCESS)
104 * pMapEnum->GetKey(key);
105 * pMapEnum->GetValue(value);
113 template< class KeyType, class ValueType >
115 : public IMultiMapT< KeyType, ValueType >
120 * The object is not fully constructed after this constructor is called. For full construction, @n
121 * the Construct() method must be called right after calling this constructor.
133 , __defaultConstruct(false)
139 * This destructor overrides Tizen::Base::Object::~Object().
143 virtual ~MultiHashMapT(void)
145 if (null != __pTable)
151 if (__defaultConstruct)
160 * Initializes this instance of %MultiHashMapT with the given capacity and load factor.
164 * @return An error code
165 * @param[in] capacity The initial capacity
166 * @param[in] loadFactor The maximum ratio of elements to buckets
167 * @exception E_SUCCESS The method is successful.
168 * @exception E_INVALID_ARG A specified input parameter is invalid, or
169 * the specified @c capacity or the @c loadFactor is negative.
170 * @remarks The key type must be a primitive data type.
171 * @see MultiHashMapT()
173 result Construct(int capacity = 16, float loadFactor = 0.75)
175 TryReturn(capacity >= 0, E_INVALID_ARG, "[%s] The capacity(%d) MUST be greater than or equal to 0.", GetErrorMessage(E_INVALID_ARG), capacity);
176 TryReturn(loadFactor >= 0, E_INVALID_ARG, "[%s] The loadFactor(%f) MUST be greater than or equal to 0.0.", GetErrorMessage(E_INVALID_ARG), loadFactor);
178 result r = E_SUCCESS;
183 __capacity = DEFAULT_CAPACITY;
188 while (__capacity < capacity)
195 if (Float::Compare(loadFactor, 0) == 0)
197 __loadFactor = DEFAULT_LOAD_FACTOR;
201 __loadFactor = loadFactor;
205 __threshold = static_cast< int >(__capacity * __loadFactor);
207 // set hash code provider
208 __pProvider = new __MultiHashMapDefaultProviderT< KeyType >();
209 TryCatch(__pProvider != null, r = E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
212 __pComparer = new Tizen::Base::ComparerT< KeyType >();
213 TryCatch(__pComparer != null, r = E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
215 __defaultConstruct = true;
217 __pTable = new __MultiHashMapEntryT< KeyType, ValueType >*[__capacity];
218 TryCatch(__pTable != null, r = E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
220 memset(__pTable, null, sizeof(__MultiHashMapEntryT< KeyType, ValueType >*) * __capacity);
233 * Initializes this instance of %MultiHashMapT by copying the elements of the specified map.
237 * @return An error code
238 * @param[in] map A map to copy
239 * @param[in] loadFactor The maximum ratio of elements to buckets @n
240 * If it is @c 0, the default load factor(0.75) is used.
241 * @exception E_SUCCESS The method is successful.
242 * @exception E_INVALID_ARG A specified input parameter is invalid, or
243 * the specified @c loadFactor is negative.
244 * @exception E_INVALID_OPERATION The current state of the instance prohibits the execution of the specified operation, or
245 * the @c map is modified during the operation of this method.
246 * @see MultiHashMapT()
248 result Construct(const IMultiMapT< KeyType, ValueType >& map, float loadFactor = 0.75)
250 TryReturn((loadFactor >= 0), E_INVALID_ARG, "[%s] The loadFactor(%f) MUST be greater than or equal to 0.0.", GetErrorMessage(E_INVALID_ARG), loadFactor);
252 result r = E_SUCCESS;
254 if (Float::Compare(loadFactor, 0) == 0)
256 loadFactor = DEFAULT_LOAD_FACTOR;
259 int capacity = static_cast< int >(map.GetCount() / loadFactor) + 1;
260 r = Construct(capacity, loadFactor);
261 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
264 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
285 * Initializes this instance of %MultiHashMapT that is empty,
286 * with the specified initial capacity, load factor, hash code provider, and comparer.
290 * @return An error code
291 * @param[in] capacity The initial capacity @n
292 * If it is @c 0, the default capacity(16) is used.
293 * @param[in] loadFactor The maximum ratio of elements to buckets @n
294 * If it is @c 0, the default load factor(0.75) is used.
295 * @param[in] provider An instance of the IHashCodeProvider derived class that supplies the hash codes
296 * for all keys in this map
297 * @param[in] comparer An instance of the IComparer derived class to use when comparing keys
298 * @exception E_SUCCESS The method is successful.
299 * @exception E_INVALID_ARG A specified input parameter is invalid, or
300 * the specified @c capacity or the @c loadFactor is negative.
301 * @remarks The instances of hash code provider and comparer will not be deallocated later from this map.
302 * @see MultiHashMapT()
304 result Construct(int capacity, float loadFactor, const IHashCodeProviderT< KeyType >& provider,
305 const IComparerT< KeyType >& comparer)
307 TryReturn(capacity >= 0, E_INVALID_ARG, "[%s] The capacity(%d) MUST be greater than or equal to 0.", GetErrorMessage(E_INVALID_ARG), capacity);
308 TryReturn(loadFactor >= 0, E_INVALID_ARG, "[%s] The loadFactor(%f) MUST be greater than or equal to 0.0.", GetErrorMessage(E_INVALID_ARG), loadFactor);
310 result r = E_SUCCESS;
314 __capacity = DEFAULT_CAPACITY;
319 while (__capacity < capacity)
326 if (Float::Compare(loadFactor, 0) == 0)
328 __loadFactor = DEFAULT_LOAD_FACTOR;
332 __loadFactor = loadFactor;
336 __threshold = static_cast< int >(__capacity * __loadFactor);
338 // set hash code provider
339 __pProvider = const_cast< IHashCodeProviderT< KeyType >* >(&provider);
342 __pComparer = const_cast< IComparerT< KeyType >* >(&comparer);
344 __pTable = new __MultiHashMapEntryT< KeyType, ValueType >*[__capacity];
345 TryCatch(__pTable != null, r = E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
347 memset(__pTable, null, sizeof(__MultiHashMapEntryT< KeyType, ValueType >*) * __capacity);
360 * Initializes this instance of %MultiHashMapT by copying the elements of the specified map,
361 * with the specified load factor, hash code provider, and comparer.
365 * @return An error code
366 * @param[in] map A map to copy
367 * @param[in] loadFactor The maximum ratio of elements to buckets @n
368 * If it is @c 0, the default load factor(0.75) is used.
369 * @param[in] provider An instance of the IHashCodeProvider derived class that supplies the hash codes
370 * for all keys in this map
371 * @param[in] comparer An instance of the IComparer derived class to use when comparing keys
372 * @exception E_SUCCESS The method is successful.
373 * @exception E_INVALID_ARG A specified input parameter is invalid, or
374 * the specified @c loadFactor is negative.
375 * @exception E_INVALID_OPERATION The current state of the instance prohibits the execution of the specified operation, or
376 * the @c map is modified during the operation of this method.
377 * @remarks The instances of hash code provider and comparer will not be deallocated later from this map.
378 * @see MultiHashMapT()
380 result Construct(const IMultiMapT< KeyType, ValueType >& map, float loadFactor, const IHashCodeProviderT< KeyType >& provider,
381 const IComparerT< KeyType >& comparer)
383 TryReturn(loadFactor >= 0, E_INVALID_ARG, "[%s] The loadFactor(%f) MUST be greater than or equal to 0.0.", GetErrorMessage(E_INVALID_ARG), loadFactor);
385 result r = E_SUCCESS;
387 if (Float::Compare(loadFactor, 0) == 0)
389 loadFactor = DEFAULT_LOAD_FACTOR;
392 int capacity = static_cast< int >(map.GetCount() / loadFactor) + 1;
394 r = Construct(capacity, loadFactor, provider, comparer);
395 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
398 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
415 * Adds the specified key-value pair to this map.
419 * @return An error code
420 * @param[in] key A key of the value to add
421 * @param[in] value A value to add
422 * @exception E_SUCCESS The method is successful.
423 * @exception E_OBJ_ALREADY_EXIST The specified pair of @c key and @c value already exists.
424 * @exception E_INVALID_ARG A specified input parameter is invalid, or
425 * the comparer has failed to compare the keys.
426 * @remarks SetItem() can be used to set value to a key that does not already exist.
427 * However, setting a value to a key that already exists overwrites the value.
431 virtual result Add(const KeyType& key, const ValueType& value)
433 result r = E_SUCCESS;
434 int hash = Hash(key);
435 int i = hash & (__capacity - 1);
436 __ValueNodeT< ValueType >* pNode = null;
437 __MultiHashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i];
438 while (null != pEntry)
440 if (hash == pEntry->hash)
443 r = __pComparer->Compare(key, pEntry->key, cmpResult);
444 TryReturn(r == E_SUCCESS, E_INVALID_ARG, "[%s] Propagating.", GetErrorMessage(r));
448 pNode = pEntry->pList;
451 if (pNode->value == value)
453 return E_OBJ_ALREADY_EXIST;
456 if (pNode->pNext != null)
458 pNode = pNode->pNext;
469 pEntry = pEntry->pNext;
472 __ValueNodeT< ValueType >* pNewNode = new __ValueNodeT< ValueType >(value);
473 TryReturn(pNewNode != null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
475 // key is not exist in this map.
478 __MultiHashMapEntryT< KeyType, ValueType >* pNewEntry = new __MultiHashMapEntryT< KeyType, ValueType >(key, pNewNode, __pTable[i],
480 TryReturn(pNewEntry != null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
481 __pTable[i] = pNewEntry;
483 // key is already exist in this map, but value is not.
486 // pNode is the last value associated to the key
487 pNode->pNext = pNewNode;
492 if (__count++ >= __threshold)
494 r = Resize(__capacity * 2);
495 TryReturn(r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
502 * Gets an enumerator of this map.
506 * @return An enumerator (an instance of the %IMapEnumeratorT derived class) of this map, @n
507 * else @c null if an exception occurs
508 * @exception E_SUCCESS The method is successful.
509 * @exception E_OUT_OF_MEMORY The memory is insufficient.
510 * @remarks If the key has multiple values, the Enumeration proceeds as follows: {A: a}, {B: b}, {B: c}, {B, d}, {C: e}, ...
511 * The specific error code can be accessed using the GetLastResult() method.
512 * @see Tizen::Base::Collection::IEnumerator
513 * @see Tizen::Base::Collection::IMapEnumerator
515 virtual IEnumeratorT< MapEntryT< KeyType, ValueType > >* GetEnumeratorN(void) const
517 result r = E_SUCCESS;
519 __MultiHashMapEnumeratorT< KeyType, ValueType >* pEnum = new __MultiHashMapEnumeratorT< KeyType, ValueType >(*this, __modCount);
520 TryCatch(pEnum != null, r = E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
522 SetLastResult(E_SUCCESS);
531 * Gets an IMapEnumerator of this map.
535 * @return An enumerator (an instance of the %IMapEnumeratorT derived class) of this map, @n
536 * else @c null if an exception occurs
537 * @exception E_SUCCESS The method is successful.
538 * @exception E_OUT_OF_MEMORY The memory is insufficient.
539 * @remarks If the key has multiple values, the Enumeration proceeds like this: {A: a}, {B: b}, {B: c}, {B, d}, {C: e}, ...
540 * @remarks The specific error code can be accessed using the GetLastResult() method.
541 * @see Tizen::Base::Collection::IEnumerator
542 * @see Tizen::Base::Collection::IMapEnumerator
544 virtual IMapEnumeratorT< KeyType, ValueType >* GetMapEnumeratorN(void) const
546 return dynamic_cast< IMapEnumeratorT< KeyType, ValueType >* >(GetEnumeratorN());
550 * Gets an enumerator of the values associated with the specified key.
554 * @return An enumerator (an instance of the IEnumeratorT derived class) of the values associated with the specified key, @n
555 * else @c null if an exception occurs
556 * @param[in] key A key to locate
557 * @exception E_SUCCESS The method is successful.
558 * @exception E_INVALID_ARG A specified input parameter is invalid, or
559 * the comparer has failed to compare the keys.
560 * @exception E_OBJ_NOT_FOUND The specified @c key is not found in the map.
561 * @remarks The specific error code can be accessed using the GetLastResult() method.
564 virtual IEnumeratorT< ValueType >* GetValuesN(const KeyType& key) const
566 result r = E_OBJ_NOT_FOUND;
568 int hash = Hash(key);
569 int i = hash & (__capacity - 1);
570 IEnumeratorT< ValueType >* pEnum = null;
572 for (__MultiHashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
574 if (hash == pEntry->hash)
577 r = __pComparer->Compare(key, pEntry->key, cmpResult);
578 TryCatch(r == E_SUCCESS, r = E_INVALID_ARG, "[%s] Propagating.", GetErrorMessage(r));
582 pEnum = new __EntryValueEnumeratorT< KeyType, ValueType >(*pEntry, pEntry->modCount);
583 TryCatch(pEnum != null, r = E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
601 * Gets a list of all unique keys in this map.
605 * @return A list of all unique keys in this map, @n
606 * else @c null if an exception occurs
607 * @exception E_SUCCESS The method is successful.
608 * @exception E_OUT_OF_MEMORY The memory is insufficient.
609 * @remarks The specific error code can be accessed using the GetLastResult() method.
612 virtual IListT< KeyType >* GetKeysN(void) const
616 result r = E_SUCCESS;
619 ArrayListT< KeyType >* pList = new ArrayListT< KeyType >();
620 r = pList->Construct(__count);
621 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
623 for (int i = 0; i < __capacity; i++)
625 for (__MultiHashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
627 r = pList->Add(pEntry->key);
628 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
643 * Gets a list of all the values in this map.
647 * @return A list of all the values in this map, @n
648 * else @c null if an exception occurs
649 * @exception E_SUCCESS The method is successful.
650 * @exception E_OUT_OF_MEMORY The memory is insufficient.
651 * @remarks The specific error code can be accessed using the GetLastResult() method.
654 virtual IListT< ValueType >* GetValuesN(void) const
658 result r = E_SUCCESS;
660 ArrayListT< ValueType >* pList = new ArrayListT< ValueType >();
661 r = pList->Construct(__count);
662 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
664 for (int i = 0; i < __capacity; i++)
666 for (__MultiHashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
668 for (__ValueNodeT< ValueType >* pNode = pEntry->pList; null != pNode; pNode = pNode->pNext)
670 r = pList->Add(pNode->value);
671 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
686 * Removes all the values for the specified key.
690 * @return An error code
691 * @param[in] key The key to remove
692 * @exception E_SUCCESS The method is successful.
693 * @exception E_INVALID_ARG The specified input parameter is invalid, or
694 * the comparer has failed to compare the keys.
695 * @exception E_OBJ_NOT_FOUND The specified @c key is not found in the map.
698 virtual result Remove(const KeyType& key)
700 result r = E_OBJ_NOT_FOUND;
701 int hash = Hash(key);
702 int i = hash & (__capacity - 1);
704 __MultiHashMapEntryT< KeyType, ValueType >* pPrev = __pTable[i];
705 for (__MultiHashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
707 if (hash == pEntry->hash)
710 r = __pComparer->Compare(key, pEntry->key, cmpResult);
711 TryReturn(r == E_SUCCESS, E_INVALID_ARG, "[%s] Propagating.", GetErrorMessage(r));
720 __pTable[i] = pEntry->pNext;
724 pPrev->pNext = pEntry->pNext;
727 __ValueNodeT< ValueType >* pNode = pEntry->pList;
728 while (null != pNode)
730 __ValueNodeT< ValueType >* pTemp = pNode;
731 pNode = pNode->pNext;
747 * Removes the specified value associated with the specified key. @n
748 * The key is also removed if there is no value associated with it.
752 * @return An error code
753 * @param[in] key The key whose mapping is to remove from the map
754 * @param[in] value The value to remove
755 * @exception E_SUCCESS The method is successful.
756 * @exception E_INVALID_ARG A specified input parameter is invalid, or
757 * the comparer has failed to compare the keys.
758 * @exception E_OBJ_NOT_FOUND The specified @c key and @c value pair is not found in the map.
761 virtual result Remove(const KeyType& key, const ValueType& value)
763 result r = E_OBJ_NOT_FOUND;
764 int hash = Hash(key);
765 int i = hash & (__capacity - 1);
767 __MultiHashMapEntryT< KeyType, ValueType >* pPrev = __pTable[i];
768 for (__MultiHashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
770 if (hash == pEntry->hash)
773 r = __pComparer->Compare(key, pEntry->key, cmpResult);
774 TryReturn(r == E_SUCCESS, E_INVALID_ARG, "[%s] Propagating.", GetErrorMessage(r));
779 __ValueNodeT< ValueType >* pPrevNode = pEntry->pList;
780 for (__ValueNodeT< ValueType >* pNode = pEntry->pList; null != pNode; pNode = pNode->pNext)
782 if (value == pNode->value)
786 if (pPrevNode == pNode)
788 pEntry->pList = pNode->pNext;
792 pPrevNode->pNext = pNode->pNext;
799 if (null == pEntry->pList)
803 __pTable[i] = pEntry->pNext;
807 pPrev->pNext = pEntry->pNext;
829 * Removes all key-value pairs in this map.
833 virtual void RemoveAll(void)
844 * Replaces the value associated with the key with the specified @c newValue.
848 * @return An error code
849 * @param[in] key A key
850 * @param[in] value A value to replace
851 * @param[in] newValue A new value to replace the existing value
852 * @exception E_SUCCESS The method is successful.
853 * @exception E_INVALID_ARG A specified input parameter is invalid, or
854 * the comparer has failed to compare the keys.
855 * @exception E_OBJ_NOT_FOUND The specified @c key and @c value pair is not found in the map.
856 * @remarks To add a new key-value pair, use the Add() method.
860 virtual result SetValue(const KeyType& key, const ValueType& value, const ValueType& newValue)
862 result r = E_SUCCESS;
863 int hash = Hash(key);
864 int i = hash & (__capacity - 1);
865 __ValueNodeT< ValueType >* pNode = null;
866 bool pairExist = false;
867 __MultiHashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i];
868 while (null != pEntry)
870 if (hash == pEntry->hash)
873 r = __pComparer->Compare(key, pEntry->key, cmpResult);
874 TryReturn(r == E_SUCCESS, E_INVALID_ARG, "[%s] Propagating.", GetErrorMessage(r));
878 pNode = pEntry->pList;
881 if (pNode->value == value)
884 pNode->value = newValue;
888 if (pNode->pNext != null)
890 pNode = pNode->pNext;
901 pEntry = pEntry->pNext;
913 * Gets the number of values currently stored in this map.
917 * @return The number of values currently stored in this map
919 virtual int GetCount(void) const
925 * Gets the number of values whose keys match the specified key.
929 * @return An error code
930 * @param[in] key A key to locate
931 * @param[out] count The number of values whose key is @c key
932 * @exception E_SUCCESS The method is successful.
933 * @exception E_INVALID_ARG A specified input parameter is invalid, or
934 * the comparer has failed to compare the keys.
935 * @exception E_OBJ_NOT_FOUND The specified @c key is not found in the map.
937 virtual result GetCount(const KeyType& key, int& count) const
939 result r = E_OBJ_NOT_FOUND;
940 int hash = Hash(key);
941 int i = hash & (__capacity - 1);
943 for (__MultiHashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
945 if (hash == pEntry->hash)
948 r = __pComparer->Compare(key, pEntry->key, cmpResult);
949 TryReturn(r == E_SUCCESS, E_INVALID_ARG, "[%s] Propagating.", GetErrorMessage(r));
954 for (__ValueNodeT< ValueType >* pNode = pEntry->pList; null != pNode; pNode = pNode->pNext)
971 * Checks whether the map contains the specified key and value.
975 * @return An error code
976 * @param[in] key The key to locate
977 * @param[in] value The value to locate
978 * @param[out] out Set to @c true if the map contains the specified key and value pair, @n
980 * @exception E_SUCCESS The method is successful.
981 * @exception E_INVALID_ARG The current state of the instance prohibits the execution of the specified operation, or
982 * the comparer has failed to compare the keys.
984 * @see ContainsValue()
986 virtual result Contains(const KeyType& key, const ValueType& value, bool& out) const
990 result r = E_SUCCESS;
991 int hash = Hash(key);
992 int i = hash & (__capacity - 1);
994 for (__MultiHashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
996 if (hash == pEntry->hash)
999 r = __pComparer->Compare(key, pEntry->key, cmpResult);
1002 AppLogException("[%s] Propagating.", GetErrorMessage(r));
1004 return E_INVALID_ARG;
1009 for (__ValueNodeT< ValueType >* pNode = pEntry->pList; null != pNode; pNode = pNode->pNext)
1011 if (value == pNode->value)
1027 * Checks whether the map contains the specified key.
1031 * @return An error code
1032 * @param[in] key The key to locate
1033 * @param[out] out Set to @c true if the map contains the specified key, @n
1035 * @exception E_SUCCESS The method is successful.
1036 * @exception E_INVALID_ARG A specified input parameter is invalid, or
1037 * the comparer has failed to compare the keys.
1038 * @see ContainsValue()
1041 virtual result ContainsKey(const KeyType& key, bool& out) const
1044 result r = E_SUCCESS;
1045 int hash = Hash(key);
1046 int i = hash & (__capacity - 1);
1048 for (__MultiHashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
1050 if (hash == pEntry->hash)
1053 r = __pComparer->Compare(key, pEntry->key, cmpResult);
1056 AppLogException("[%s] Propagating.", GetErrorMessage(r));
1058 return E_INVALID_ARG;
1072 * Checks whether the map contains the specified value.
1076 * @return @c true if the map contains the specified value, @n
1078 * @param[in] value The value to locate
1080 * @see ContainsKey()
1083 virtual bool ContainsValue(const ValueType& value) const
1086 for (int i = 0; i < __capacity; i++)
1088 for (__MultiHashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
1090 for (__ValueNodeT< ValueType >* pNode = pEntry->pList; null != pNode; pNode = pNode->pNext)
1092 if (value == pNode->value)
1111 * Compares the specified instance to the current instance for equality.
1115 * @return @c true if the two instances are equal, @n
1117 * @param[in] obj The object to compare with the current instance
1118 * @remarks This method returns @c true only if the specified object is also an instance of the %MultiHashMapT class,
1119 * both maps have the same number of elements, and both maps contain the same elements.
1121 virtual bool Equals(const Object& obj) const
1123 result r = E_SUCCESS;
1126 const MultiHashMapT< KeyType, ValueType >* other = dynamic_cast< const MultiHashMapT< KeyType, ValueType >* >(&obj);
1127 if (null == other) // obj is not MultiHashMapT<KeyType, ValueType>
1131 else if (other == this)
1135 else if (__count != other->__count)
1141 for (int i = 0; i < __capacity; i++)
1143 for (__MultiHashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
1145 for (__ValueNodeT< ValueType >* pNode = pEntry->pList; null != pNode; pNode = pNode->pNext)
1147 r = other->Contains(pEntry->key, pNode->value, out);
1165 * Gets the hash value of the current instance.
1169 * @return The hash value of the current instance
1170 * @remarks The two Tizen::Base::Object::Equals() instances must return the same hash value. For better performance, @n
1171 * the used hash function must generate a random distribution for all inputs.
1173 virtual int GetHashCode(void) const
1177 for (int i = 0; i < __capacity; i++)
1179 for (__MultiHashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
1181 for (__ValueNodeT< ValueType >* pNode = pEntry->pList; null != pNode; pNode = pNode->pNext)
1183 hash += reinterpret_cast< int >(&pNode->value);
1185 hash += reinterpret_cast< int >(&pEntry->key);
1192 * The implementation of this copy constructor is intentionally blank and declared as private to prohibit copying of objects.
1194 * @param[in] map An instance of %MultiHashMapT to initialize the current instance
1196 MultiHashMapT(const MultiHashMapT< KeyType, ValueType >& map);
1199 * The implementation of this copy assignment operator is intentionally blank and declared as private to prohibit copying of objects.
1201 * @param[in] map An instance of %MultiHashMapT
1203 MultiHashMapT< KeyType, ValueType >& operator =(const MultiHashMapT< KeyType, ValueType >& map);
1206 * Copies all the pairs from the specified map to this map.
1208 * @return An error code
1209 * @param[in] map The map to copy
1210 * @exception E_SUCCESS The method is successful.
1211 * @exception E_INVALID_OPERATION The current state of the instance prohibits the execution of the specified operation. @n
1212 * The @c map is modified during the operation of this method.
1214 result AddAll(const IMultiMapT< KeyType, ValueType >& map)
1216 result r = E_SUCCESS;
1218 IMultiMapT< KeyType, ValueType >* pMap = const_cast< IMultiMapT< KeyType, ValueType >* >(&map);
1219 IMapEnumeratorT< KeyType, ValueType >* pMapEnum = pMap->GetMapEnumeratorN();
1221 TryCatch(pMapEnum != null, r = GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
1228 r = pMapEnum->MoveNext();
1229 // enumerator is reached to the end of collection
1230 if (E_OUT_OF_RANGE == r)
1235 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
1237 r = pMapEnum->GetKey(key);
1238 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
1240 r = pMapEnum->GetValue(value);
1241 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
1243 r = Add(key, value);
1244 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
1247 if (null != pMapEnum)
1254 if (null != pMapEnum)
1262 * Gets a hash value for the specified object.
1264 * @return The hash value for the specified object
1265 * @param[in] obj The object to get hash value
1267 int Hash(const KeyType& obj) const
1269 int h = __pProvider->GetHashCode(obj);
1271 h ^= (h >> 20) ^ (h >> 12);
1273 return h ^ (h >> 7) ^ (h >> 4);
1277 * Resizes the contents of this map into a new array with a
1278 * larger capacity. @n
1279 * This method is called automatically when the
1280 * number of keys in this map reaches its threshold.
1282 * @return An error code
1283 * @param[in] newCapacity The new capacity @n
1284 * It must be a power of 2 and must be greater than current capacity.
1285 * @exception E_SUCCESS The method is successful.
1286 * @exception E_OUT_OF_MEMORY The memory is insufficient.
1288 result Resize(int newCapacity)
1290 result r = E_SUCCESS;
1291 __MultiHashMapEntryT< KeyType, ValueType >** newTable = new __MultiHashMapEntryT< KeyType, ValueType >*[newCapacity];
1292 TryCatch(newTable != null, r = E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
1293 for (int i = 0; i < newCapacity; i++)
1298 for (int i = 0; i < __capacity; i++)
1300 __MultiHashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i];
1301 while (null != pEntry)
1303 __MultiHashMapEntryT< KeyType, ValueType >* pNext = pEntry->pNext;
1304 int i = pEntry->hash & (newCapacity - 1);
1305 pEntry->pNext = newTable[i];
1306 newTable[i] = pEntry;
1312 __pTable = newTable;
1313 __capacity = newCapacity;
1314 __threshold = static_cast< int >(__capacity * __loadFactor);
1323 * Clears all key-value pairs in this map.
1328 for (int i = 0; i < __capacity; i++)
1330 __MultiHashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i];
1331 while (null != pEntry)
1333 __MultiHashMapEntryT< KeyType, ValueType >* pNext = pEntry->pNext;
1334 __ValueNodeT< ValueType >* pNode = pEntry->pList;
1335 while (null != pNode)
1337 __ValueNodeT< ValueType >* pTemp = pNode;
1338 pNode = pNode->pNext;
1348 __MultiHashMapEntryT< KeyType, ValueType >** __pTable;
1353 IHashCodeProviderT< KeyType >* __pProvider;
1354 IComparerT< KeyType >* __pComparer;
1355 bool __defaultConstruct;
1358 static const int DEFAULT_CAPACITY = 16;
1359 static const float DEFAULT_LOAD_FACTOR;
1361 friend class __MultiHashMapEnumeratorT< KeyType, ValueType >;
1366 // @class __ValueNodeT
1367 // @brief This class is a node for MultiHashMapT.
1370 template< class ValueType >
1376 * This is the constructor for this class.
1380 * @param[in] v An object to include in this node
1382 __ValueNodeT(const ValueType& v)
1389 * This is the destructor for this class.
1393 virtual ~__ValueNodeT(void)
1398 * Internal variable.
1402 __ValueNodeT< ValueType >* pNext;
1405 * Internal variable.
1414 // @class __MultiHashMapEntryT
1415 // @brief This class is an entry for MultiHashMapT class.
1418 template< class KeyType, class ValueType >
1419 class __MultiHashMapEntryT
1424 * This is the constructor for this class.
1428 * @param[in] keyType A key to include in this entry
1429 * @param[in] list A list of values whose key is specified @n
1430 * It cannot be @c null.
1431 * @param[in] next A pointer to the next entry
1432 * @param[in] h An hash value of the key
1434 __MultiHashMapEntryT(const KeyType& keyType, __ValueNodeT< ValueType >* list, __MultiHashMapEntryT< KeyType, ValueType >* next, int h)
1444 * This is the destructor for this class.
1448 virtual ~__MultiHashMapEntryT(void)
1453 * Internal variable.
1460 * Internal variable.
1464 __ValueNodeT< ValueType >* pList;
1467 * Internal variable.
1471 __MultiHashMapEntryT< KeyType, ValueType >* pNext;
1474 * Internal variable.
1481 * Internal variable.
1487 friend class __EntryValueEnumeratorT< KeyType, ValueType >;
1489 }; // __MultiHashMapEntryT
1492 // @class __MultiHashMapEnumeratorT
1493 // @brief This class is an implementation of IMapEnumeratorT for %MultiHashMapT.
1496 template< class KeyType, class ValueType >
1497 class __MultiHashMapEnumeratorT
1498 : public IMapEnumeratorT< KeyType, ValueType >
1503 * This is the constructor for this class.
1507 * @param[in] map A map to enumerate
1508 * @param[in] modCount The modification count to detect the change in the map
1510 __MultiHashMapEnumeratorT(const MultiHashMapT< KeyType, ValueType >& map, int modCount)
1512 , __modCount(modCount)
1520 * This is the destructor for this class.
1524 virtual ~__MultiHashMapEnumeratorT(void)
1529 * Gets the current object in the map.
1533 * @return An error code
1534 * @param[out] obj The current object
1535 * @exception E_INVALID_OPERATION Either of the following conditions has occurred: @n
1536 * - The current state of the instance prohibits the execution of the specified operation. @n
1537 * - This enumerator is currently positioned before the first element or
1538 * past the last element. @n
1539 * - The map is modified after this enumerator is created.
1540 * @exception E_SUCCESS The method is successful.
1542 result GetCurrent(MapEntryT< KeyType, ValueType >& obj) const
1544 TryReturn((__modCount == __map.__modCount), E_INVALID_OPERATION,
1545 "[%s] The source collection is modified after the creation of this enumerator.", GetErrorMessage(E_INVALID_OPERATION));
1546 TryReturn((__pEntry != null && __pNode != null), E_INVALID_OPERATION,
1547 "[%s] Invalid position(pEntry or pNode is null).", GetErrorMessage(E_INVALID_OPERATION));
1549 obj = MapEntryT< KeyType, ValueType >(__pEntry->key, __pNode->value);
1554 * Moves this enumerator to the next element of the map. @n
1555 * After the enumerator is first created or reset using the Reset() method,
1556 * the first call to this method positions the enumerator to the first element in the @c collection.
1560 * @return An error code
1561 * @exception E_SUCCESS The method is successful.
1562 * @exception E_INVALID_OPERATION The current state of the instance prohibits the execution of the specified operation, or
1563 * the map is modified after this enumerator is created.
1564 * @exception E_OUT_OF_RANGE The enumerator has passed the end of the map.
1567 result MoveNext(void)
1569 TryReturn((__modCount == __map.__modCount), E_INVALID_OPERATION,
1570 "[%s] The source collection is modified after the creation of this enumerator.", GetErrorMessage(E_INVALID_OPERATION));
1572 result r = E_SUCCESS;
1573 if ((null != __pNode) && (__pNode->pNext != null))
1575 __pNode = __pNode->pNext;
1577 else if ((null != __pEntry) && (__pEntry->pNext != null))
1579 __pEntry = __pEntry->pNext;
1580 __pNode = __pEntry->pList;
1586 if (++__index >= static_cast< int >(__map.__capacity))
1588 // Do not log the E_OUT_OF_RANGE, because it is normal or trivial in most cases.
1592 __pEntry = __map.__pTable[__index];
1593 if (null != __pEntry)
1595 __pNode = __pEntry->pList;
1605 * Positions this enumerator before the first element in the map.
1609 * @return An error code
1610 * @exception E_SUCCESS The method is successful.
1611 * @exception E_INVALID_OPERATION The current state of the instance prohibits the execution of the specified operation, or
1612 * the map is modified after this enumerator is created.
1616 TryReturn((__modCount == __map.__modCount), E_INVALID_OPERATION,
1617 "[%s] The source collection is modified after the creation of this enumerator.", GetErrorMessage(E_INVALID_OPERATION));
1626 * Gets the current key in the map.
1630 * @return An error code
1631 * @param[out] key The current key
1632 * @exception E_INVALID_OPERATION Either of the following conditions has occurred: @n
1633 * - The current state of the instance prohibits the execution of the specified operation. @n
1634 * - This enumerator is currently positioned before the first element or
1635 * past the last element. @n
1636 * - The map is modified after this enumerator is created.
1637 * @exception E_SUCCESS The method is successful.
1639 result GetKey(KeyType& key) const
1641 TryReturn((__modCount == __map.__modCount), E_INVALID_OPERATION,
1642 "[%s] The source collection is modified after the creation of this enumerator.", GetErrorMessage(E_INVALID_OPERATION));
1643 TryReturn((__pEntry != null && __pNode != null), E_INVALID_OPERATION,
1644 "[%s] Invalid position(pEntry or pNode is null).", GetErrorMessage(E_INVALID_OPERATION));
1646 key = __pEntry->key;
1651 * Gets the current value in the map.
1655 * @return An error code
1656 * @param[out] value The current value
1657 * @exception E_INVALID_OPERATION Either of the following conditions has occurred: @n
1658 * - The current state of the instance prohibits the execution of the specified operation. @n
1659 * - This enumerator is currently positioned before the first element or
1660 * past the last element. @n
1661 * - The map is modified after the enumerator is created.
1662 * @exception E_SUCCESS The method is successful.
1664 result GetValue(ValueType& value) const
1666 TryReturn((__modCount == __map.__modCount), E_INVALID_OPERATION,
1667 "[%s] The source collection is modified after the creation of this enumerator.", GetErrorMessage(E_INVALID_OPERATION));
1668 TryReturn((__pEntry != null && __pNode != null), E_INVALID_OPERATION,
1669 "[%s] Invalid position(pEntry or pNode is null).", GetErrorMessage(E_INVALID_OPERATION));
1671 value = __pNode->value;
1676 const MultiHashMapT< KeyType, ValueType >& __map;
1678 __MultiHashMapEntryT< KeyType, ValueType >* __pEntry;
1679 __ValueNodeT< ValueType >* __pNode;
1682 }; // __MultiHashMapEnumeratorT
1685 // @class __EntryValueEnumeratorT
1686 // @brief This class is an implementation of IEnumeratorT to enumerate values whose key is the same.
1689 template< class KeyType, class ValueType >
1690 class __EntryValueEnumeratorT
1691 : public IEnumeratorT< ValueType >
1696 * Initializes an instance of __EntryValueEnumeratorT with the specified parameters.
1700 * @param[in] entry An entry to enumerate
1701 * @param[in] modCount The modification count to detect the change in the entry
1703 __EntryValueEnumeratorT(const __MultiHashMapEntryT< KeyType, ValueType >& entry, int modCount)
1705 , __modCount(modCount)
1712 * This is the destructor for this class.
1716 virtual ~__EntryValueEnumeratorT(void)
1721 * Gets the current value in the entry.
1725 * @return An error code
1726 * @param[out] obj The current value
1727 * @exception E_INVALID_OPERATION Either of the following conditions has occurred: @n
1728 * - The current state of the instance prohibits the execution of the specified operation. @n
1729 * - This enumerator is currently positioned before the first element or
1730 * past the last element. @n
1731 * - The entry is modified after this enumerator is created.
1732 * @exception E_SUCCESS The method is successful.
1734 result GetCurrent(ValueType& obj) const
1736 TryReturn((__modCount == __entry.modCount), E_INVALID_OPERATION,
1737 "[%s] The source collection is modified after the creation of this enumerator.", GetErrorMessage(E_INVALID_OPERATION));
1738 TryReturn(__pNode != null, E_INVALID_OPERATION, "[%s] Invalid position(pNode is null).", GetErrorMessage(E_INVALID_OPERATION));
1740 obj = __pNode->value;
1745 * Moves this enumerator to the next element of the entry. @n
1746 * After the enumerator is first created or reset using the Reset() method,
1747 * the first call to this method positions the enumerator to the first element in the collection.
1751 * @return An error code
1752 * @exception E_SUCCESS The method is successful.
1753 * @exception E_INVALID_OPERATION The current state of the instance prohibits the execution of the specified operation, or
1754 * the entry is modified after this enumerator is created.
1755 * @exception E_OUT_OF_RANGE The enumerator has passed the end of the entry.
1758 result MoveNext(void)
1760 TryReturn((__modCount == __entry.modCount), E_INVALID_OPERATION,
1761 "[%s] The source collection is modified after the creation of this enumerator.", GetErrorMessage(E_INVALID_OPERATION));
1763 result r = E_SUCCESS;
1764 if (null == __pNode)
1766 __pNode = __entry.pList;
1767 AppAssert(null != __pNode);
1769 else if ((null != __pNode) && (__pNode->pNext != null))
1771 __pNode = __pNode->pNext;
1775 // Do not log the E_OUT_OF_RANGE, because it is normal or trivial in most cases.
1783 * Positions this enumerator before the first element in the entry.
1787 * @return An error code
1788 * @exception E_SUCCESS The method is successful.
1789 * @exception E_INVALID_OPERATION The current state of the instance prohibits the execution of the specified operation, or
1790 * the entry is modified after this enumerator is created.
1794 TryReturn((__modCount == __entry.modCount), E_INVALID_OPERATION,
1795 "[%s] The source collection is modified after the creation of this enumerator.", GetErrorMessage(E_INVALID_OPERATION));
1802 const __MultiHashMapEntryT< KeyType, ValueType >& __entry;
1804 __ValueNodeT< ValueType >* __pNode;
1806 }; // __EntryValueEnumeratorT
1809 // @class __MultiHashMapDefaultProviderT
1810 // @brief This class is an implementation of IHashCodeProviderT for HashMap.
1813 template< class KeyType >
1814 class __MultiHashMapDefaultProviderT
1815 : public IHashCodeProviderT< KeyType >
1820 * This is the default constructor for this class.
1824 __MultiHashMapDefaultProviderT(void) {}
1827 * This is the destructor for this class.
1831 virtual ~__MultiHashMapDefaultProviderT(void) {}
1836 * Gets the hash code of the specified instance.
1840 * @return The hash code
1841 * @see Tizen::Base::Object::GetHashCode()
1843 virtual int GetHashCode(const KeyType& obj) const
1848 }; // __MultiHashMapDefaultProviderT
1850 template< class KeyType, class ValueType >
1851 const float MultiHashMapT< KeyType, ValueType >::DEFAULT_LOAD_FACTOR = 0.75;
1853 }}} // Tizen::Base::Collection
1855 #endif //_FBASE_COL_MULTI_HASH_MAP_T_H_