Shadowrun: Awakened 29 September 2011 - Build 871
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_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.

GNU Lesser General Public License 3 Sourceforge.net