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 FBaseColHashMapT.h
19 * @brief This is the header file for the %HashMapT class.
21 * This header file contains the declarations of the %HashMapT class.
23 #ifndef _FBASE_COL_HASH_MAP_T_H_
24 #define _FBASE_COL_HASH_MAP_T_H_
26 #include <FBaseObject.h>
27 #include <FBaseResult.h>
28 #include <FBaseColIComparerT.h>
29 #include <FBaseColIHashCodeProviderT.h>
30 #include <FBaseColIListT.h>
31 #include <FBaseColIMapT.h>
32 #include <FBaseColArrayListT.h>
33 #include <FBaseColMapEntryT.h>
34 #include <FBaseComparerT.h>
35 #include <FBaseFloat.h>
37 namespace Tizen { namespace Base { namespace Collection
40 template< class KeyType, class ValueType > class __HashMapEntryT;
41 template< class KeyType, class ValueType > class __HashMapEnumeratorT;
42 template< class KeyType > class __HashMapDefaultProviderT;
46 * @brief This class provides a template-based collection of associated keys and values
47 * that are organized based on the hash code of the key.
51 * The %HashMapT class provides a template-based collection of associated keys and values
52 * that are organized based on the hash code of the key.
53 * It contains unique keys and each key maps to one single value.
54 * The key and value cannot be a @c null reference. Several methods in the %HashMapT class need the assignment (=) operators of the KeyType and the ValueType.
56 * For more information on the class features, see <a href="../org.tizen.native.appprogramming/html/guide/base/hashmap_multihashmap.htm">HashMap and MultiHashMap</a>.
58 * The following example demonstrates how to use the %HashMapT class.
63 * using namespace Tizen::Base;
64 * using namespace Tizen::Base::Collection;
67 * MyClass::HashMapTSample(void)
69 * HashMapT< int, int > map;
71 * // Constructs a %HashMapT instance with default capacity, load factor, hash code provider, and comparer
74 * map.Add(1, 100); // map.GetCount() : 1
75 * map.Add(2, 200); // map.GetCount() : 2
76 * map.Add(3, 300); // map.GetCount() : 3
81 * // Gets a value with the specified key
83 * map.GetValue(key, value); // value : 100
85 * // Removes the value with the specified key
88 * // Uses an enumerator to access elements in the map
89 * IMapEnumeratorT< int, int >* pMapEnum = map.GetMapEnumeratorN();
90 * while (pMapEnum->MoveNext() == E_SUCCESS)
92 * pMapEnum->GetKey(key);
93 * pMapEnum->GetValue(value);
100 template< class KeyType, class ValueType >
102 : public IMapT< KeyType, ValueType >
107 * The object is not fully constructed after this constructor is called. For full construction, @n
108 * the Construct() method must be called right after calling this constructor.
120 , __defaultConstruct(false)
126 * This destructor overrides Tizen::Base::Object::~Object().
130 virtual ~HashMapT(void)
132 if (null != __pTable)
138 if (__defaultConstruct)
147 * Initializes this instance of %HashMapT with the specified parameters.
151 * @return An error code
152 * @param[in] capacity The initial capacity
153 * @param[in] loadFactor The maximum ratio of elements to buckets
154 * @exception E_SUCCESS The method is successful.
155 * @exception E_INVALID_ARG Either of the following conditions has occurred:
156 * - A specified input parameter is invalid.
157 * - The specified @c capacity or the specified @c loadFactor is negative.
158 * @remarks To work properly, the key type must be of a primitive number type.
161 result Construct(int capacity = 16, float loadFactor = 0.75)
163 TryReturn(capacity >= 0, E_INVALID_ARG, "[%s] The capacity(%d) MUST be greater than or equal to 0.", GetErrorMessage(E_INVALID_ARG), capacity);
164 TryReturn(loadFactor >= 0, E_INVALID_ARG, "[%s] The loadFactor(%f) MUST be greater than or equal to 0.0.", GetErrorMessage(E_INVALID_ARG), loadFactor);
166 result r = E_SUCCESS;
170 __capacity = DEFAULT_CAPACITY;
175 while (__capacity < capacity)
181 if (Float::Compare(loadFactor, 0) == 0)
183 __loadFactor = DEFAULT_LOAD_FACTOR;
187 __loadFactor = loadFactor;
190 __threshold = static_cast< int >(__capacity * __loadFactor);
192 __pProvider = new __HashMapDefaultProviderT< KeyType >();
193 TryCatch(__pProvider != null, r = E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
195 __pComparer = new Tizen::Base::ComparerT< KeyType >();
196 TryCatch(__pComparer != null, r = E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
198 __defaultConstruct = true;
200 __pTable = new __HashMapEntryT< KeyType, ValueType >*[__capacity];
201 TryCatch(__pTable != null, r = E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
203 memset(__pTable, null, sizeof(__HashMapEntryT< KeyType, ValueType >*) * __capacity);
216 * Initializes this instance of %HashMapT by copying the elements of the specified @c map.
220 * @return An error code
221 * @param[in] map The map to copy
222 * @param[in] loadFactor The maximum ratio of elements to buckets
223 * @exception E_SUCCESS The method is successful.
224 * @exception E_INVALID_ARG Either of the following conditions has occurred:
225 * - A specified input parameter is invalid.
226 * - The specified @c loadFactor is negative.
227 * @exception E_INVALID_OPERATION Either of the following conditions has occurred:
228 * - The current state of the instance prohibits the execution of the specified operation.
229 * - The specified @c map is modified during the operation of this method.
232 result Construct(const IMapT< KeyType, ValueType >& map, float loadFactor = 0.75)
234 TryReturn(loadFactor >= 0, E_INVALID_ARG, "[%s] The loadFactor(%f) MUST be greater than or equal to 0.0.", GetErrorMessage(E_INVALID_ARG), loadFactor);
236 result r = E_SUCCESS;
238 if (Float::Compare(loadFactor, 0) == 0)
240 loadFactor = DEFAULT_LOAD_FACTOR;
243 int capacity = static_cast< int >(map.GetCount() / loadFactor) + 1;
245 r = Construct(capacity, loadFactor);
246 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
249 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
270 * Initializes this instance of the empty %HashMapT, with the specified initial capacity, load factor, hash code provider, and comparer.
274 * @return An error code
275 * @param[in] capacity The initial capacity @n
276 * If it is @c 0, the default capacity (16) is used.
277 * @param[in] loadFactor The maximum ratio of the elements to buckets @n
278 * If it is @c 0, the default load factor (0.75) is used.
279 * @param[in] provider An instance of the IHashCodeProviderT-derived class that supplies the hash codes
280 * for all the keys in this map
281 * @param[in] comparer An instance of the IComparerT-derived class to use when comparing the keys
282 * @exception E_SUCCESS The method is successful.
283 * @exception E_INVALID_ARG Either of the following conditions has occurred:
284 * - A specified input parameter is invalid.
285 * - The specified @c capacity is negative.
286 * - The specified @c loadFactor is negative.
287 * @remarks The instances of the hash code provider and the comparer are not deallocated later from this map.
290 result Construct(int capacity, float loadFactor, const IHashCodeProviderT< KeyType >& provider,
291 const IComparerT< KeyType >& comparer)
293 TryReturn(capacity >= 0, E_INVALID_ARG, "[%s] The capacity(%d) MUST be greater than or equal to 0.", GetErrorMessage(E_INVALID_ARG), capacity);
294 TryReturn(loadFactor >= 0, E_INVALID_ARG, "[%s] The loadFactor(%f) MUST be greater than or equal to 0.0.", GetErrorMessage(E_INVALID_ARG), loadFactor);
296 result r = E_SUCCESS;
300 __capacity = DEFAULT_CAPACITY;
305 while (__capacity < capacity)
311 if (Float::Compare(loadFactor, 0) == 0)
313 __loadFactor = DEFAULT_LOAD_FACTOR;
317 __loadFactor = loadFactor;
320 __threshold = static_cast< int >(__capacity * __loadFactor);
322 __pProvider = const_cast< IHashCodeProviderT< KeyType >* >(&provider);
324 __pComparer = const_cast< IComparerT< KeyType >* >(&comparer);
326 __pTable = new __HashMapEntryT< KeyType, ValueType >*[__capacity];
327 TryCatch(__pTable != null, r = E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
329 memset(__pTable, null, sizeof(__HashMapEntryT< KeyType, ValueType >*) * __capacity);
342 * Initializes this instance of %HashMapT by copying the elements of the specified @c map,
343 * with the specified load factor, hash code provider, and comparer.
347 * @return An error code
348 * @param[in] map The map to copy
349 * @param[in] loadFactor The maximum ratio of elements to buckets @n
350 * If it is @c 0, the default load factor (0.75) is used.
351 * @param[in] provider An instance of the IHashCodeProviderT-derived class that supplies the hash codes
352 * for all the keys in this map
353 * @param[in] comparer An instance of the IComparerT-derived class to use when comparing the keys
354 * @exception E_SUCCESS The method is successful.
355 * @exception E_INVALID_ARG Either of the following conditions has occurred:
356 * - A specified input parameter is invalid.
357 * - The specified @c loadFactor is negative.
358 * - Either the specified @c provider or the specified @c comparer is @c null.
359 * @exception E_INVALID_OPERATION Either of the following conditions has occurred:
360 * - The current state of the instance prohibits the execution of the specified operation.
361 * - The specified @c map is modified during the operation of this method.
362 * @remarks The instances of the hash code provider and the comparer are not deallocated later from this map.
365 result Construct(const IMapT< KeyType, ValueType >& map, float loadFactor, const IHashCodeProviderT< KeyType >& provider,
366 const IComparerT< KeyType >& comparer)
368 TryReturn((loadFactor >= 0), E_INVALID_ARG, "[%s] The loadFactor(%f) MUST be greater than or equal to 0.0.", GetErrorMessage(E_INVALID_ARG), loadFactor);
370 result r = E_SUCCESS;
371 if (Float::Compare(loadFactor, 0) == 0)
373 loadFactor = DEFAULT_LOAD_FACTOR;
376 int capacity = static_cast< int >(map.GetCount() / loadFactor) + 1;
377 r = Construct(capacity, loadFactor, provider, comparer);
378 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
381 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
398 * Adds the specified key-value pair to the map.
402 * @return An error code
403 * @param[in] key The key of the value to add
404 * @param[in] value The value to add
405 * @exception E_SUCCESS The method is successful.
406 * @exception E_INVALID_ARG Either of the following conditions has occurred:
407 * - A specified input parameter is invalid.
408 * - The comparer has failed to compare the keys.
409 * @exception E_OBJ_ALREADY_EXIST The specified @c key already exists.
412 virtual result Add(const KeyType& key, const ValueType& value)
414 __HashMapEntryT< KeyType, ValueType >* pNewEntry;
416 result r = E_SUCCESS;
417 int hash = Hash(key);
418 int i = hash & (__capacity - 1);
421 r = ContainsKey(key, out);
422 TryReturn((!out), E_OBJ_ALREADY_EXIST, "[%s] The key is already exist in this collection.", GetErrorMessage(E_OBJ_ALREADY_EXIST));
423 TryReturn(r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
426 pNewEntry = new __HashMapEntryT< KeyType, ValueType >(key, value, __pTable[i], hash);
427 TryReturn(pNewEntry != null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
428 __pTable[i] = pNewEntry;
431 if (__count++ >= __threshold)
433 r = Resize(__capacity * 2);
434 TryReturn(r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
441 * Gets the elements of the map through an instance of the IMapEnumeratorT-derived class.
445 * @return An instance of the IMapEnumeratorT-derived class, @n
446 * else @c null if an exception occurs
447 * @exception E_SUCCESS The method is successful.
448 * @exception E_OUT_OF_MEMORY The memory is insufficient.
449 * @remarks The specific error code can be accessed using the GetLastResult() method.
450 * @see Tizen::Base::Collection::IEnumerator
451 * @see Tizen::Base::Collection::IMapEnumerator
453 virtual IEnumeratorT< MapEntryT< KeyType, ValueType > >* GetEnumeratorN(void) const
455 result r = E_SUCCESS;
457 __HashMapEnumeratorT< KeyType, ValueType >* pEnum = new __HashMapEnumeratorT< KeyType, ValueType >(*this, __modCount);
458 TryCatch(pEnum != null, r = E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
460 SetLastResult(E_SUCCESS);
469 * Gets the elements of the map through an instance of the IMapEnumeratorT class.
473 * @return An instance of the IMapEnumeratorT class, @n
474 * else @c null if an exception occurs
475 * @exception E_SUCCESS The method is successful.
476 * @exception E_OUT_OF_MEMORY The memory is insufficient.
477 * @remarks The specific error code can be accessed using the GetLastResult() method.
478 * @see Tizen::Base::Collection::IEnumerator
479 * @see Tizen::Base::Collection::IMapEnumerator
481 virtual IMapEnumeratorT< KeyType, ValueType >* GetMapEnumeratorN(void) const
483 return dynamic_cast< IMapEnumeratorT< KeyType, ValueType >* >(GetEnumeratorN());
487 * Gets the value associated with the specified @c key.
491 * @return The value associated with the key, @n
492 * else @c null if an exception occurs
493 * @param[in] key The key to locate
494 * @param[out] value The value associated with the @c key
495 * @exception E_SUCCESS The method is successful.
496 * @exception E_INVALID_ARG Either of the following conditions has occurred:
497 * - A specified input parameter is invalid.
498 * - The comparer has failed to compare the keys.
499 * @exception E_OBJ_NOT_FOUND The specified @c key has not been found in the map.
502 virtual result GetValue(const KeyType& key, ValueType& value) const
504 result r = E_OBJ_NOT_FOUND;
506 int hash = Hash(key);
507 int i = hash & (__capacity - 1);
509 for (__HashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
511 if (hash == pEntry->hash)
514 r = __pComparer->Compare(key, pEntry->key, cmpResult);
515 TryReturn(r == E_SUCCESS, E_INVALID_ARG, "[%s] Propagating.", GetErrorMessage(r));
519 value = pEntry->value;
525 return E_OBJ_NOT_FOUND;
529 * Gets the value associated with the specified @c key.
533 * @return The value associated with the key, @n
534 * else @c null if an exception occurs
535 * @param[in] key The key to locate
536 * @param[out] value The value associated with the @c key
537 * @exception E_SUCCESS The method is successful.
538 * @exception E_INVALID_ARG Either of the following conditions has occurred:
539 * - A specified input parameter is invalid.
540 * - The comparer has failed to compare the keys.
541 * @exception E_OBJ_NOT_FOUND The specified @c key has not been found in the map.
544 virtual result GetValue(const KeyType& key, ValueType& value)
546 return (static_cast< const HashMapT< KeyType, ValueType >* >(this))->GetValue(key, value);
550 * Gets the list of all the keys in the map.
554 * @return A pointer to the IListT object that contains all the keys in the map, @n
555 * else @c null if an exception occurs
556 * @exception E_SUCCESS The method is successful.
557 * @exception E_OUT_OF_MEMORY The memory is insufficient.
559 * - The order of the keys is the same as the corresponding values in the IListT interface returned by the GetValuesN() method.
560 * - The specific error code can be accessed using the GetLastResult() method.
563 virtual IListT< KeyType >* GetKeysN(void) const
565 result r = E_SUCCESS;
567 ArrayListT< KeyType >* pList = new ArrayListT< KeyType >();
568 TryCatch(pList != null, r = E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
570 r = pList->Construct(__count);
571 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
573 for (int i = 0; i < __capacity; i++)
575 for (__HashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
577 r = pList->Add(pEntry->key);
578 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
582 SetLastResult(E_SUCCESS);
593 * Gets all the values in the map.
597 * @return A pointer to the IListT object that contains all the values in the map, @n
598 * else @c null if an exception occurs
599 * @exception E_SUCCESS The method is successful.
600 * @exception E_OUT_OF_MEMORY The memory is insufficient.
601 * @remarks The specific error code can be accessed using the GetLastResult() method.
604 virtual IListT< ValueType >* GetValuesN(void) const
606 result r = E_SUCCESS;
608 ArrayListT< ValueType >* pList = new ArrayListT< ValueType >();
609 TryCatch(pList != null, r = E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
611 r = pList->Construct(__count);
612 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
614 for (int i = 0; i < __capacity; i++)
616 for (__HashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
618 r = pList->Add(pEntry->value);
619 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
623 SetLastResult(E_SUCCESS);
634 * Removes the value associated to the specified @c key.
638 * @return An error code
639 * @param[in] key The key to remove
640 * @exception E_SUCCESS The method is successful.
641 * @exception E_INVALID_ARG Either of the following conditions has occurred:
642 * - The specified input parameter is invalid.
643 * - The comparer has failed to compare the keys.
644 * @exception E_OBJ_NOT_FOUND The specified @c key has not been found in the map.
647 virtual result Remove(const KeyType& key)
649 result r = E_OBJ_NOT_FOUND;
650 int hash = Hash(key);
651 int i = hash & (__capacity - 1);
653 __HashMapEntryT< KeyType, ValueType >* pPrev = __pTable[i];
654 for (__HashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
656 if (hash == pEntry->hash)
659 r = __pComparer->Compare(key, pEntry->key, cmpResult);
660 TryReturn(r == E_SUCCESS, E_INVALID_ARG, "[%s] Propagating.", GetErrorMessage(r));
667 __pTable[i] = pEntry->pNext;
671 pPrev->pNext = pEntry->pNext;
683 return E_OBJ_NOT_FOUND;
687 * Removes all the key-value pairs in the map.
691 virtual void RemoveAll(void)
702 * Replaces the value associated with the specified @c key with the specified new @c value.
706 * @return An error code
707 * @param[in] key The key whose value is replaced
708 * @param[in] value The new value to replace
709 * @exception E_SUCCESS The method is successful.
710 * @exception E_INVALID_ARG Either of the following conditions has occurred:
711 * - A specified input parameter is invalid.
712 * - The comparer has failed to compare the keys.
713 * @exception E_OBJ_NOT_FOUND The specified @c key has not been found in the map.
714 * @remarks Use the Add() method to add a new key-value pair.
717 virtual result SetValue(const KeyType& key, const ValueType& value)
719 result r = E_SUCCESS;
720 int hash = Hash(key);
721 int i = hash & (__capacity - 1);
724 for (__HashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
726 if (hash == pEntry->hash)
728 r = __pComparer->Compare(key, pEntry->key, cmpResult);
729 TryReturn(r == E_SUCCESS, E_INVALID_ARG, "[%s] Propagating.", GetErrorMessage(r));
732 pEntry->value = value;
749 * Gets the number of pairs currently stored in the map.
753 * @return The pairs stored in the map
755 virtual int GetCount(void) const
761 * Checks whether the map contains the specified @c key.
765 * @return An error code
766 * @param[in] key The key to locate
767 * @param[out] out Set to @c true if the map contains the specified @c key, @n
769 * @exception E_SUCCESS The method is successful.
770 * @exception E_INVALID_ARG Either of the following conditions has occurred:
771 * - A specified input parameter is invalid.
772 * - The comparer has failed to compare the keys.
773 * @see ContainsValue()
775 virtual result ContainsKey(const KeyType& key, bool& out) const
779 result r = E_SUCCESS;
780 int hash = Hash(key);
781 int i = hash & (__capacity - 1);
783 for (__HashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
785 if (hash == pEntry->hash)
788 r = __pComparer->Compare(key, pEntry->key, cmpResult);
789 TryReturn(r == E_SUCCESS, E_INVALID_ARG, "[%s] Propagating.", GetErrorMessage(r));
803 * Checks whether the map contains the specified @c value.
807 * @return @c true if the map contains the specified @c value, @n
809 * @param[in] value The value to locate
813 virtual bool ContainsValue(const ValueType& value) const
815 for (int i = 0; i < __capacity; i++)
817 for (__HashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
819 if (value == pEntry->value)
830 * Compares two instances of %HashMapT.
834 * @return @c true if the two instances match, @n
836 * @param[in] obj The object to compare with the current instance
837 * @remarks This method returns @c true if and only if the two instances contain the same number of elements and all the elements are present in both of them.
839 virtual bool Equals(const Object& obj) const
841 const HashMapT< KeyType, ValueType >* other = dynamic_cast< const HashMapT< KeyType, ValueType >* >(&obj);
846 else if (other == this)
850 else if (__count != other->__count)
856 for (int i = 0; i < __capacity; i++)
858 for (__HashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
860 ValueType otherValue;
861 result r = other->GetValue(pEntry->key, otherValue);
866 if (pEntry->value != otherValue)
878 * Gets the hash value of the current instance.
882 * @return The hash value of the current instance
883 * @remarks The two Tizen::Base::Object::Equals() instances must return the same hash value. @n
884 * For better performance, the used hash function must generate a random distribution for all the inputs.
886 virtual int GetHashCode(void) const
889 for (int i = 0; i < __capacity; i++)
891 for (__HashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
893 hash += reinterpret_cast< int >(&pEntry->key);
894 hash += reinterpret_cast< int >(&pEntry->value);
902 * The implementation of this copy constructor is intentionally blank and declared as private to prohibit copying of objects.
904 * @param[in] map The instance of the %HashMapT class to copy from
906 HashMapT(const HashMapT< KeyType, ValueType >& map);
909 * The implementation of this copy assignment operator is intentionally blank and declared as private to prohibit copying of objects.
911 * @param[in] map An instance of %HashMapT
913 HashMapT< KeyType, ValueType >& operator =(const HashMapT< KeyType, ValueType >& map);
916 * Copies all the pairs from a specified @c map to this map.
918 * @return An error code
919 * @param[in] map The map to copy
920 * @exception E_SUCCESS The method is successful.
921 * @exception E_INVALID_OPERATION The current state of the instance prohibits the execution of the specified operation. @n
922 * The @c map is modified during the operation of this method.
924 result AddAll(const IMapT< KeyType, ValueType >& map)
926 result r = E_SUCCESS;
928 IMapT< KeyType, ValueType >* pMap = const_cast< IMapT< KeyType, ValueType >* >(&map);
929 IMapEnumeratorT< KeyType, ValueType >* pMapEnum = pMap->GetMapEnumeratorN();
931 TryCatch(pMapEnum != null, r = GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
933 while ((r = pMapEnum->MoveNext()) != E_OUT_OF_RANGE)
935 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
940 r = pMapEnum->GetKey(key);
941 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
943 r = pMapEnum->GetValue(value);
944 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
946 int hash = Hash(key);
947 int i = hash & (__capacity - 1);
948 __HashMapEntryT< KeyType, ValueType >* pNewEntry = new __HashMapEntryT< KeyType, ValueType >(key, value, __pTable[i], hash);
950 TryCatch(pNewEntry != null, r = E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
951 __pTable[i] = pNewEntry;
955 if (null != pMapEnum)
963 if (null != pMapEnum)
972 * Gets the hash value for the specified object.
974 * @return The hash value for the specified object
975 * @param[in] obj The object to get hash value
977 int Hash(const KeyType& obj) const
979 int h = __pProvider->GetHashCode(obj);
981 h ^= (h >> 20) ^ (h >> 12);
983 return h ^ (h >> 7) ^ (h >> 4);
987 * Resizes the content of a map to a new array with a greater capacity.
989 * @return An error code
990 * @param[in] newCapacity The new capacity @n
991 * It must be a power of two and greater than the current capacity.
992 * @exception E_SUCCESS The method is successful.
993 * @exception E_OUT_OF_MEMORY The memory is insufficient.
994 * @remarks This method is called automatically when the number of keys in a map reaches its threshold.
996 result Resize(int newCapacity)
998 result r = E_SUCCESS;
999 __HashMapEntryT< KeyType, ValueType >** pNewTable = new __HashMapEntryT< KeyType, ValueType >*[newCapacity];
1000 TryReturn(pNewTable != null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
1002 memset(pNewTable, null, sizeof(__HashMapEntryT< KeyType, ValueType >*) * newCapacity);
1004 for (int i = 0; i < __capacity; i++)
1006 __HashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i];
1007 while (null != pEntry)
1009 __HashMapEntryT< KeyType, ValueType >* pNext = pEntry->pNext;
1010 int i = pEntry->hash & (newCapacity - 1);
1011 pEntry->pNext = pNewTable[i];
1012 pNewTable[i] = pEntry;
1018 __pTable = pNewTable;
1019 __capacity = newCapacity;
1020 __threshold = static_cast< int >(__capacity * __loadFactor);
1026 * Clears all key-value pairs in this map.
1030 for (int i = 0; i < __capacity; i++)
1032 __HashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i];
1033 while (null != pEntry)
1035 __HashMapEntryT< KeyType, ValueType >* pNext = pEntry->pNext;
1043 __HashMapEntryT< KeyType, ValueType >** __pTable;
1048 IHashCodeProviderT< KeyType >* __pProvider;
1049 IComparerT< KeyType >* __pComparer;
1050 bool __defaultConstruct;
1053 static const int DEFAULT_CAPACITY = 16;
1054 static const float DEFAULT_LOAD_FACTOR;
1056 friend class __HashMapEnumeratorT< KeyType, ValueType >;
1061 // @class __HashMapEntryT
1062 // @brief This is an entry for the %HashMapT class.
1065 template< class KeyType, class ValueType >
1066 class __HashMapEntryT
1071 * This is the constructor for this class.
1075 * @param[in] k The key to include in this entry
1076 * @param[in] v The value to include in this entry
1077 * @param[in] next A pointer to the next entry
1078 * @param[in] h The hash value of the key
1080 __HashMapEntryT(const KeyType& k, const ValueType& v, __HashMapEntryT< KeyType, ValueType >* next, int h)
1089 * This is the destructor for this class.
1093 virtual ~__HashMapEntryT(void)
1098 * Internal variable.
1105 * Internal variable.
1112 * Internal variable.
1119 * Internal variable.
1123 __HashMapEntryT< KeyType, ValueType >* pNext;
1125 }; // __HashMapEntryT
1128 // @class __HashMapEnumeratorT
1129 // @brief This is an implementation of the IMapEnumeratorT interface for the %HashMapT class.
1132 template< class KeyType, class ValueType >
1133 class __HashMapEnumeratorT
1134 : public IMapEnumeratorT< KeyType, ValueType >
1139 * This is the constructor for this class.
1143 * @param[in] map The map to enumerate
1144 * @param[in] modCount The modification count to detect the change in the map
1146 __HashMapEnumeratorT(const HashMapT< KeyType, ValueType >& map, int modCount)
1148 , __modCount(modCount)
1156 * This is the destructor for this class.
1160 virtual ~__HashMapEnumeratorT(void)
1166 * Gets the current object in the map.
1170 * @return An error code
1171 * @param[out] obj The current object
1172 * @exception E_SUCCESS The method is successful.
1173 * @exception E_INVALID_OPERATION Either of the following conditions has occurred:
1174 * - The current state of the instance prohibits the execution of the specified operation.
1175 * - This enumerator is currently positioned before the first element or past the last element.
1176 * - The map is modified after this enumerator is created.
1178 virtual result GetCurrent(MapEntryT< KeyType, ValueType >& obj) const
1180 TryReturn((__modCount == __map.__modCount), E_INVALID_OPERATION,
1181 "[%s] The source collection is modified after the creation of this enumerator.", GetErrorMessage(E_INVALID_OPERATION));
1182 TryReturn((__pEntry != null), E_INVALID_OPERATION, "[%s] Invalid position(pEntry is null).", GetErrorMessage(E_INVALID_OPERATION));
1184 obj = MapEntryT< KeyType, ValueType >(__pEntry->key, __pEntry->value);
1189 * Moves this enumerator to the next element of the map.
1190 * When this enumerator is first created, or when the Reset() method is called, or when the %MoveNext() method is first called, the enumerator positions itself to the first element in the map.
1194 * @return An error code
1195 * @exception E_SUCCESS The method is successful.
1196 * @exception E_INVALID_OPERATION Either of the following conditions has occurred:
1197 * - The current state of the instance prohibits the execution of the specified operation.
1198 * - The map is modified after this enumerator is created.
1199 * @exception E_OUT_OF_RANGE The enumerator has passed the end of the map.
1201 virtual result MoveNext(void)
1203 TryReturn((__modCount == __map.__modCount), E_INVALID_OPERATION,
1204 "[%s] The source collection is modified after the creation of this enumerator.", GetErrorMessage(E_INVALID_OPERATION));
1206 if ((null != __pEntry) && (null != __pEntry->pNext))
1208 __pEntry = __pEntry->pNext;
1213 while (++__index < __map.__capacity)
1215 __pEntry = __map.__pTable[__index];
1216 if (null != __pEntry)
1223 return E_OUT_OF_RANGE;
1227 * Positions the enumerator before the first element in the map.
1231 * @return An error code
1232 * @exception E_SUCCESS The method is successful.
1233 * @exception E_INVALID_OPERATION Either of the following conditions has occurred:
1234 * - The current state of the instance prohibits the execution of the specified operation.
1235 * - The map is modified after this enumerator is created.
1237 virtual result Reset(void)
1239 TryReturn((__modCount == __map.__modCount), E_INVALID_OPERATION,
1240 "[%s] The source collection is modified after the creation of this enumerator.", GetErrorMessage(E_INVALID_OPERATION));
1248 * Gets the current key in the map.
1252 * @return An error code
1253 * @param[out] key The current key
1254 * @exception E_SUCCESS The method is successful.
1255 * @exception E_INVALID_OPERATION Either of the following conditions has occurred:
1256 * - The current state of the instance prohibits the execution of the specified operation.
1257 * - This enumerator is currently positioned before the first element or past the last element.
1258 * - The map is modified after this enumerator is created.
1260 virtual result GetKey(KeyType& key) const
1262 TryReturn((__modCount == __map.__modCount), E_INVALID_OPERATION,
1263 "[%s] The source collection is modified after the creation of this enumerator.", GetErrorMessage(E_INVALID_OPERATION));
1264 TryReturn((__pEntry != null), E_INVALID_OPERATION, "[%s] Invalid position(pEntry is null).", GetErrorMessage(E_INVALID_OPERATION));
1266 key = __pEntry->key;
1271 * Gets the current value in the map.
1275 * @return An error code
1276 * @param[out] value The current value
1277 * @exception E_SUCCESS The method is successful.
1278 * @exception E_INVALID_OPERATION Either of the following conditions has occurred:
1279 * - The current state of the instance prohibits the execution of the specified operation.
1280 * - This enumerator is currently positioned before the first element or past the last element
1281 * - The map is modified after the enumerator is created.
1283 virtual result GetValue(ValueType& value) const
1285 TryReturn((__modCount == __map.__modCount), E_INVALID_OPERATION,
1286 "[%s] The source collection is modified after the creation of this enumerator.", GetErrorMessage(E_INVALID_OPERATION));
1287 TryReturn((__pEntry != null), E_INVALID_OPERATION, "[%s] Invalid position(pEntry is null).", GetErrorMessage(E_INVALID_OPERATION));
1289 value = __pEntry->value;
1294 const HashMapT< KeyType, ValueType >& __map;
1296 __HashMapEntryT< KeyType, ValueType >* __pEntry;
1299 }; // __HashMapEnumeratorT
1302 // @class __HashMapDefaultProviderT
1303 // @brief This is an implementation of the IHashCodeProviderT interface for the HashMap class.
1306 template< class KeyType >
1307 class __HashMapDefaultProviderT
1308 : public IHashCodeProviderT< KeyType >
1313 * This is the default constructor for this class.
1317 __HashMapDefaultProviderT(void) {}
1320 * This is the destructor for this class.
1324 virtual ~__HashMapDefaultProviderT(void) {}
1327 * Gets the hash code of the specified object.
1331 * @return The hash code of the specified object
1332 * @see Tizen::Base::Object::GetHashCode
1334 virtual int GetHashCode(const KeyType& obj) const
1339 }; // __HashMapDefaultProviderT
1341 template< class KeyType, class ValueType >
1342 const float HashMapT< KeyType, ValueType >::DEFAULT_LOAD_FACTOR = 0.75;
1344 }}} // Tizen::Base::Collection
1346 #endif //_FBASE_COL_HASH_MAP_T_H_