fbxsdk/core/base/fbxhashmap.h Source File

fbxhashmap.h
Go to the documentation of this file.
1 /****************************************************************************************
2 
3  Copyright (C) 2015 Autodesk, Inc.
4  All rights reserved.
5 
6  Use of this software is subject to the terms of the Autodesk license agreement
7  provided at the time of installation or download, or which otherwise accompanies
8  this software in either electronic or hard copy form.
9 
10 ****************************************************************************************/
11 
13 #ifndef _FBXSDK_CORE_BASE_HASHMAP_H_
14 #define _FBXSDK_CORE_BASE_HASHMAP_H_
15 
16 #include <fbxsdk/fbxsdk_def.h>
17 
20 
21 #include <fbxsdk/fbxsdk_nsbegin.h>
22 
23 template<class T> class FbxNoOpDestruct { public: static inline void DoIt(T&) {} };
24 template<class T> class FbxPtrDestruct { public: static inline void DoIt(T& v) { FbxDelete(v); v = NULL; } };
25 
26 //True if equal, false otherwise
27 template<class T> class FbxDefaultComparator{ public: static inline bool CompareIt( const T& t1, const T& t2 ) { return t1 == t2; } };
28 
44 template< typename KEY, typename VALUE, typename HASH, class Destruct = FbxNoOpDestruct<VALUE>, class Comparator = FbxDefaultComparator<KEY> >
46 {
47 public:
48  typedef KEY KeyType;
49  typedef VALUE ValueType;
50  typedef HASH HashFunctorType;
51 
52 private:
53 
54  class ListItem
55  {
56  public:
57  ListItem* mNext;
58  ValueType mValue;
59  KeyType mKey;
60 
61  ListItem()
62  :
63  mNext(NULL)
64  {
65  }
66 
67  ~ListItem()
68  {
69  Destruct::DoIt(mValue);
70  }
71  };
72 
73 public:
77  class Iterator
78  {
79  public:
80 
81  typedef ListItem ListItemType;
83 
87  Iterator( const Iterator& pOther )
88  :
89  mMap( pOther.mMap ),
90  mBucketIndex( pOther.mBucketIndex ),
91  mCurrentItem( pOther.mCurrentItem )
92  {
93 
94  }
95 
99  ~Iterator(){};
100 
105  KeyValuePair operator*() const
106  {
107  KeyValuePair lItem;
108 
109  if( mCurrentItem )
110  {
111  lItem.mFirst = mCurrentItem->mKey;
112  lItem.mSecond = mCurrentItem->mValue;
113  return lItem;
114  }
115 
116  FBX_ASSERT_NOW("Accessing out of bounds iterator");
117 
118  return lItem;
119  }
120 
125  void Next()
126  {
127  if( !mCurrentItem )
128  return;
129 
130  if( mCurrentItem->mNext )
131  {
132  mCurrentItem = mCurrentItem->mNext;
133  return;
134  }
135  else
136  {
137  mBucketIndex++;
138  for( ; mBucketIndex < mMap->mBuckets.GetCount(); ++mBucketIndex )
139  {
140  if( mMap->mBuckets[ mBucketIndex ] )
141  {
142  mCurrentItem = mMap->mBuckets[ mBucketIndex ];
143  return;
144  }
145  }
146 
147  if( mBucketIndex >= mMap->mBuckets.GetCount() )
148  {
149  *this = mMap->End();
150  return;
151  }
152  }
153  }
154 
162  bool operator==( const Iterator& pOther ) const
163  {
164  return mCurrentItem == pOther.mCurrentItem &&
165  mBucketIndex == pOther.mBucketIndex &&
166  mMap == pOther.mMap;
167  }
168 
173  bool operator!=( const Iterator& pOther ) const
174  {
175  return !(*this == pOther);
176  }
177 
183  Iterator& operator=( const Iterator& pOther )
184  {
185  this->mBucketIndex = pOther.mBucketIndex;
186  this->mMap = pOther.mMap;
187  this->mCurrentItem = pOther.mCurrentItem;
188  return *this;
189  }
190 
191  private:
192  const FbxHashMap* mMap;
193 
194  int mBucketIndex;
195  ListItemType* mCurrentItem;
196 
197  Iterator(const FbxHashMap* pMap, int pBucketIndex, ListItemType* pCurrentItem)
198  :
199  mMap( pMap ),
200  mBucketIndex(pBucketIndex),
201  mCurrentItem(pCurrentItem)
202  {
203 
204  }
205 
206  friend class FbxHashMap;
207  };
208 
213  FbxHashMap( int pBucketSize )
214  {
215  mBuckets.Resize( pBucketSize );
216  }
217 
222  {
223  mBuckets.Resize(30);
224  }
225 
230  {
231  Clear();
232  mBuckets.Clear();
233  }
234 
238  void Clear()
239  {
240  for( int i = 0; i < mBuckets.GetCount(); ++i)
241  {
242  if( mBuckets[i] )
243  {
244  ListItem* lNext = mBuckets[i]->mNext;
245  while( lNext )
246  {
247  ListItem* lNextNext = lNext->mNext;
248  FbxDelete(lNext);
249  lNext = lNextNext;
250  }
251 
252  FbxDelete(mBuckets[i]);
253  mBuckets[i] = NULL;
254  }
255  }
256  }
257 
264  const Iterator Find( const KeyType& pKey ) const
265  {
266  unsigned int lIndex = mHashFunctor(pKey);
267  lIndex = lIndex % mBuckets.GetCount();
268  ListItem* lItem = mBuckets[lIndex];
269  while( lItem )
270  {
271  if( Comparator::CompareIt( lItem->mKey, pKey ) )
272  {
273  Iterator lIt( this, lIndex, lItem );
274  return lIt;
275  }
276  lItem = lItem->mNext;
277  }
278 
279  return End();
280  }
281 
287  VALUE Remove( const KEY& pKey )
288  {
289  unsigned int lIndex = mHashFunctor(pKey);
290  lIndex = lIndex % mBuckets.GetCount();
291  ListItem* lItem = mBuckets.GetAt(lIndex);
292  ListItem* lLastItem = NULL;
293 
294  while( lItem )
295  {
296  if( lItem->mKey == pKey )
297  {
298  if( lLastItem )
299  lLastItem->mNext = lItem->mNext;
300 
301  if( mBuckets.GetAt(lIndex) == lItem )
302  mBuckets.SetAt(lIndex, lItem->mNext );
303 
304  VALUE lValue = lItem->mValue;
305  FbxDelete(lItem);
306 
307  return lValue;
308  }
309 
310  lLastItem = lItem;
311  lItem = lItem->mNext;
312  }
313 
314  return VALUE();
315  }
316 
324  ValueType& operator[]( const KeyType& pKey )
325  {
326  unsigned int lIndex = 0;
327  Iterator lIt = InternalFind( pKey, lIndex);
328  if( lIt != End() )
329  {
330  return lIt.mCurrentItem->mValue;
331  }
332 
333  lIndex = lIndex % mBuckets.GetCount();
334  ListItem* lItem = FbxNew< ListItem >();
335  lItem->mNext = NULL;
336  lItem->mKey = pKey;
337 
338  if( !mBuckets.GetAt(lIndex) )
339  {
340  mBuckets.SetAt(lIndex, lItem);
341  }
342  else
343  {
344  lItem->mNext = mBuckets.GetAt(lIndex);
345  mBuckets.SetAt(lIndex, lItem);
346  }
347 
348  return lItem->mValue;
349  }
350 
354  Iterator Start() const
355  {
356  for( int i = 0; i < mBuckets.GetCount(); ++i )
357  {
358  if( mBuckets[i] )
359  {
360  Iterator lIt( this, i, mBuckets[i] );
361  return lIt;
362  }
363  }
364 
365  return End();
366  }
367 
372  Iterator End() const
373  {
374  Iterator lIt( this, 0, NULL );
375  return lIt;
376  }
377 
378 private:
379 
380  // Avoid calculating the hashvalue twice
381  const Iterator InternalFind( const KeyType& pKey, unsigned int& pOutCalculatedIndex ) const
382  {
383  pOutCalculatedIndex = mHashFunctor(pKey);
384  unsigned int lIndex = pOutCalculatedIndex % mBuckets.GetCount();
385  ListItem* lItem = mBuckets[lIndex];
386  while( lItem )
387  {
388  if( Comparator::CompareIt( lItem->mKey, pKey ) )
389  {
390  Iterator lIt( this, lIndex, lItem );
391  return lIt;
392  }
393  lItem = lItem->mNext;
394  }
395 
396  return End();
397  }
398 
399 
400  // not implemented yet!
401  FbxHashMap( const FbxHashMap& pOther ) {};
402 
403  FbxArray<ListItem*> mBuckets;
404  HashFunctorType mHashFunctor;
405 
406  friend class Iterator;
407 };
408 
409 #include <fbxsdk/fbxsdk_nsend.h>
410 
411 #endif /* _FBXSDK_CORE_BASE_HASHMAP_H_ */
FbxPair< KeyType, ValueType > KeyValuePair
Definition: fbxhashmap.h:82
FBX SDK environment definition.
~Iterator()
Destructor.
Definition: fbxhashmap.h:99
static void DoIt(T &v)
Definition: fbxhashmap.h:24
This object represents a standard hash map.
Definition: fbxhashmap.h:45
#define NULL
Definition: fbxarch.h:210
static void DoIt(T &)
Definition: fbxhashmap.h:23
Iterator(const Iterator &pOther)
Copy constructor.
Definition: fbxhashmap.h:87
Iterator & operator=(const Iterator &pOther)
Assign the current iterator to the one on the right hand side of the operator.
Definition: fbxhashmap.h:183
T GetAt(const int pIndex) const
Retrieve a copy of the element at given index position in the array.
Definition: fbxarray.h:139
ListItem ListItemType
Definition: fbxhashmap.h:81
void FbxDelete(T *p)
Deletion policy for pointer template classes that uses the FbxDelete() function.
Definition: fbxnew.h:341
void Clear()
Reset the number of element to zero and free the memory allocated.
Definition: fbxarray.h:350
void Next()
Advances the iterator to the next keyvaluepair in the hashmap.
Definition: fbxhashmap.h:125
KeyValuePair operator*() const
Used to dereference an iterator and give it a behavior more similar to a pointer. ...
Definition: fbxhashmap.h:105
KEY KeyType
Definition: fbxhashmap.h:48
Iterator End() const
Returns an iterator pointing on the last element in the map.
Definition: fbxhashmap.h:372
Iterate through every element in a hash map.
Definition: fbxhashmap.h:77
ValueType & operator[](const KeyType &pKey)
Add or retrieve a KeyValuePair from the Hashmap.
Definition: fbxhashmap.h:324
void SetAt(const int pIndex, const T &pElement)
Set the element at given position in the array.
Definition: fbxarray.h:212
This class template holds a pair of objects.
Definition: fbxpair.h:22
~FbxHashMap()
Clear all elements in the hash map before destroying itself.
Definition: fbxhashmap.h:229
const Iterator Find(const KeyType &pKey) const
Find an element in the hashmap.
Definition: fbxhashmap.h:264
FbxHashMap()
Construct a FbxHashMap with the default maximum number of elements (30)
Definition: fbxhashmap.h:221
VALUE ValueType
Definition: fbxhashmap.h:49
VALUE Remove(const KEY &pKey)
Remove an element in the hashmap.
Definition: fbxhashmap.h:287
bool operator!=(const Iterator &pOther) const
Check inequivalence between 2 iterators.
Definition: fbxhashmap.h:173
Second mSecond
The second object in the pair.
Definition: fbxpair.h:57
FbxHashMap(int pBucketSize)
Construct a FbxHashMap with an user-defined maximum number of elements.
Definition: fbxhashmap.h:213
friend class Iterator
Definition: fbxhashmap.h:406
bool operator==(const Iterator &pOther) const
Check equivalence between two iterators.
Definition: fbxhashmap.h:162
bool Resize(const int pSize)
Inserts or erases elements at the end such that Size() becomes pSize, increasing capacity if needed...
Definition: fbxarray.h:297
First mFirst
The first object in the pair.
Definition: fbxpair.h:56
Iterator Start() const
Returns an iterator pointing on the first non-null element in the map.
Definition: fbxhashmap.h:354
HASH HashFunctorType
Definition: fbxhashmap.h:50
static bool CompareIt(const T &t1, const T &t2)
Definition: fbxhashmap.h:27
void Clear()
Calls operator delete on all elements of the hashmap, de-allocating all memory and destroying them...
Definition: fbxhashmap.h:238