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 the keys in this map.
605 * @return A list of all the 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 order of the keys is the same as the corresponding values in the IListT interface returned by the GetValuesN() method.
610 * The specific error code can be accessed using the GetLastResult() method.
613 virtual IListT< KeyType >* GetKeysN(void) const
617 result r = E_SUCCESS;
620 ArrayListT< KeyType >* pList = new ArrayListT< KeyType >();
621 r = pList->Construct(__count);
622 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
624 for (int i = 0; i < __capacity; i++)
626 for (__MultiHashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
628 r = pList->Add(pEntry->key);
629 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
644 * Gets a list of all the values in this map.
648 * @return A list of all the values in this map, @n
649 * else @c null if an exception occurs
650 * @exception E_SUCCESS The method is successful.
651 * @exception E_OUT_OF_MEMORY The memory is insufficient.
652 * @remarks The specific error code can be accessed using the GetLastResult() method.
655 virtual IListT< ValueType >* GetValuesN(void) const
659 result r = E_SUCCESS;
661 ArrayListT< ValueType >* pList = new ArrayListT< ValueType >();
662 r = pList->Construct(__count);
663 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
665 for (int i = 0; i < __capacity; i++)
667 for (__MultiHashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
669 for (__ValueNodeT< ValueType >* pNode = pEntry->pList; null != pNode; pNode = pNode->pNext)
671 r = pList->Add(pNode->value);
672 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
687 * Removes all the values for the specified key.
691 * @return An error code
692 * @param[in] key The key to remove
693 * @exception E_SUCCESS The method is successful.
694 * @exception E_INVALID_ARG The specified input parameter is invalid, or
695 * the comparer has failed to compare the keys.
696 * @exception E_OBJ_NOT_FOUND The specified @c key is not found in the map.
699 virtual result Remove(const KeyType& key)
701 result r = E_OBJ_NOT_FOUND;
702 int hash = Hash(key);
703 int i = hash & (__capacity - 1);
705 __MultiHashMapEntryT< KeyType, ValueType >* pPrev = __pTable[i];
706 for (__MultiHashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
708 if (hash == pEntry->hash)
711 r = __pComparer->Compare(key, pEntry->key, cmpResult);
712 TryReturn(r == E_SUCCESS, E_INVALID_ARG, "[%s] Propagating.", GetErrorMessage(r));
721 __pTable[i] = pEntry->pNext;
725 pPrev->pNext = pEntry->pNext;
728 __ValueNodeT< ValueType >* pNode = pEntry->pList;
729 while (null != pNode)
731 __ValueNodeT< ValueType >* pTemp = pNode;
732 pNode = pNode->pNext;
748 * Removes the specified value associated with the specified key. @n
749 * The key is also removed if there is no value associated with it.
753 * @return An error code
754 * @param[in] key The key whose mapping is to remove from the map
755 * @param[in] value The value to remove
756 * @exception E_SUCCESS The method is successful.
757 * @exception E_INVALID_ARG A specified input parameter is invalid, or
758 * the comparer has failed to compare the keys.
759 * @exception E_OBJ_NOT_FOUND The specified @c key and @c value pair is not found in the map.
762 virtual result Remove(const KeyType& key, const ValueType& value)
764 result r = E_OBJ_NOT_FOUND;
765 int hash = Hash(key);
766 int i = hash & (__capacity - 1);
768 __MultiHashMapEntryT< KeyType, ValueType >* pPrev = __pTable[i];
769 for (__MultiHashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
771 if (hash == pEntry->hash)
774 r = __pComparer->Compare(key, pEntry->key, cmpResult);
775 TryReturn(r == E_SUCCESS, E_INVALID_ARG, "[%s] Propagating.", GetErrorMessage(r));
780 __ValueNodeT< ValueType >* pPrevNode = pEntry->pList;
781 for (__ValueNodeT< ValueType >* pNode = pEntry->pList; null != pNode; pNode = pNode->pNext)
783 if (value == pNode->value)
787 if (pPrevNode == pNode)
789 pEntry->pList = pNode->pNext;
793 pPrevNode->pNext = pNode->pNext;
800 if (null == pEntry->pList)
804 __pTable[i] = pEntry->pNext;
808 pPrev->pNext = pEntry->pNext;
830 * Removes all key-value pairs in this map.
834 virtual void RemoveAll(void)
845 * Replaces the value associated with the key with the specified @c newValue.
849 * @return An error code
850 * @param[in] key A key
851 * @param[in] value A value to replace
852 * @param[in] newValue A new value to replace the existing value
853 * @exception E_SUCCESS The method is successful.
854 * @exception E_INVALID_ARG A specified input parameter is invalid, or
855 * the comparer has failed to compare the keys.
856 * @exception E_OBJ_NOT_FOUND The specified @c key and @c value pair is not found in the map.
857 * @remarks To add a new key-value pair, use the Add() method.
861 virtual result SetValue(const KeyType& key, const ValueType& value, const ValueType& newValue)
863 result r = E_SUCCESS;
864 int hash = Hash(key);
865 int i = hash & (__capacity - 1);
866 __ValueNodeT< ValueType >* pNode = null;
867 bool pairExist = false;
868 __MultiHashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i];
869 while (null != pEntry)
871 if (hash == pEntry->hash)
874 r = __pComparer->Compare(key, pEntry->key, cmpResult);
875 TryReturn(r == E_SUCCESS, E_INVALID_ARG, "[%s] Propagating.", GetErrorMessage(r));
879 pNode = pEntry->pList;
882 if (pNode->value == value)
885 pNode->value = newValue;
889 if (pNode->pNext != null)
891 pNode = pNode->pNext;
902 pEntry = pEntry->pNext;
914 * Gets the number of values currently stored in this map.
918 * @return The number of values currently stored in this map
920 virtual int GetCount(void) const
926 * Gets the number of values whose keys match the specified key.
930 * @return An error code
931 * @param[in] key A key to locate
932 * @param[out] count The number of values whose key is @c key
933 * @exception E_SUCCESS The method is successful.
934 * @exception E_INVALID_ARG A specified input parameter is invalid, or
935 * the comparer has failed to compare the keys.
936 * @exception E_OBJ_NOT_FOUND The specified @c key is not found in the map.
938 virtual result GetCount(const KeyType& key, int& count) const
940 result r = E_OBJ_NOT_FOUND;
941 int hash = Hash(key);
942 int i = hash & (__capacity - 1);
944 for (__MultiHashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
946 if (hash == pEntry->hash)
949 r = __pComparer->Compare(key, pEntry->key, cmpResult);
950 TryReturn(r == E_SUCCESS, E_INVALID_ARG, "[%s] Propagating.", GetErrorMessage(r));
955 for (__ValueNodeT< ValueType >* pNode = pEntry->pList; null != pNode; pNode = pNode->pNext)
972 * Checks whether the map contains the specified key and value.
976 * @return An error code
977 * @param[in] key The key to locate
978 * @param[in] value The value to locate
979 * @param[out] out Set to @c true if the map contains the specified key and value pair, @n
981 * @exception E_SUCCESS The method is successful.
982 * @exception E_INVALID_ARG The current state of the instance prohibits the execution of the specified operation, or
983 * the comparer has failed to compare the keys.
985 * @see ContainsValue()
987 virtual result Contains(const KeyType& key, const ValueType& value, bool& out) const
991 result r = E_SUCCESS;
992 int hash = Hash(key);
993 int i = hash & (__capacity - 1);
995 for (__MultiHashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
997 if (hash == pEntry->hash)
1000 r = __pComparer->Compare(key, pEntry->key, cmpResult);
1003 AppLogException("[%s] Propagating.", GetErrorMessage(r));
1005 return E_INVALID_ARG;
1010 for (__ValueNodeT< ValueType >* pNode = pEntry->pList; null != pNode; pNode = pNode->pNext)
1012 if (value == pNode->value)
1028 * Checks whether the map contains the specified key.
1032 * @return An error code
1033 * @param[in] key The key to locate
1034 * @param[out] out Set to @c true if the map contains the specified key, @n
1036 * @exception E_SUCCESS The method is successful.
1037 * @exception E_INVALID_ARG A specified input parameter is invalid, or
1038 * the comparer has failed to compare the keys.
1039 * @see ContainsValue()
1042 virtual result ContainsKey(const KeyType& key, bool& out) const
1045 result r = E_SUCCESS;
1046 int hash = Hash(key);
1047 int i = hash & (__capacity - 1);
1049 for (__MultiHashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
1051 if (hash == pEntry->hash)
1054 r = __pComparer->Compare(key, pEntry->key, cmpResult);
1057 AppLogException("[%s] Propagating.", GetErrorMessage(r));
1059 return E_INVALID_ARG;
1073 * Checks whether the map contains the specified value.
1077 * @return @c true if the map contains the specified value, @n
1079 * @param[in] value The value to locate
1081 * @see ContainsKey()
1084 virtual bool ContainsValue(const ValueType& value) const
1087 for (int i = 0; i < __capacity; i++)
1089 for (__MultiHashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
1091 for (__ValueNodeT< ValueType >* pNode = pEntry->pList; null != pNode; pNode = pNode->pNext)
1093 if (value == pNode->value)
1112 * Compares the specified instance to the current instance for equality.
1116 * @return @c true if the two instances are equal, @n
1118 * @param[in] obj The object to compare with the current instance
1119 * @remarks This method returns @c true only if the specified object is also an instance of the %MultiHashMapT class,
1120 * both maps have the same number of elements, and both maps contain the same elements.
1122 virtual bool Equals(const Object& obj) const
1124 result r = E_SUCCESS;
1127 const MultiHashMapT< KeyType, ValueType >* other = dynamic_cast< const MultiHashMapT< KeyType, ValueType >* >(&obj);
1128 if (null == other) // obj is not MultiHashMapT<KeyType, ValueType>
1132 else if (other == this)
1136 else if (__count != other->__count)
1142 for (int i = 0; i < __capacity; i++)
1144 for (__MultiHashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
1146 for (__ValueNodeT< ValueType >* pNode = pEntry->pList; null != pNode; pNode = pNode->pNext)
1148 r = other->Contains(pEntry->key, pNode->value, out);
1166 * Gets the hash value of the current instance.
1170 * @return The hash value of the current instance
1171 * @remarks The two Tizen::Base::Object::Equals() instances must return the same hash value. For better performance, @n
1172 * the used hash function must generate a random distribution for all inputs.
1174 virtual int GetHashCode(void) const
1178 for (int i = 0; i < __capacity; i++)
1180 for (__MultiHashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
1182 for (__ValueNodeT< ValueType >* pNode = pEntry->pList; null != pNode; pNode = pNode->pNext)
1184 hash += reinterpret_cast< int >(&pNode->value);
1186 hash += reinterpret_cast< int >(&pEntry->key);
1193 * The implementation of this copy constructor is intentionally blank and declared as private to prohibit copying of objects.
1195 * @param[in] map An instance of %MultiHashMapT to initialize the current instance
1197 MultiHashMapT(const MultiHashMapT< KeyType, ValueType >& map);
1200 * The implementation of this copy assignment operator is intentionally blank and declared as private to prohibit copying of objects.
1202 * @param[in] map An instance of %MultiHashMapT
1204 MultiHashMapT< KeyType, ValueType >& operator =(const MultiHashMapT< KeyType, ValueType >& map);
1207 * Copies all the pairs from the specified map to this map.
1209 * @return An error code
1210 * @param[in] map The map to copy
1211 * @exception E_SUCCESS The method is successful.
1212 * @exception E_INVALID_OPERATION The current state of the instance prohibits the execution of the specified operation. @n
1213 * The @c map is modified during the operation of this method.
1215 result AddAll(const IMultiMapT< KeyType, ValueType >& map)
1217 result r = E_SUCCESS;
1219 IMultiMapT< KeyType, ValueType >* pMap = const_cast< IMultiMapT< KeyType, ValueType >* >(&map);
1220 IMapEnumeratorT< KeyType, ValueType >* pMapEnum = pMap->GetMapEnumeratorN();
1222 TryCatch(pMapEnum != null, r = GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
1229 r = pMapEnum->MoveNext();
1230 // enumerator is reached to the end of collection
1231 if (E_OUT_OF_RANGE == r)
1236 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
1238 r = pMapEnum->GetKey(key);
1239 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
1241 r = pMapEnum->GetValue(value);
1242 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
1244 r = Add(key, value);
1245 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
1248 if (null != pMapEnum)
1255 if (null != pMapEnum)
1263 * Gets a hash value for the specified object.
1265 * @return The hash value for the specified object
1266 * @param[in] obj The object to get hash value
1268 int Hash(const KeyType& obj) const
1270 int h = __pProvider->GetHashCode(obj);
1272 h ^= (h >> 20) ^ (h >> 12);
1274 return h ^ (h >> 7) ^ (h >> 4);
1278 * Resizes the contents of this map into a new array with a
1279 * larger capacity. @n
1280 * This method is called automatically when the
1281 * number of keys in this map reaches its threshold.
1283 * @return An error code
1284 * @param[in] newCapacity The new capacity @n
1285 * It must be a power of 2 and must be greater than current capacity.
1286 * @exception E_SUCCESS The method is successful.
1287 * @exception E_OUT_OF_MEMORY The memory is insufficient.
1289 result Resize(int newCapacity)
1291 result r = E_SUCCESS;
1292 __MultiHashMapEntryT< KeyType, ValueType >** newTable = new __MultiHashMapEntryT< KeyType, ValueType >*[newCapacity];
1293 TryCatch(newTable != null, r = E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
1294 for (int i = 0; i < newCapacity; i++)
1299 for (int i = 0; i < __capacity; i++)
1301 __MultiHashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i];
1302 while (null != pEntry)
1304 __MultiHashMapEntryT< KeyType, ValueType >* pNext = pEntry->pNext;
1305 int i = pEntry->hash & (newCapacity - 1);
1306 pEntry->pNext = newTable[i];
1307 newTable[i] = pEntry;
1313 __pTable = newTable;
1314 __capacity = newCapacity;
1315 __threshold = static_cast< int >(__capacity * __loadFactor);
1324 * Clears all key-value pairs in this map.
1329 for (int i = 0; i < __capacity; i++)
1331 __MultiHashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i];
1332 while (null != pEntry)
1334 __MultiHashMapEntryT< KeyType, ValueType >* pNext = pEntry->pNext;
1335 __ValueNodeT< ValueType >* pNode = pEntry->pList;
1336 while (null != pNode)
1338 __ValueNodeT< ValueType >* pTemp = pNode;
1339 pNode = pNode->pNext;
1349 __MultiHashMapEntryT< KeyType, ValueType >** __pTable;
1354 IHashCodeProviderT< KeyType >* __pProvider;
1355 IComparerT< KeyType >* __pComparer;
1356 bool __defaultConstruct;
1359 static const int DEFAULT_CAPACITY = 16;
1360 static const float DEFAULT_LOAD_FACTOR;
1362 friend class __MultiHashMapEnumeratorT< KeyType, ValueType >;
1367 // @class __ValueNodeT
1368 // @brief This class is a node for MultiHashMapT.
1371 template< class ValueType >
1377 * This is the constructor for this class.
1381 * @param[in] v An object to include in this node
1383 __ValueNodeT(const ValueType& v)
1390 * This is the destructor for this class.
1394 virtual ~__ValueNodeT(void)
1399 * Internal variable.
1403 __ValueNodeT< ValueType >* pNext;
1406 * Internal variable.
1415 // @class __MultiHashMapEntryT
1416 // @brief This class is an entry for MultiHashMapT class.
1419 template< class KeyType, class ValueType >
1420 class __MultiHashMapEntryT
1425 * This is the constructor for this class.
1429 * @param[in] keyType A key to include in this entry
1430 * @param[in] list A list of values whose key is specified @n
1431 * It cannot be @c null.
1432 * @param[in] next A pointer to the next entry
1433 * @param[in] h An hash value of the key
1435 __MultiHashMapEntryT(const KeyType& keyType, __ValueNodeT< ValueType >* list, __MultiHashMapEntryT< KeyType, ValueType >* next, int h)
1445 * This is the destructor for this class.
1449 virtual ~__MultiHashMapEntryT(void)
1454 * Internal variable.
1461 * Internal variable.
1465 __ValueNodeT< ValueType >* pList;
1468 * Internal variable.
1472 __MultiHashMapEntryT< KeyType, ValueType >* pNext;
1475 * Internal variable.
1482 * Internal variable.
1488 friend class __EntryValueEnumeratorT< KeyType, ValueType >;
1490 }; // __MultiHashMapEntryT
1493 // @class __MultiHashMapEnumeratorT
1494 // @brief This class is an implementation of IMapEnumeratorT for %MultiHashMapT.
1497 template< class KeyType, class ValueType >
1498 class __MultiHashMapEnumeratorT
1499 : public IMapEnumeratorT< KeyType, ValueType >
1504 * This is the constructor for this class.
1508 * @param[in] map A map to enumerate
1509 * @param[in] modCount The modification count to detect the change in the map
1511 __MultiHashMapEnumeratorT(const MultiHashMapT< KeyType, ValueType >& map, int modCount)
1513 , __modCount(modCount)
1521 * This is the destructor for this class.
1525 virtual ~__MultiHashMapEnumeratorT(void)
1530 * Gets the current object in the map.
1534 * @return An error code
1535 * @param[out] obj The current object
1536 * @exception E_INVALID_OPERATION Either of the following conditions has occurred: @n
1537 * - The current state of the instance prohibits the execution of the specified operation. @n
1538 * - This enumerator is currently positioned before the first element or
1539 * past the last element. @n
1540 * - The map is modified after this enumerator is created.
1541 * @exception E_SUCCESS The method is successful.
1543 result GetCurrent(MapEntryT< KeyType, ValueType >& obj) const
1545 TryReturn((__modCount == __map.__modCount), E_INVALID_OPERATION,
1546 "[%s] The source collection is modified after the creation of this enumerator.", GetErrorMessage(E_INVALID_OPERATION));
1547 TryReturn((__pEntry != null && __pNode != null), E_INVALID_OPERATION,
1548 "[%s] Invalid position(pEntry or pNode is null).", GetErrorMessage(E_INVALID_OPERATION));
1550 obj = MapEntryT< KeyType, ValueType >(__pEntry->key, __pNode->value);
1555 * Moves this enumerator to the next element of the map. @n
1556 * After the enumerator is first created or reset using the Reset() method,
1557 * the first call to this method positions the enumerator to the first element in the @c collection.
1561 * @return An error code
1562 * @exception E_SUCCESS The method is successful.
1563 * @exception E_INVALID_OPERATION The current state of the instance prohibits the execution of the specified operation, or
1564 * the map is modified after this enumerator is created.
1565 * @exception E_OUT_OF_RANGE The enumerator has passed the end of the map.
1568 result MoveNext(void)
1570 TryReturn((__modCount == __map.__modCount), E_INVALID_OPERATION,
1571 "[%s] The source collection is modified after the creation of this enumerator.", GetErrorMessage(E_INVALID_OPERATION));
1573 result r = E_SUCCESS;
1574 if ((null != __pNode) && (__pNode->pNext != null))
1576 __pNode = __pNode->pNext;
1578 else if ((null != __pEntry) && (__pEntry->pNext != null))
1580 __pEntry = __pEntry->pNext;
1581 __pNode = __pEntry->pList;
1587 if (++__index >= static_cast< int >(__map.__capacity))
1589 // Do not log the E_OUT_OF_RANGE, because it is normal or trivial in most cases.
1593 __pEntry = __map.__pTable[__index];
1594 if (null != __pEntry)
1596 __pNode = __pEntry->pList;
1606 * Positions this enumerator before the first element in the map.
1610 * @return An error code
1611 * @exception E_SUCCESS The method is successful.
1612 * @exception E_INVALID_OPERATION The current state of the instance prohibits the execution of the specified operation, or
1613 * the map is modified after this enumerator is created.
1617 TryReturn((__modCount == __map.__modCount), E_INVALID_OPERATION,
1618 "[%s] The source collection is modified after the creation of this enumerator.", GetErrorMessage(E_INVALID_OPERATION));
1627 * Gets the current key in the map.
1631 * @return An error code
1632 * @param[out] key The current key
1633 * @exception E_INVALID_OPERATION Either of the following conditions has occurred: @n
1634 * - The current state of the instance prohibits the execution of the specified operation. @n
1635 * - This enumerator is currently positioned before the first element or
1636 * past the last element. @n
1637 * - The map is modified after this enumerator is created.
1638 * @exception E_SUCCESS The method is successful.
1640 result GetKey(KeyType& key) const
1642 TryReturn((__modCount == __map.__modCount), E_INVALID_OPERATION,
1643 "[%s] The source collection is modified after the creation of this enumerator.", GetErrorMessage(E_INVALID_OPERATION));
1644 TryReturn((__pEntry != null && __pNode != null), E_INVALID_OPERATION,
1645 "[%s] Invalid position(pEntry or pNode is null).", GetErrorMessage(E_INVALID_OPERATION));
1647 key = __pEntry->key;
1652 * Gets the current value in the map.
1656 * @return An error code
1657 * @param[out] value The current value
1658 * @exception E_INVALID_OPERATION Either of the following conditions has occurred: @n
1659 * - The current state of the instance prohibits the execution of the specified operation. @n
1660 * - This enumerator is currently positioned before the first element or
1661 * past the last element. @n
1662 * - The map is modified after the enumerator is created.
1663 * @exception E_SUCCESS The method is successful.
1665 result GetValue(ValueType& value) const
1667 TryReturn((__modCount == __map.__modCount), E_INVALID_OPERATION,
1668 "[%s] The source collection is modified after the creation of this enumerator.", GetErrorMessage(E_INVALID_OPERATION));
1669 TryReturn((__pEntry != null && __pNode != null), E_INVALID_OPERATION,
1670 "[%s] Invalid position(pEntry or pNode is null).", GetErrorMessage(E_INVALID_OPERATION));
1672 value = __pNode->value;
1677 const MultiHashMapT< KeyType, ValueType >& __map;
1679 __MultiHashMapEntryT< KeyType, ValueType >* __pEntry;
1680 __ValueNodeT< ValueType >* __pNode;
1683 }; // __MultiHashMapEnumeratorT
1686 // @class __EntryValueEnumeratorT
1687 // @brief This class is an implementation of IEnumeratorT to enumerate values whose key is the same.
1690 template< class KeyType, class ValueType >
1691 class __EntryValueEnumeratorT
1692 : public IEnumeratorT< ValueType >
1697 * Initializes an instance of __EntryValueEnumeratorT with the specified parameters.
1701 * @param[in] entry An entry to enumerate
1702 * @param[in] modCount The modification count to detect the change in the entry
1704 __EntryValueEnumeratorT(const __MultiHashMapEntryT< KeyType, ValueType >& entry, int modCount)
1706 , __modCount(modCount)
1713 * This is the destructor for this class.
1717 virtual ~__EntryValueEnumeratorT(void)
1722 * Gets the current value in the entry.
1726 * @return An error code
1727 * @param[out] obj The current value
1728 * @exception E_INVALID_OPERATION Either of the following conditions has occurred: @n
1729 * - The current state of the instance prohibits the execution of the specified operation. @n
1730 * - This enumerator is currently positioned before the first element or
1731 * past the last element. @n
1732 * - The entry is modified after this enumerator is created.
1733 * @exception E_SUCCESS The method is successful.
1735 result GetCurrent(ValueType& obj) const
1737 TryReturn((__modCount == __entry.modCount), E_INVALID_OPERATION,
1738 "[%s] The source collection is modified after the creation of this enumerator.", GetErrorMessage(E_INVALID_OPERATION));
1739 TryReturn(__pNode != null, E_INVALID_OPERATION, "[%s] Invalid position(pNode is null).", GetErrorMessage(E_INVALID_OPERATION));
1741 obj = __pNode->value;
1746 * Moves this enumerator to the next element of the entry. @n
1747 * After the enumerator is first created or reset using the Reset() method,
1748 * the first call to this method positions the enumerator to the first element in the collection.
1752 * @return An error code
1753 * @exception E_SUCCESS The method is successful.
1754 * @exception E_INVALID_OPERATION The current state of the instance prohibits the execution of the specified operation, or
1755 * the entry is modified after this enumerator is created.
1756 * @exception E_OUT_OF_RANGE The enumerator has passed the end of the entry.
1759 result MoveNext(void)
1761 TryReturn((__modCount == __entry.modCount), E_INVALID_OPERATION,
1762 "[%s] The source collection is modified after the creation of this enumerator.", GetErrorMessage(E_INVALID_OPERATION));
1764 result r = E_SUCCESS;
1765 if (null == __pNode)
1767 __pNode = __entry.pList;
1768 AppAssert(null != __pNode);
1770 else if ((null != __pNode) && (__pNode->pNext != null))
1772 __pNode = __pNode->pNext;
1776 // Do not log the E_OUT_OF_RANGE, because it is normal or trivial in most cases.
1784 * Positions this enumerator before the first element in the entry.
1788 * @return An error code
1789 * @exception E_SUCCESS The method is successful.
1790 * @exception E_INVALID_OPERATION The current state of the instance prohibits the execution of the specified operation, or
1791 * the entry is modified after this enumerator is created.
1795 TryReturn((__modCount == __entry.modCount), E_INVALID_OPERATION,
1796 "[%s] The source collection is modified after the creation of this enumerator.", GetErrorMessage(E_INVALID_OPERATION));
1803 const __MultiHashMapEntryT< KeyType, ValueType >& __entry;
1805 __ValueNodeT< ValueType >* __pNode;
1807 }; // __EntryValueEnumeratorT
1810 // @class __MultiHashMapDefaultProviderT
1811 // @brief This class is an implementation of IHashCodeProviderT for HashMap.
1814 template< class KeyType >
1815 class __MultiHashMapDefaultProviderT
1816 : public IHashCodeProviderT< KeyType >
1821 * This is the default constructor for this class.
1825 __MultiHashMapDefaultProviderT(void) {}
1828 * This is the destructor for this class.
1832 virtual ~__MultiHashMapDefaultProviderT(void) {}
1837 * Gets the hash code of the specified instance.
1841 * @return The hash code
1842 * @see Tizen::Base::Object::GetHashCode()
1844 virtual int GetHashCode(const KeyType& obj) const
1849 }; // __MultiHashMapDefaultProviderT
1851 template< class KeyType, class ValueType >
1852 const float MultiHashMapT< KeyType, ValueType >::DEFAULT_LOAD_FACTOR = 0.75;
1854 }}} // Tizen::Base::Collection
1856 #endif //_FBASE_COL_MULTI_HASH_MAP_T_H_