• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

DS_Map.h

Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 #ifndef __RAKNET_MAP_H
00011 #define __RAKNET_MAP_H
00012 
00013 #include "DS_OrderedList.h"
00014 #include "Export.h"
00015 #include "RakMemoryOverride.h"
00016 #include "RakAssert.h"
00017 
00018 // If I want to change this to a red-black tree, this is a good site: http://www.cs.auckland.ac.nz/software/AlgAnim/red_black.html
00019 // This makes insertions and deletions faster.  But then traversals are slow, while they are currently fast.
00020 
00023 namespace DataStructures
00024 {
00027         template <class key_type>
00028                 int defaultMapKeyComparison(const key_type &a, const key_type &b)
00029         {
00030                 if (a<b) return -1; if (a==b) return 0; return 1;
00031         }
00032 
00034         template <class key_type, class data_type, int (*key_comparison_func)(const key_type&, const key_type&)=defaultMapKeyComparison<key_type> >
00035         class RAK_DLL_EXPORT Map
00036         {
00037         public:
00038                 static void IMPLEMENT_DEFAULT_COMPARISON(void) {DataStructures::defaultMapKeyComparison<key_type>(key_type(),key_type());}
00039 
00040                 struct MapNode
00041                 {
00042                         MapNode() {}
00043                         MapNode(key_type _key, data_type _data) : mapNodeKey(_key), mapNodeData(_data) {}
00044                         MapNode& operator = ( const MapNode& input ) {mapNodeKey=input.mapNodeKey; mapNodeData=input.mapNodeData; return *this;}
00045                         MapNode( const MapNode & input) {mapNodeKey=input.mapNodeKey; mapNodeData=input.mapNodeData;}
00046                         key_type mapNodeKey;
00047                         data_type mapNodeData;
00048                 };
00049 
00050                 // Has to be a static because the comparison callback for DataStructures::OrderedList is a C function
00051                 static int NodeComparisonFunc(const key_type &a, const MapNode &b)
00052                 {
00053 #ifdef _MSC_VER
00054 #pragma warning( disable : 4127 ) // warning C4127: conditional expression is constant
00055 #endif
00056                         return key_comparison_func(a, b.mapNodeKey);
00057                 }
00058 
00059                 Map();
00060                 ~Map();
00061                 Map( const Map& original_copy );
00062                 Map& operator= ( const Map& original_copy );
00063 
00064                 data_type& Get(const key_type &key) const; 
00065                 data_type Pop(const key_type &key);
00066                 // Add if needed
00067                 void Set(const key_type &key, const data_type &data);
00068                 // Must already exist
00069                 void SetExisting(const key_type &key, const data_type &data);
00070                 // Must add
00071                 void SetNew(const key_type &key, const data_type &data);
00072                 bool Has(const key_type &key) const;
00073                 bool Delete(const key_type &key);
00074                 data_type& operator[] ( const unsigned int position ) const;
00075                 key_type GetKeyAtIndex( const unsigned int position ) const;
00076                 unsigned GetIndexAtKey( const key_type &key );
00077                 void RemoveAtIndex(const unsigned index);
00078                 void Clear(void);
00079                 unsigned Size(void) const;
00080 
00081         protected:
00082                 DataStructures::OrderedList< key_type,MapNode,&Map::NodeComparisonFunc > mapNodeList;
00083 
00084                 void SaveLastSearch(const key_type &key, unsigned index) const;
00085                 bool HasSavedSearchResult(const key_type &key) const;
00086 
00087                 unsigned lastSearchIndex;
00088                 key_type lastSearchKey;
00089                 bool lastSearchIndexValid;
00090         };
00091 
00092         template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
00093         Map<key_type, data_type, key_comparison_func>::Map()
00094         {
00095                 lastSearchIndexValid=false;
00096         }
00097 
00098         template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
00099         Map<key_type, data_type, key_comparison_func>::~Map()
00100         {
00101                 Clear();
00102         }
00103 
00104         template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
00105         Map<key_type, data_type, key_comparison_func>::Map( const Map& original_copy )
00106         {
00107                 mapNodeList=original_copy.mapNodeList;
00108         lastSearchIndex=original_copy.lastSearchIndex;
00109                 lastSearchKey=original_copy.lastSearchKey;
00110                 lastSearchIndexValid=original_copy.lastSearchIndexValid;
00111         }
00112 
00113     template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
00114         Map<key_type, data_type, key_comparison_func>& Map<key_type, data_type, key_comparison_func>::operator= ( const Map& original_copy )
00115         {
00116                 mapNodeList=original_copy.mapNodeList;
00117                 lastSearchIndex=original_copy.lastSearchIndex;
00118                 lastSearchKey=original_copy.lastSearchKey;
00119                 lastSearchIndexValid=original_copy.lastSearchIndexValid;
00120                 return *this;
00121         }
00122 
00123         template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
00124         data_type& Map<key_type, data_type, key_comparison_func>::Get(const key_type &key) const
00125         {
00126                 if (HasSavedSearchResult(key))
00127                         return mapNodeList[lastSearchIndex].mapNodeData;
00128 
00129                 bool objectExists;
00130                 unsigned index;
00131                 index=mapNodeList.GetIndexFromKey(key, &objectExists);
00132                 RakAssert(objectExists);
00133                 SaveLastSearch(key,index);
00134                 return mapNodeList[index].mapNodeData;
00135         }
00136 
00137         template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
00138         unsigned Map<key_type, data_type, key_comparison_func>::GetIndexAtKey( const key_type &key )
00139         {
00140                 if (HasSavedSearchResult(key))
00141                         return lastSearchIndex;
00142 
00143                 bool objectExists;
00144                 unsigned index;
00145                 index=mapNodeList.GetIndexFromKey(key, &objectExists);
00146                 if (objectExists==false)
00147                 {
00148                         RakAssert(objectExists);
00149                 }
00150                 SaveLastSearch(key,index);
00151                 return index;
00152         }
00153 
00154         template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
00155         void Map<key_type, data_type, key_comparison_func>::RemoveAtIndex(const unsigned index)
00156         {
00157                 mapNodeList.RemoveAtIndex(index);
00158                 lastSearchIndexValid=false;
00159         }
00160 
00161         template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
00162                 data_type Map<key_type, data_type, key_comparison_func>::Pop(const key_type &key)
00163         {
00164                 bool objectExists;
00165                 unsigned index;
00166                 if (HasSavedSearchResult(key))
00167                         index=lastSearchIndex;
00168                 else
00169                 {
00170                         index=mapNodeList.GetIndexFromKey(key, &objectExists);
00171                         RakAssert(objectExists);
00172                 }               
00173                 data_type tmp = mapNodeList[index].mapNodeData;
00174                 mapNodeList.RemoveAtIndex(index);
00175                 lastSearchIndexValid=false;
00176                 return tmp;
00177         }
00178 
00179         template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
00180         void Map<key_type, data_type, key_comparison_func>::Set(const key_type &key, const data_type &data)
00181         {
00182                 bool objectExists;
00183                 unsigned index;
00184 
00185                 if (HasSavedSearchResult(key))
00186                 {
00187                         mapNodeList[lastSearchIndex].mapNodeData=data;
00188                         return;
00189                 }
00190                 
00191                 index=mapNodeList.GetIndexFromKey(key, &objectExists);
00192 
00193                 if (objectExists)
00194                 {
00195                         SaveLastSearch(key,index);
00196                         mapNodeList[index].mapNodeData=data;
00197                 }
00198                 else
00199                 {
00200                         SaveLastSearch(key,mapNodeList.Insert(key,MapNode(key,data), true, __FILE__,__LINE__));
00201                 }
00202         }
00203 
00204         template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
00205         void Map<key_type, data_type, key_comparison_func>::SetExisting(const key_type &key, const data_type &data)
00206         {
00207                 bool objectExists;
00208                 unsigned index;
00209 
00210                 if (HasSavedSearchResult(key))
00211                 {
00212                         index=lastSearchIndex;
00213                 }
00214                 else
00215                 {
00216                         index=mapNodeList.GetIndexFromKey(key, &objectExists);
00217                         RakAssert(objectExists);
00218                         SaveLastSearch(key,index);
00219                 }               
00220 
00221                 mapNodeList[index].mapNodeData=data;
00222         }       
00223 
00224         template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
00225         void Map<key_type, data_type, key_comparison_func>::SetNew(const key_type &key, const data_type &data)
00226         {
00227 #ifdef _DEBUG
00228                 bool objectExists;
00229                 mapNodeList.GetIndexFromKey(key, &objectExists);
00230                 RakAssert(objectExists==false);
00231 #endif
00232                 SaveLastSearch(key,mapNodeList.Insert(key,MapNode(key,data), true, __FILE__,__LINE__));
00233         }
00234 
00235         template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
00236         bool Map<key_type, data_type, key_comparison_func>::Has(const key_type &key) const
00237         {
00238                 if (HasSavedSearchResult(key))
00239                         return true;
00240 
00241                 bool objectExists;
00242                 unsigned index;
00243                 index=mapNodeList.GetIndexFromKey(key, &objectExists);
00244                 if (objectExists)
00245                         SaveLastSearch(key,index);
00246                 return objectExists;
00247         }
00248 
00249         template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
00250         bool Map<key_type, data_type, key_comparison_func>::Delete(const key_type &key)
00251         {
00252                 if (HasSavedSearchResult(key))
00253                 {
00254                         lastSearchIndexValid=false;
00255                         mapNodeList.RemoveAtIndex(lastSearchIndex);   
00256                         return true;
00257                 }
00258 
00259                 bool objectExists;
00260                 unsigned index;
00261                 index=mapNodeList.GetIndexFromKey(key, &objectExists);
00262                 if (objectExists)
00263                 {
00264                         lastSearchIndexValid=false;
00265                         mapNodeList.RemoveAtIndex(index);
00266                         return true;
00267                 }
00268                 else
00269                         return false;
00270         }
00271 
00272         template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
00273         void Map<key_type, data_type, key_comparison_func>::Clear(void)
00274         {
00275                 lastSearchIndexValid=false;
00276                 mapNodeList.Clear(false, __FILE__, __LINE__);
00277         }
00278 
00279         template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
00280         data_type& Map<key_type, data_type, key_comparison_func>::operator[]( const unsigned int position ) const
00281         {
00282                 return mapNodeList[position].mapNodeData;
00283         }
00284 
00285         template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
00286                 key_type Map<key_type, data_type, key_comparison_func>::GetKeyAtIndex( const unsigned int position ) const
00287         {
00288                 return mapNodeList[position].mapNodeKey;
00289         }
00290 
00291         template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
00292         unsigned Map<key_type, data_type, key_comparison_func>::Size(void) const
00293         {
00294                 return mapNodeList.Size();
00295         }
00296 
00297         template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
00298         void Map<key_type, data_type, key_comparison_func>::SaveLastSearch(const key_type &key, const unsigned index) const
00299         {
00300                 (void) key;
00301                 (void) index;
00302 
00303                 /*
00304                 lastSearchIndex=index;
00305                 lastSearchKey=key;
00306                 lastSearchIndexValid=true;
00307                 */
00308         }
00309 
00310         template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
00311         bool Map<key_type, data_type, key_comparison_func>::HasSavedSearchResult(const key_type &key) const
00312         {
00313                 (void) key;
00314 
00315                 // Not threadsafe!
00316                 return false;
00317                 // return lastSearchIndexValid && key_comparison_func(key,lastSearchKey)==0;
00318         }
00319 }
00320 
00321 #endif

Generated on Thu Sep 30 2010 01:27:22 for RakNet by  doxygen 1.7.1