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 FBaseColHashMapT.h
20 * @brief This is the header file for the %HashMapT class.
22 * This header file contains the declarations of the %HashMapT class.
24 #ifndef _FBASE_COL_HASH_MAP_T_H_
25 #define _FBASE_COL_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 <FBaseColIMapT.h>
33 #include <FBaseColArrayListT.h>
34 #include <FBaseColMapEntryT.h>
35 #include <FBaseComparerT.h>
36 #include <FBaseFloat.h>
39 namespace Tizen { namespace Base { namespace Collection
42 template< class KeyType, class ValueType > class __HashMapEntryT;
43 template< class KeyType, class ValueType > class __HashMapEnumeratorT;
44 template< class KeyType > class __HashMapDefaultProviderT;
48 * @brief This class provides a template-based collection of associated keys and values
49 * that are organized based on the hash code of the key.
53 * The %HashMapT class provides a template-based collection of associated keys and values
54 * that are organized based on the hash code of the key.
55 * It contains unique keys and each key maps to one single value.
56 * The key and value cannot be a null reference. Several methods in the %HashMapT class need assignment (=) operators of KeyType and 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 %HashMapT class.
65 * using namespace Tizen::Base;
66 * using namespace Tizen::Base::Collection;
69 * MyClass::HashMapTSample(void)
71 * HashMapT< int, int > map;
73 * // Constructs a %HashMapT instance with default capacity, load factor, hash code provider, and comparer
76 * map.Add(1, 100); // map.GetCount() : 1
77 * map.Add(2, 200); // map.GetCount() : 2
78 * map.Add(3, 300); // map.GetCount() : 3
83 * // Gets a value with the specified key
85 * map.GetValue(key, value); // value : 100
87 * // Removes the value with the specified key
90 * // Uses an enumerator to access elements in the map
91 * IMapEnumeratorT< int, int >* pMapEnum = map.GetMapEnumeratorN();
92 * while (pMapEnum->MoveNext() == E_SUCCESS)
94 * pMapEnum->GetKey(key);
95 * pMapEnum->GetValue(value);
102 template< class KeyType, class ValueType >
104 : public IMapT< KeyType, ValueType >
109 * The object is not fully constructed after this constructor is called. For full construction, @n
110 * the Construct() method must be called right after calling this constructor.
122 , __defaultConstruct(false)
128 * This destructor overrides Tizen::Base::Object::~Object().
132 virtual ~HashMapT(void)
134 if (null != __pTable)
140 if (__defaultConstruct)
149 * Initializes this instance of %HashMapT with the specified parameters.
153 * @return An error code
154 * @param[in] capacity The initial capacity
155 * @param[in] loadFactor The maximum ratio of elements to buckets
156 * @exception E_SUCCESS The method is successful.
157 * @exception E_INVALID_ARG A specified input parameter is invalid, or
158 * the @c capacity or the @c loadFactor is negative.
159 * @remarks To work properly, the key type must be of a primitive number type.
162 result Construct(int capacity = 16, float loadFactor = 0.75)
164 TryReturn(capacity >= 0, E_INVALID_ARG, "[%s] The capacity(%d) MUST be greater than or equal to 0.", GetErrorMessage(E_INVALID_ARG), capacity);
165 TryReturn(loadFactor >= 0, E_INVALID_ARG, "[%s] The loadFactor(%f) MUST be greater than or equal to 0.0.", GetErrorMessage(E_INVALID_ARG), loadFactor);
167 result r = E_SUCCESS;
171 __capacity = DEFAULT_CAPACITY;
176 while (__capacity < capacity)
182 if (Float::Compare(loadFactor, 0) == 0)
184 __loadFactor = DEFAULT_LOAD_FACTOR;
188 __loadFactor = loadFactor;
191 __threshold = static_cast< int >(__capacity * __loadFactor);
193 __pProvider = new __HashMapDefaultProviderT< KeyType >();
194 TryCatch(__pProvider != null, r = E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
196 __pComparer = new Tizen::Base::ComparerT< KeyType >();
197 TryCatch(__pComparer != null, r = E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
199 __defaultConstruct = true;
201 __pTable = new __HashMapEntryT< KeyType, ValueType >*[__capacity];
202 TryCatch(__pTable != null, r = E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
204 memset(__pTable, null, sizeof(__HashMapEntryT< KeyType, ValueType >*) * __capacity);
217 * Initializes this instance of %HashMapT by copying the elements of the specified @c map.
221 * @return An error code
222 * @param[in] map The map to copy
223 * @param[in] loadFactor The maximum ratio of elements to buckets
224 * @exception E_SUCCESS The method is successful.
225 * @exception E_INVALID_ARG A specified input parameter is invalid, or
226 * the @c loadFactor is negative.
227 * @exception E_INVALID_OPERATION The current state of the instance prohibits the execution of the specified operation, or
228 * the @c map is modified during the operation of this method.
231 result Construct(const IMapT< KeyType, ValueType >& map, float loadFactor = 0.75)
233 TryReturn(loadFactor >= 0, E_INVALID_ARG, "[%s] The loadFactor(%f) MUST be greater than or equal to 0.0.", GetErrorMessage(E_INVALID_ARG), loadFactor);
235 result r = E_SUCCESS;
237 if (Float::Compare(loadFactor, 0) == 0)
239 loadFactor = DEFAULT_LOAD_FACTOR;
242 int capacity = static_cast< int >(map.GetCount() / loadFactor) + 1;
244 r = Construct(capacity, loadFactor);
245 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
248 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
269 * Initializes this instance of an empty %HashMapT class, with the specified initial capacity, load factor, hash code provider, and comparer.
273 * @return An error code
274 * @param[in] capacity The initial capacity @n
275 * If it is @c 0, the default capacity (16) is used.
276 * @param[in] loadFactor The maximum ratio of the elements to buckets @n
277 * If it is @c 0, the default load factor (0.75) is used.
278 * @param[in] provider An instance of the IHashCodeProviderT-derived class that supplies the hash codes
279 * for all keys in this map
280 * @param[in] comparer An instance of the IComparerT-derived class to use when comparing keys
281 * @exception E_SUCCESS The method is successful.
282 * @exception E_INVALID_ARG Either of the following conditions has occurred: @n
283 * - A specified input parameter is invalid. @n
284 * - The specified @c capacity is negative. @n
285 * - The @c loadFactor is negative.
286 * @remarks The instances of hash code provider and comparer will not be deallocated later from this map.
289 result Construct(int capacity, float loadFactor, const IHashCodeProviderT< KeyType >& provider,
290 const IComparerT< KeyType >& comparer)
292 TryReturn(capacity >= 0, E_INVALID_ARG, "[%s] The capacity(%d) MUST be greater than or equal to 0.", GetErrorMessage(E_INVALID_ARG), capacity);
293 TryReturn(loadFactor >= 0, E_INVALID_ARG, "[%s] The loadFactor(%f) MUST be greater than or equal to 0.0.", GetErrorMessage(E_INVALID_ARG), loadFactor);
295 result r = E_SUCCESS;
299 __capacity = DEFAULT_CAPACITY;
304 while (__capacity < capacity)
310 if (Float::Compare(loadFactor, 0) == 0)
312 __loadFactor = DEFAULT_LOAD_FACTOR;
316 __loadFactor = loadFactor;
319 __threshold = static_cast< int >(__capacity * __loadFactor);
321 __pProvider = const_cast< IHashCodeProviderT< KeyType >* >(&provider);
323 __pComparer = const_cast< IComparerT< KeyType >* >(&comparer);
325 __pTable = new __HashMapEntryT< KeyType, ValueType >*[__capacity];
326 TryCatch(__pTable != null, r = E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
328 memset(__pTable, null, sizeof(__HashMapEntryT< KeyType, ValueType >*) * __capacity);
341 * Initializes this instance of %HashMapT by copying the elements of the specified @c map,
342 * with the specified load factor, hash code provider, and comparer.
346 * @return An error code
347 * @param[in] map The map to copy
348 * @param[in] loadFactor The maximum ratio of elements to buckets @n
349 * If it is @c 0, the default load factor (0.75) is used.
350 * @param[in] provider An instance of the IHashCodeProviderT-derived class that supplies the hash codes
351 * for all keys in this map
352 * @param[in] comparer An instance of the IComparerT-derived class to use when comparing keys
353 * @exception E_SUCCESS The method is successful.
354 * @exception E_INVALID_ARG Either of the following conditions has occurred: @n
355 * - A specified input parameter is invalid. @n
356 * - The @c loadFactor is negative. @n
357 * - The @c provider is a @c null or the @c comparer is a @c null.
358 * @exception E_INVALID_OPERATION The current state of the instance prohibits the execution of the specified operation, or
359 * the @c map is modified during the operation of this method.
360 * @remarks The instances of hash code provider and comparer will not be deallocated later from this map.
363 result Construct(const IMapT< KeyType, ValueType >& map, float loadFactor, const IHashCodeProviderT< KeyType >& provider,
364 const IComparerT< KeyType >& comparer)
366 TryReturn((loadFactor >= 0), E_INVALID_ARG, "[%s] The loadFactor(%f) MUST be greater than or equal to 0.0.", GetErrorMessage(E_INVALID_ARG), loadFactor);
368 result r = E_SUCCESS;
369 if (Float::Compare(loadFactor, 0) == 0)
371 loadFactor = DEFAULT_LOAD_FACTOR;
374 int capacity = static_cast< int >(map.GetCount() / loadFactor) + 1;
375 r = Construct(capacity, loadFactor, provider, comparer);
376 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
379 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
396 * Adds the specified key-value pair to a map.
400 * @return An error code
401 * @param[in] key The key of the value to add
402 * @param[in] value The value to add
403 * @exception E_SUCCESS The method is successful.
404 * @exception E_INVALID_ARG A specified input parameter is invalid, or
405 * the comparer has failed to compare the keys.
406 * @exception E_OBJ_ALREADY_EXIST The specified @c key already exists.
409 virtual result Add(const KeyType& key, const ValueType& value)
411 __HashMapEntryT< KeyType, ValueType >* pNewEntry;
413 result r = E_SUCCESS;
414 int hash = Hash(key);
415 int i = hash & (__capacity - 1);
418 r = ContainsKey(key, out);
419 TryReturn((!out), E_OBJ_ALREADY_EXIST, "[%s] The key is already exist in this collection.", GetErrorMessage(E_OBJ_ALREADY_EXIST));
420 TryReturn(r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
423 pNewEntry = new __HashMapEntryT< KeyType, ValueType >(key, value, __pTable[i], hash);
424 TryReturn(pNewEntry != null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
425 __pTable[i] = pNewEntry;
428 if (__count++ >= __threshold)
430 r = Resize(__capacity * 2);
431 TryReturn(r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
438 * Gets the elements of a map in an instance of the IMapEnumeratorT-derived class.
442 * @return An instance of the IMapEnumeratorT-derived class if successful, @n
443 * else @c null if an exception occurs
444 * @exception E_SUCCESS The method is successful.
445 * @exception E_OUT_OF_MEMORY The memory is insufficient.
446 * @remarks The specific error code can be accessed using the GetLastResult() method.
447 * @see Tizen::Base::Collection::IEnumerator
448 * @see Tizen::Base::Collection::IMapEnumerator
450 virtual IEnumeratorT< MapEntryT< KeyType, ValueType > >* GetEnumeratorN(void) const
452 result r = E_SUCCESS;
454 __HashMapEnumeratorT< KeyType, ValueType >* pEnum = new __HashMapEnumeratorT< KeyType, ValueType >(*this, __modCount);
455 TryCatch(pEnum != null, r = E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
457 SetLastResult(E_SUCCESS);
466 * Gets the elements of a map in an instance of the IMapEnumeratorT class.
470 * @return An instance of the IMapEnumeratorT class if successful, @n
471 * else @c null if an exception occurs
472 * @exception E_SUCCESS The method is successful.
473 * @exception E_OUT_OF_MEMORY The memory is insufficient.
474 * @remarks The specific error code can be accessed using the GetLastResult() method.
475 * @see Tizen::Base::Collection::IEnumerator
476 * @see Tizen::Base::Collection::IMapEnumerator
478 virtual IMapEnumeratorT< KeyType, ValueType >* GetMapEnumeratorN(void) const
480 return dynamic_cast< IMapEnumeratorT< KeyType, ValueType >* >(GetEnumeratorN());
484 * Gets the value associated with the specified @c key.
488 * @return The value associated with the key, @n
489 * else @c null if an exception occurs
490 * @param[in] key The key to locate
491 * @param[out] value The value associated with the key
492 * @exception E_SUCCESS The method is successful.
493 * @exception E_INVALID_ARG A specified input parameter is invalid, or
494 * The comparer has failed to compare the keys.
495 * @exception E_OBJ_NOT_FOUND The specified @c key is not found in the map.
498 virtual result GetValue(const KeyType& key, ValueType& value) const
500 result r = E_OBJ_NOT_FOUND;
502 int hash = Hash(key);
503 int i = hash & (__capacity - 1);
505 for (__HashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
507 if (hash == pEntry->hash)
510 r = __pComparer->Compare(key, pEntry->key, cmpResult);
511 TryReturn(r == E_SUCCESS, E_INVALID_ARG, "[%s] Propagating.", GetErrorMessage(r));
515 value = pEntry->value;
521 return E_OBJ_NOT_FOUND;
525 * Gets the value associated with the specified @c key.
529 * @return The value associated with the key, @n
530 * else @c null if an exception occurs
531 * @param[in] key The key to locate
532 * @param[out] value The value associated with the key
533 * @exception E_SUCCESS The method is successful.
534 * @exception E_INVALID_ARG A specified input parameter is invalid, or
535 * the comparer has failed to compare the keys.
536 * @exception E_OBJ_NOT_FOUND The specified @c key is not found in the map.
539 virtual result GetValue(const KeyType& key, ValueType& value)
541 return (static_cast< const HashMapT< KeyType, ValueType >* >(this))->GetValue(key, value);
545 * Gets a list of all the keys in a map.
549 * @return A pointer to an IListT object containing all the keys in the map, @n
550 * else @c null if an exception occurs
551 * @exception E_SUCCESS The method is successful.
552 * @exception E_OUT_OF_MEMORY The memory is insufficient.
553 * @remarks The order of the keys is the same as the corresponding values in the IListT interface returned by the GetValuesN() method.
554 * @remarks The specific error code can be accessed using the GetLastResult() method.
557 virtual IListT< KeyType >* GetKeysN(void) const
559 result r = E_SUCCESS;
561 ArrayListT< KeyType >* pList = new ArrayListT< KeyType >();
562 TryCatch(pList != null, r = E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
564 r = pList->Construct(__count);
565 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
567 for (int i = 0; i < __capacity; i++)
569 for (__HashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
571 r = pList->Add(pEntry->key);
572 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
576 SetLastResult(E_SUCCESS);
587 * Gets all the values in a map.
591 * @return A pointer to an IListT object containing all the values in the map, @n
592 * else @c null if an exception occurs
593 * @exception E_SUCCESS The method is successful.
594 * @exception E_OUT_OF_MEMORY The memory is insufficient.
595 * @remarks The specific error code can be accessed using the GetLastResult() method.
598 virtual IListT< ValueType >* GetValuesN(void) const
600 result r = E_SUCCESS;
602 ArrayListT< ValueType >* pList = new ArrayListT< ValueType >();
603 TryCatch(pList != null, r = E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
605 r = pList->Construct(__count);
606 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
608 for (int i = 0; i < __capacity; i++)
610 for (__HashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
612 r = pList->Add(pEntry->value);
613 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
617 SetLastResult(E_SUCCESS);
628 * Removes the value associated with the specified @c key.
632 * @return An error code
633 * @param[in] key The key to remove
634 * @exception E_SUCCESS The method is successful.
635 * @exception E_INVALID_ARG The specified input parameter is invalid, or
636 * the comparer has failed to compare the keys.
637 * @exception E_OBJ_NOT_FOUND The specified @c key is not found in the map.
640 virtual result Remove(const KeyType& key)
642 result r = E_OBJ_NOT_FOUND;
643 int hash = Hash(key);
644 int i = hash & (__capacity - 1);
646 __HashMapEntryT< KeyType, ValueType >* pPrev = __pTable[i];
647 for (__HashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
649 if (hash == pEntry->hash)
652 r = __pComparer->Compare(key, pEntry->key, cmpResult);
653 TryReturn(r == E_SUCCESS, E_INVALID_ARG, "[%s] Propagating.", GetErrorMessage(r));
660 __pTable[i] = pEntry->pNext;
664 pPrev->pNext = pEntry->pNext;
676 return E_OBJ_NOT_FOUND;
680 * Removes all key-value pairs in the map.
684 virtual void RemoveAll(void)
695 * Replaces the value associated with the specified @c key with the specified new @c value.
699 * @return An error code
700 * @param[in] key The key for which the value is to replace
701 * @param[in] value The new value to replace
702 * @exception E_SUCCESS The method is successful.
703 * @exception E_INVALID_ARG A specified input parameter is invalid, or
704 * the comparer has failed to compare the keys.
705 * @exception E_OBJ_NOT_FOUND The specified @c key is not found in the map.
706 * @remarks Use the Add() method to add a new key-value pair.
710 virtual result SetValue(const KeyType& key, const ValueType& value)
712 result r = E_SUCCESS;
713 int hash = Hash(key);
714 int i = hash & (__capacity - 1);
717 for (__HashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
719 if (hash == pEntry->hash)
721 r = __pComparer->Compare(key, pEntry->key, cmpResult);
722 TryReturn(r == E_SUCCESS, E_INVALID_ARG, "[%s] Propagating.", GetErrorMessage(r));
725 pEntry->value = value;
742 * Gets the number of pairs currently stored in a map.
746 * @return The pairs stored in the map
748 virtual int GetCount(void) const
754 * Checks whether a map contains the specified @c key.
758 * @return An error code
759 * @param[in] key The key to locate
760 * @param[out] out Set to @c true if the map contains the specified @c key, @n
762 * @exception E_SUCCESS The method is successful.
763 * @exception E_INVALID_ARG A specified input parameter is invalid, or
764 * the comparer has failed to compare the keys.
765 * @see ContainsValue()
767 virtual result ContainsKey(const KeyType& key, bool& out) const
771 result r = E_SUCCESS;
772 int hash = Hash(key);
773 int i = hash & (__capacity - 1);
775 for (__HashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
777 if (hash == pEntry->hash)
780 r = __pComparer->Compare(key, pEntry->key, cmpResult);
781 TryReturn(r == E_SUCCESS, E_INVALID_ARG, "[%s] Propagating.", GetErrorMessage(r));
795 * Checks whether a map contains the specified @c value.
799 * @return @c true if the map contains the specified @c value, @n
801 * @param[in] value The value to locate
805 virtual bool ContainsValue(const ValueType& value) const
807 for (int i = 0; i < __capacity; i++)
809 for (__HashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
811 if (value == pEntry->value)
822 * Compares two instances of the %HashMapT class.
826 * @return @c true if the two instances match, @n
828 * @param[in] obj The object to compare with the current instance
829 * @remarks This method returns @c true if and only if the two instances contain the same number of elements and all the elements of each other.
831 virtual bool Equals(const Object& obj) const
833 const HashMapT< KeyType, ValueType >* other = dynamic_cast< const HashMapT< KeyType, ValueType >* >(&obj);
838 else if (other == this)
842 else if (__count != other->__count)
848 for (int i = 0; i < __capacity; i++)
850 for (__HashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
852 ValueType otherValue;
853 result r = other->GetValue(pEntry->key, otherValue);
858 if (pEntry->value != otherValue)
870 * Gets the hash value of the current instance.
874 * @return The hash value of the current instance
875 * @remarks The two Tizen::Base::Object::Equals() instances must return the same hash value. For better performance, @n
876 * the used hash function must generate a random distribution for all inputs.
878 virtual int GetHashCode(void) const
881 for (int i = 0; i < __capacity; i++)
883 for (__HashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i]; null != pEntry; pEntry = pEntry->pNext)
885 hash += reinterpret_cast< int >(&pEntry->key);
886 hash += reinterpret_cast< int >(&pEntry->value);
894 * The implementation of this copy constructor is intentionally blank and declared as private to prohibit copying of objects.
896 * @param[in] map The instance of the %HashMapT class to copy from
898 HashMapT(const HashMapT< KeyType, ValueType >& map);
901 * The implementation of this copy assignment operator is intentionally blank and declared as private to prohibit copying of objects.
903 * @param[in] map An instance of %HashMapT
905 HashMapT< KeyType, ValueType >& operator =(const HashMapT< KeyType, ValueType >& map);
908 * Copies all the pairs from a specified @c map to this map.
910 * @return An error code
911 * @param[in] map The map to copy
912 * @exception E_SUCCESS The method is successful.
913 * @exception E_INVALID_OPERATION The current state of the instance prohibits the execution of the specified operation. @n
914 * The @c map is modified during the operation of this method.
916 result AddAll(const IMapT< KeyType, ValueType >& map)
918 result r = E_SUCCESS;
920 IMapT< KeyType, ValueType >* pMap = const_cast< IMapT< KeyType, ValueType >* >(&map);
921 IMapEnumeratorT< KeyType, ValueType >* pMapEnum = pMap->GetMapEnumeratorN();
923 TryCatch(pMapEnum != null, r = GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
925 while ((r = pMapEnum->MoveNext()) != E_OUT_OF_RANGE)
927 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
932 r = pMapEnum->GetKey(key);
933 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
935 r = pMapEnum->GetValue(value);
936 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
938 int hash = Hash(key);
939 int i = hash & (__capacity - 1);
940 __HashMapEntryT< KeyType, ValueType >* pNewEntry = new __HashMapEntryT< KeyType, ValueType >(key, value, __pTable[i], hash);
942 TryCatch(pNewEntry != null, r = E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
943 __pTable[i] = pNewEntry;
947 if (null != pMapEnum)
955 if (null != pMapEnum)
964 * Gets the hash value for the specified object.
966 * @return The hash value for the specified object
967 * @param[in] obj The object to get hash value
969 int Hash(const KeyType& obj) const
971 int h = __pProvider->GetHashCode(obj);
973 h ^= (h >> 20) ^ (h >> 12);
975 return h ^ (h >> 7) ^ (h >> 4);
979 * Resizes the content of a map to a new array with a greater capacity.
981 * @return An error code
982 * @param[in] newCapacity The new capacity @n
983 * It must be a power of two and greater than the current capacity.
984 * @exception E_SUCCESS The method is successful.
985 * @exception E_OUT_OF_MEMORY The memory is insufficient.
986 * @remarks This method is called automatically when the number of keys in a map reaches its threshold.
988 result Resize(int newCapacity)
990 result r = E_SUCCESS;
991 __HashMapEntryT< KeyType, ValueType >** pNewTable = new __HashMapEntryT< KeyType, ValueType >*[newCapacity];
992 TryReturn(pNewTable != null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
994 memset(pNewTable, null, sizeof(__HashMapEntryT< KeyType, ValueType >*) * newCapacity);
996 for (int i = 0; i < __capacity; i++)
998 __HashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i];
999 while (null != pEntry)
1001 __HashMapEntryT< KeyType, ValueType >* pNext = pEntry->pNext;
1002 int i = pEntry->hash & (newCapacity - 1);
1003 pEntry->pNext = pNewTable[i];
1004 pNewTable[i] = pEntry;
1010 __pTable = pNewTable;
1011 __capacity = newCapacity;
1012 __threshold = static_cast< int >(__capacity * __loadFactor);
1018 * Clears all key-value pairs in this map.
1022 for (int i = 0; i < __capacity; i++)
1024 __HashMapEntryT< KeyType, ValueType >* pEntry = __pTable[i];
1025 while (null != pEntry)
1027 __HashMapEntryT< KeyType, ValueType >* pNext = pEntry->pNext;
1035 __HashMapEntryT< KeyType, ValueType >** __pTable;
1040 IHashCodeProviderT< KeyType >* __pProvider;
1041 IComparerT< KeyType >* __pComparer;
1042 bool __defaultConstruct;
1045 static const int DEFAULT_CAPACITY = 16;
1046 static const float DEFAULT_LOAD_FACTOR;
1048 friend class __HashMapEnumeratorT< KeyType, ValueType >;
1053 // @class __HashMapEntryT
1054 // @brief This is an entry for the %HashMapT class.
1057 template< class KeyType, class ValueType >
1058 class __HashMapEntryT
1063 * This is the constructor for this class.
1067 * @param[in] k The key to include in this entry
1068 * @param[in] v The value to include in this entry
1069 * @param[in] next A pointer to the next entry
1070 * @param[in] h A hash value of the key
1072 __HashMapEntryT(const KeyType& k, const ValueType& v, __HashMapEntryT< KeyType, ValueType >* next, int h)
1081 * This is the destructor for this class.
1085 virtual ~__HashMapEntryT(void)
1090 * Internal variable.
1097 * Internal variable.
1104 * Internal variable.
1111 * Internal variable.
1115 __HashMapEntryT< KeyType, ValueType >* pNext;
1117 }; // __HashMapEntryT
1120 // @class __HashMapEnumeratorT
1121 // @brief This is an implementation of the IMapEnumeratorT interface for the %HashMapT class.
1124 template< class KeyType, class ValueType >
1125 class __HashMapEnumeratorT
1126 : public IMapEnumeratorT< KeyType, ValueType >
1131 * This is the constructor for this class.
1135 * @param[in] map The map to enumerate
1136 * @param[in] modCount The modification count to detect the change in the map
1138 __HashMapEnumeratorT(const HashMapT< KeyType, ValueType >& map, int modCount)
1140 , __modCount(modCount)
1148 * This is the destructor for this class.
1152 virtual ~__HashMapEnumeratorT(void)
1158 * Gets the current object in the map.
1162 * @return An error code
1163 * @param[out] obj The current object
1164 * @exception E_SUCCESS The method is successful.
1165 * @exception E_INVALID_OPERATION The current state of the instance prohibits the execution of the specified operation. @n
1166 * This enumerator is currently positioned before the first element or
1167 * past the last element or the map is modified after this enumerator is created.
1169 virtual result GetCurrent(MapEntryT< KeyType, ValueType >& obj) const
1171 TryReturn((__modCount == __map.__modCount), E_INVALID_OPERATION,
1172 "[%s] The source collection is modified after the creation of this enumerator.", GetErrorMessage(E_INVALID_OPERATION));
1173 TryReturn((__pEntry != null), E_INVALID_OPERATION, "[%s] Invalid position(pEntry is null).", GetErrorMessage(E_INVALID_OPERATION));
1175 obj = MapEntryT< KeyType, ValueType >(__pEntry->key, __pEntry->value);
1180 * Moves this enumerator to the next elements of the map.
1181 * 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.
1185 * @return An error code
1186 * @exception E_SUCCESS The method is successful.
1187 * @exception E_INVALID_OPERATION The current state of the instance prohibits the execution of the specified operation, or
1188 * the map is modified after this enumerator is created.
1189 * @exception E_OUT_OF_RANGE The enumerator has passed the end of the map.
1192 virtual result MoveNext(void)
1194 TryReturn((__modCount == __map.__modCount), E_INVALID_OPERATION,
1195 "[%s] The source collection is modified after the creation of this enumerator.", GetErrorMessage(E_INVALID_OPERATION));
1197 if ((null != __pEntry) && (null != __pEntry->pNext))
1199 __pEntry = __pEntry->pNext;
1204 while (++__index < __map.__capacity)
1206 __pEntry = __map.__pTable[__index];
1207 if (null != __pEntry)
1214 return E_OUT_OF_RANGE;
1218 * Positions the enumerator before the first element in a map.
1222 * @return An error code
1223 * @exception E_SUCCESS The method is successful.
1224 * @exception E_INVALID_OPERATION The current state of the instance prohibits the execution of the specified operation, or
1225 * the map is modified after this enumerator is created.
1227 virtual result Reset(void)
1229 TryReturn((__modCount == __map.__modCount), E_INVALID_OPERATION,
1230 "[%s] The source collection is modified after the creation of this enumerator.", GetErrorMessage(E_INVALID_OPERATION));
1238 * Gets the current key in a map.
1242 * @return An error code
1243 * @param[out] key The current key
1244 * @exception E_SUCCESS The method is successful.
1245 * @exception E_INVALID_OPERATION The current state of the instance prohibits the execution of the specified operation. @n
1246 * This enumerator is currently positioned before the first element or
1247 * past the last element or the map is modified after this enumerator is created.
1249 virtual result GetKey(KeyType& key) const
1251 TryReturn((__modCount == __map.__modCount), E_INVALID_OPERATION,
1252 "[%s] The source collection is modified after the creation of this enumerator.", GetErrorMessage(E_INVALID_OPERATION));
1253 TryReturn((__pEntry != null), E_INVALID_OPERATION, "[%s] Invalid position(pEntry is null).", GetErrorMessage(E_INVALID_OPERATION));
1255 key = __pEntry->key;
1260 * Gets the current value in a map.
1264 * @return An error code
1265 * @param[out] value The current value
1266 * @exception E_SUCCESS The method is successful.
1267 * @exception E_INVALID_OPERATION The current state of the instance prohibits the execution of the specified operation. @n
1268 * This enumerator is currently positioned before the first element or
1269 * past the last element or the map is modified after the enumerator is created.
1271 virtual result GetValue(ValueType& value) const
1273 TryReturn((__modCount == __map.__modCount), E_INVALID_OPERATION,
1274 "[%s] The source collection is modified after the creation of this enumerator.", GetErrorMessage(E_INVALID_OPERATION));
1275 TryReturn((__pEntry != null), E_INVALID_OPERATION, "[%s] Invalid position(pEntry is null).", GetErrorMessage(E_INVALID_OPERATION));
1277 value = __pEntry->value;
1282 const HashMapT< KeyType, ValueType >& __map;
1284 __HashMapEntryT< KeyType, ValueType >* __pEntry;
1287 }; // __HashMapEnumeratorT
1290 // @class __HashMapDefaultProviderT
1291 // @brief This is an implementation of the IHashCodeProviderT interface for the HashMap class.
1294 template< class KeyType >
1295 class __HashMapDefaultProviderT
1296 : public IHashCodeProviderT< KeyType >
1301 * This is the default constructor for this class.
1305 __HashMapDefaultProviderT(void) {}
1308 * This is the destructor for this class.
1312 virtual ~__HashMapDefaultProviderT(void) {}
1315 * Gets the hash code of the specified object.
1319 * @return The hash code of the specified object
1320 * @see Tizen::Base::Object::GetHashCode
1322 virtual int GetHashCode(const KeyType& obj) const
1327 }; // __HashMapDefaultProviderT
1329 template< class KeyType, class ValueType >
1330 const float HashMapT< KeyType, ValueType >::DEFAULT_LOAD_FACTOR = 0.75;
1332 }}} // Tizen::Base::Collection
1334 #endif //_FBASE_COL_HASH_MAP_T_H_