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 a specified 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 a specified map,
342 * with a 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 a specified 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 a specified 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 a specified 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 a specified key with a new 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 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 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 value.
799 * @return @c true if the map contains the specified 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 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 a 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_