248064d4ef79fb7d022a82999eead71c908d2239
[platform/framework/native/appfw.git] / inc / FBaseColMultiHashMap.h
1 //
2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
3 //
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
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
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.
15 //
16
17 /**
18  * @file                FBaseColMultiHashMap.h
19  * @brief               This is the header file for the %MultiHashMap class.
20  *
21  * This header file contains the declarations of the %MultiHashMap class.
22  */
23 #ifndef _FBASE_COL_MULTI_HASH_MAP_H_
24 #define _FBASE_COL_MULTI_HASH_MAP_H_
25
26 #include <FBaseObject.h>
27 #include <FBaseColIComparer.h>
28 #include <FBaseColIHashCodeProvider.h>
29 #include <FBaseColIMultiMap.h>
30
31
32 namespace Tizen { namespace Base { namespace Collection
33 {
34
35 class _MultiHashMapEntry;
36
37 /**
38  * @class MultiHashMap
39  * @brief This class represents a collection of associated keys and values that are organized based on the hash code of the key.
40  *
41  * @since 2.0
42  *
43  *  The %MultiHashMap class represents a collection of associated keys and values that are organized based on the hash code of the key.
44  * There is no limit on the number of elements with the same key, but duplicated elements with the same key are not allowed.
45  * The key and value cannot be @c null.
46  * @n
47  * For more information on the class features, see <a href="../org.tizen.native.appprogramming/html/guide/base/hashmap_multihashmap.htm">HashMap and MultiHashMap</a>.
48  *
49  * The following example demonstrates how to use the %MultiHashMap class.
50  *
51  * @code
52  *      #include <FBase.h>
53  *
54  *      using namespace Tizen::Base;
55  *      using namespace Tizen::Base::Collection;
56  *
57  *      void
58  *      MyClass::MultiHashMapSample(void)
59  *      {
60  *              MultiHashMap map(SingleObjectDeleter);
61  *
62  *              // Constructs a MultiHashMap instance with default values for capacity, load factor, hash code provider, and comparer
63  *              map.Construct();
64  *
65  *              map.Add(new String(L"Zero"), new Integer(0));           // map.GetCount() : 1, map : (Zero -> 0)
66  *              map.Add(new String(L"One"), new Integer(1));            // map.GetCount() : 2, map : (Zero -> 0), (one -> 1)
67  *              map.Add(new String(L"Two"), new Integer(2));            // map.GetCount() : 3, map : (Zero -> 0), (one -> 1), (Two -> 2)
68  *              map.Add(new String(L"Two"), new Integer(20));           // map.GetCount() : 4, map : (Zero -> 0), (One -> 1), (Two -> 2, 20)
69  *
70  *              // Gets values with the specified key
71  *              Integer*        pValue = null;
72  *              IEnumerator *pValueEnum = map.GetValuesN(String(L"Two"));
73  *              while(pValueEnum->MoveNext() == E_SUCCESS)
74  *              {
75  *                      pValue = static_cast< Integer* > (pValueEnum->GetCurrent());
76  *              }
77  *
78  *              delete pValueEnum;
79  *
80  *              // Removes values with the specified key     // String(L"Two"), Integer(2), Integer(20) are removed
81  *              map.Remove(String(L"Two"));
82  *
83  *              // Uses an enumerator to access elements in the map
84  *              IMapEnumerator* pMapEnum = map.GetMapEnumeratorN();
85  *              String* pKey = null;
86  *              while (pMapEnum->MoveNext() == E_SUCCESS)
87  *              {
88  *                      pKey = static_cast< String* > (pMapEnum->GetKey());
89  *                      pValue = static_cast< Integer* > (pMapEnum->GetValue());
90  *              }
91  *
92  *              delete pMapEnum;
93  *
94  *              // Deallocates all objects
95  *              // Because the destructor calls RemoveAll() internally, you do not need to call RemoveAll() to destroy all elements at the end.
96  *              // map.RemoveAll();
97  *      }
98  * @endcode
99  */
100 class _OSP_EXPORT_ MultiHashMap
101         : public IMultiMap
102         , public Object
103 {
104 public:
105         using IMultiMap::Add;
106         using IMultiMap::Remove;
107         using IMultiMap::RemoveAll;
108         using IMultiMap::SetValue;
109         using IMultiMap::Contains;
110         using IMultiMap::ContainsKey;
111
112         /**
113          * The object is not fully constructed after this constructor is called. For full construction, @n
114          * the Construct() method must be called right after calling this constructor.
115          *
116          * @since 2.0
117          *
118          * @param[in]   deleter The function pointer to type of the element deleter
119          * @remarks     To create an owing collection, set the element deleter value as @c SingleObjectDeleter. This gives the collection the ownership of elements and the collection will destroy elements. @n
120          *                      On the other hand, to create a non-owning collection, you do not need to set the element deleter value, as @c NoOpDeleter is the default element deleter.
121          *                      It means that you do not transfer the ownership of elements to the collection.
122          * @see         NoOpDeleter()
123          * @see         SingleObjectDeleter()
124          * @see         ArrayDeleter()
125          */
126         explicit MultiHashMap(DeleterFunctionType deleter = NoOpDeleter);
127
128         /**
129          * This destructor overrides Tizen::Base::Object::~Object().
130          *
131          * @since 2.0
132          */
133         virtual ~MultiHashMap(void);
134
135         /**
136          * Initializes a new instance of %MultiHashMap with the specified capacity and load factor.
137          *
138          * @since 2.0
139          *
140          * @return              An error code
141          * @param[in]   capacity                The initial capacity
142          * @param[in]   loadFactor              The maximum ratio of elements to buckets
143          * @exception   E_SUCCESS               The method is successful.
144          * @exception   E_INVALID_ARG   A specified input parameter is invalid, or
145          *                                                                the @c capacity or the @c loadFactor is negative.
146          * @remarks             The GetHashCode() method of the key object is used for hashing and the
147          *                              Equals() method of the key object is used for comparing the keys.
148          * @see                 MultiHashMap()
149          */
150         result Construct(int capacity = 16, float loadFactor = 0.75);
151
152         /**
153          * Initializes a new instance of %MultiHashMap by copying the elements of the given map.
154          *
155          * @since 2.0
156          *
157          * @return              An error code
158          * @param[in]   map                             The map to copy
159          * @param[in]   loadFactor              The maximum ratio of elements to buckets @n
160          *                                                              If it is @c 0, the default load factor(0.75) is used.
161          * @exception   E_SUCCESS                       The method is successful.
162          * @exception   E_INVALID_ARG           The specified @c loadFactor is negative.
163          * @exception   E_INVALID_OPERATION     The current state of the instance prohibits the execution of the specified operation, or
164          *                                                                      the @c map is modified during the operation of this method.
165          * @remarks             This method performs a shallow copy. It copies just the pointer; not the element itself.
166          * @see                 MultiHashMap()
167          */
168         result Construct(const IMultiMap& map, float loadFactor = 0.75);
169
170
171         /**
172          * Initializes a new instance of the %MultiHashMap class, with the specified initial capacity, load factor, hash code provider, and comparer.
173          *
174          * @since 2.0
175          *
176          * @return              An error code
177          * @param[in]   capacity        The initial capacity @n
178          *                                                      If it is @c 0, the default capacity (16) is used.
179          * @param[in]   loadFactor      The maximum ratio of elements to buckets @n
180          *                                                      If it is @c 0, the default load factor (0.75) is used.
181          * @param[in]   provider        An instance of the IHashCodeProvider derived class that supplies the hash codes
182          *                                                      for all keys in this map
183          * @param[in]   comparer        An instance of the IComparer derived class to use when comparing keys
184          * @exception   E_SUCCESS               The method is successful.
185          * @exception   E_INVALID_ARG   A specified input parameter is invalid, or
186          *                                                                the @c capacity or the @c loadFactor is negative.
187          * @remarks             The instances of hash code provider and comparer will not be deallocated later from this map.
188          * @see                 MultiHashMap()
189          */
190         result Construct(int capacity, float loadFactor, const IHashCodeProvider& provider, const IComparer& comparer);
191
192         /**
193          * Initializes a new instance of the %MultiHashMap class by copying the elements of the specified map,
194          * with the specified load factor, hash code provider, and comparer.
195          *
196          * @since 2.0
197          *
198          * @return              An error code
199          * @param[in]   map                     A map to copy
200          * @param[in]   loadFactor      The maximum ratio of elements to buckets @n
201          *                                                      If it is @c 0, the default load factor (0.75) is used.
202          * @param[in]   provider        An instance of the IHashCodeProvider derived class that supplies the hash codes
203          *                                                      for all keys in this map
204          * @param[in]   comparer        An instance of the IComparer derived class to use when comparing keys
205          * @exception   E_SUCCESS                       The method is successful.
206          * @exception   E_INVALID_ARG           A specified input parameter is invalid, or
207          *                                                                      the @c loadFactor is negative.
208          * @exception   E_INVALID_OPERATION     The current state of the instance prohibits the execution of the specified operation, or
209          *                                                                      the @c map is modified during the operation of this method.
210          * @remarks             This method performs a shallow copy. It copies just the pointer; not the element itself.
211          *                      The instances of hash code provider and comparer will not be deallocated later from this map.
212          * @see                 MultiHashMap()
213          */
214         result Construct(const IMultiMap& map, float loadFactor, const IHashCodeProvider& provider, const IComparer& comparer);
215
216         /**
217          * Adds the specified key-value pair to this map.
218          *
219          * @since 2.0
220          *
221          * @return              An error code
222          * @param[in]   pKey    The pointer to key to add
223          * @param[in]   pValue  The pointer to corresponding value to add
224          * @exception   E_SUCCESS                       The method is successful.
225          * @exception   E_OBJ_ALREADY_EXIST     The specified pair of @c pKey and @c pValue already exists.
226          * @exception   E_INVALID_ARG           A specified input parameter is invalid, or
227          *                                                                      the comparer has failed to compare the keys.
228          * @remarks             This method performs a shallow copy. It adds just the pointer; not the element itself.
229          * @see                 Remove()
230          */
231         virtual result Add(Object* pKey, Object* pValue);
232
233         /**
234          * Gets an enumerator of this map.
235          *
236          * @since 2.0
237          *
238          * @return              An enumerator (an instance of the IEnumerator derived class) of this map, @n
239          *                              else @c null if some exception occurs
240          * @remarks             If the key has multiple values, the enumeration proceeds as follows: {A: a}, {B: b}, {B: c}, {B, d}, {C: e}, ...
241          *                      The specific error code can be accessed using the GetLastResult() method.
242          * @see                 IEnumerator()
243          * @see                 IMapEnumerator()
244          */
245         virtual IEnumerator* GetEnumeratorN(void) const;
246
247         /**
248          * Gets an enumerator of this map.
249          *
250          * @since 2.0
251          *
252          * @return              An enumerator (an instance of the IMapEnumerator derived class) of this map, @n
253          *                              else @c null if some exception occurs
254          * @remarks             If the key has multiple values, the enumeration proceeds as follows: {A: a}, {B: b}, {B: c}, {B, d}, {C: e}, ...
255          *              The specific error code can be accessed using the GetLastResult() method.
256          * @see                 IEnumerator()
257          * @see                 IMapEnumerator()
258          */
259         virtual IMapEnumerator* GetMapEnumeratorN(void) const;
260
261         /**
262          * Gets an enumerator of the values associated with the specified key.
263          *
264          * @since 2.0
265          *
266          * @return              An enumerator (an instance of the IEnumerator derived class) of the values associated with the specified key, @n
267          *                              else @c null if some exception occurs
268          * @param[in]   key     A key to locate
269          * @exception   E_SUCCESS                       The method is successful.
270          * @exception   E_INVALID_ARG           A specified input parameter is invalid, or
271          *                                                                      the comparer has failed to compare the keys.
272          * @exception   E_OBJ_NOT_FOUND         The specified @c key is not found in the map.
273          * @remarks             The specific error code can be accessed using the GetLastResult() method.
274          * @see                 SetValue()
275          */
276         virtual IEnumerator* GetValuesN(const Object& key) const;
277
278         /**
279          * Gets a list of all unique keys in this map.
280          *
281          * @since 2.0
282          *
283          * @return              A list of all unique keys in this map
284          * @remarks             The %IList stores just the pointers to the elements in the map, not the elements themselves.
285          *                      The specific error code can be accessed using the GetLastResult() method.
286          * @see                 GetValuesN()
287          */
288         virtual IList* GetKeysN(void) const;
289
290         /**
291          * Gets a list of all the values in this map.
292          *
293          * @since 2.0
294          *
295          * @return              A list of all the values in this map
296          * @remarks             The IList stores just the pointers to the elements in the map, not the elements themselves.
297          *                      The specific error code can be accessed using the GetLastResult() method.
298          * @see                 GetKeysN()
299          */
300         virtual IList* GetValuesN(void) const;
301
302         /**
303          * Removes all the values with the specified key.
304          *
305          * @since 2.0
306          *
307          * @return              An error code
308          * @param[in]   key The key to remove
309          * @exception   E_SUCCESS                       The method is successful.
310          * @exception   E_INVALID_ARG           A specified input parameter is invalid, or
311          *                                                                      the comparer has failed to compare keys.
312          * @exception   E_OBJ_NOT_FOUND         The specified @c key is not found in the map.
313          * @see                 Add()
314          */
315         virtual result Remove(const Object& key);
316
317         /**
318          * Removes the specified value associated with the specified key.
319          *
320          * @since 2.0
321          *
322          * @return              An error code
323          * @param[in]   key The key whose mapping is to remove from the map
324          * @param[in]   value   The value to remove
325          * @exception   E_SUCCESS                       The method is successful.
326          * @exception   E_INVALID_ARG           A specified input parameter is invalid, or
327          *                                                                      the comparer has failed to compare the keys.
328          * @exception   E_OBJ_NOT_FOUND         The specified @c key and @c value pair is not found in the map.
329          * @remarks             The specified key is also removed if there are no more values associated with it.
330          * @see                 Add()
331          */
332         virtual result Remove(const Object& key, const Object& value);
333
334         /**
335          * Removes all the object pointers in the @c collection. @n
336          *
337          * @since 2.0
338          *
339          * @remarks             This method can be called before deleting @c collection.
340          */
341         virtual void RemoveAll(void);
342
343         /**
344          * Sets the value associated with the given key with a new value.
345          *
346          * @since 2.0
347          *
348          * @return              An error code
349          * @param[in]   key             The key for which the associated value needs to replace
350          * @param[in]   value   The value to replace
351          * @param[in]   pNewValue       The pointer to new value to replace the existing value
352          * @exception   E_SUCCESS                       The method is successful.
353          * @exception   E_INVALID_ARG           A specified input parameter is invalid, or
354          *                                                                      the comparer has failed to compare the keys.
355          * @exception   E_OBJ_NOT_FOUND         The specified @c key and @c value pair is not found in the map.
356          * @remarks             To add a new key-value pair, use the Add() method.
357          * @see                 Add()
358          * @see                 GetValuesN()
359          */
360         virtual result SetValue(const Object& key, const Object& value, Object* pNewValue);
361
362         /**
363          * Gets the number of values currently stored in this map.
364          *
365          * @since 2.0
366          *
367          * @return              The number of values currently stored in this map
368          */
369         virtual int GetCount(void) const;
370
371         /**
372          * Gets the number of values whose key matches the key.
373          *
374          * @since 2.0
375          *
376          * @return              An error code
377          * @param[in]   key     A key to locate
378          * @param[out]  count   The number of values whose key is the @c key
379          * @exception   E_SUCCESS                       The method is successful.
380          * @exception   E_INVALID_ARG           A specified input parameter is invalid, or
381          *                                                                      the comparer has failed to compare the keys.
382          * @exception   E_OBJ_NOT_FOUND         The specified @c key is not found in the map.
383          */
384         virtual result GetCount(const Object& key, int& count) const;
385
386         /**
387          * Checks whether the map contains the specified key and value.
388          *
389          * @since 2.0
390          *
391          * @return              @c true if the map contains the specified key and value pair, @n
392          *                              else @c false
393          * @param[in]   key     The key to locate
394          * @param[in]   value   The value to locate
395          * @exception   E_SUCCESS               The method is successful.
396          * @exception   E_INVALID_ARG   A specified input parameter is invalid, or
397          *                                                              the comparer has failed to compare the keys.
398          * @remarks             The specific error code can be accessed using the GetLastResult() method.
399          * @see                 ContainsKey()
400          * @see                 ContainsValue()
401          */
402         virtual bool Contains(const Object& key, const Object& value) const;
403
404         /**
405          * Checks whether the map contains the specified key.
406          *
407          * @since 2.0
408          *
409          * @return              @c true if the map contains the specified key, @n
410          *                              else @c false
411          * @param[in]   key     The key to locate
412          * @exception   E_SUCCESS               The method is successful.
413          * @exception   E_INVALID_ARG   A specified input parameter is invalid, or
414          *                                                              the comparer has failed to compare the keys.
415          * @remarks             The specific error code can be accessed using the GetLastResult() method.
416          * @see                 ContainsValue()
417          * @see                 Contains()
418          */
419         virtual bool ContainsKey(const Object& key) const;
420
421         /**
422          * Checks whether the map contains the specified value.
423          *
424          * @since 2.0
425          *
426          * @return              @c true if the map contains the specified value, @n
427          *                              else @c false
428          * @param[in]   value   The value to locate
429          *
430          * @see                         ContainsKey()
431          * @see                         Contains()
432          */
433         virtual bool ContainsValue(const Object& value) const;
434
435         /**
436          * Compares the specified instance to the current instance for equality.
437          *
438          * @since 2.0
439          *
440          * @return              @c true if the two instances are equal, @n
441          *                              @c false
442          * @param[in]   obj The object to compare with the current instance
443          * @remarks             This method returns @c true only if the specified object is also an instance of %MultiHashMap class,
444          *                              both maps have the same number of elements, and both maps contain the same elements.
445          */
446         virtual bool Equals(const Object& obj) const;
447
448         /**
449          * Gets the hash value of the current instance.
450          *
451          * @since 2.0
452          *
453          * @return      The hash value of the current instance
454          * @remarks     The two Tizen::Base::Object::Equals() instances must return the same hash value. For better performance, @n
455          *                      the used hash function must generate a random distribution for all inputs.
456          */
457         virtual int GetHashCode(void) const;
458
459         /**
460          * Gets the element deleter of the collection.
461          *
462          * @since 2.0
463          *
464          * @return              A function pointer to the existing element deleter
465          */
466         virtual DeleterFunctionType GetDeleter(void) const;
467
468 private:
469         /**
470          * The implementation of this copy constructor is intentionally blank and declared as private to prohibit copying of objects.
471          *
472          * @param[in]   map An instance of %MultiHashMap to initialize the current instance
473          */
474         MultiHashMap(const MultiHashMap& map);
475
476         /**
477          * The implementation of this copy assignment operator is intentionally blank and declared as private to prohibit copying of objects.
478          *
479          * @param[in]   map An instance of %MultiHashMap
480          */
481         MultiHashMap& operator =(const MultiHashMap& map);
482
483         /**
484          * Copies all the pairs from the specified map to this map.
485          *
486          * @return              An error code
487          * @param[in]   map The map to copy
488          * @exception   E_SUCCESS                       The method is successful.
489          * @exception   E_INVALID_OPERATION     The current state of the instance prohibits the execution of the specified operation. @n
490          *                                                                      The @c map is modified during the operation of this method.
491          */
492         result AddAll(const IMultiMap& map);
493
494         /**
495          * Gets a hash value for the specified object.
496          *
497          * @return              An @c int hash value for the specified object
498          * @param[in]   obj     The object to get hash value
499          */
500         int Hash(const Object& obj) const;
501
502         /**
503          * Rehashes the contents of this map into a new array with a
504          * larger capacity. @n
505          * This method is called automatically when the number of keys in this map reaches its threshold.
506          *
507          * @return              An error code
508          * @param[in]   newCapacity             The new capacity @n
509          *                                                              It must be a power of two and be greater than current capacity.
510          * @exception   E_SUCCESS                       The method is successful.
511          */
512         result Resize(int newCapacity);
513
514         /**
515          * Clears all key-value pairs in this map.
516          */
517         void Reset(void);
518
519         /**
520          * Sets the element deleter of the collection.
521          *
522          * @since 2.0
523          *
524          * @param[in]   deleter A function pointer to the element deleter to set
525          */
526         virtual void SetDeleter(DeleterFunctionType deleter);
527
528         _MultiHashMapEntry** __pTable;
529         int __count;
530         int __capacity;
531         float __loadFactor;
532         int __threshold;
533         IHashCodeProvider* __pProvider;
534         IComparer* __pComparer;
535         bool __needToRemoveProviderComparer;
536         int __modCount;
537         DeleterFunctionType __deleter;
538         static const int DEFAULT_CAPACITY = 16;
539         static const float DEFAULT_LOAD_FACTOR;
540
541         friend class _MultiHashMapEnumerator;
542         friend class _MultiHashMapImpl;
543         class _MultiHashMapImpl* __pMultiHashMapImpl;
544
545 }; // MultiHashMap
546
547 }}} // Tizen::Base::Collection
548
549 #endif //_FBASE_COL_MULTI_HASH_MAP_H_