![]() |
Shadowrun: Awakened 29 September 2011 - Build 871
|
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_AND_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_AND_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_AND_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
Copyright © 2007-2010 by The Shadowrun: Awakened Team. This work is licensed under the GNU Lesser General Public License 3.