SLikeNet 0.1.3

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DS_Map.h
Go to the documentation of this file.
1 /*
2 * Original work: Copyright (c) 2014, Oculus VR, Inc.
3 * All rights reserved.
4 *
5 * This source code is licensed under the BSD-style license found in the
6 * RakNet License.txt file in the licenses directory of this source tree. An additional grant
7 * of patent rights can be found in the RakNet Patents.txt file in the same directory.
8 *
9 *
10 * Modified work: Copyright (c) 2016-2017, SLikeSoft UG (haftungsbeschränkt)
11 *
12 * This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
13 * license found in the license.txt file in the root directory of this source tree.
14 */
15
20
21
22 #ifndef __RAKNET_MAP_H
23 #define __RAKNET_MAP_H
24
25 #include "DS_OrderedList.h"
26 #include "Export.h"
27 #include "memoryoverride.h"
28 #include "assert.h"
29
30 // 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
31 // This makes insertions and deletions faster. But then traversals are slow, while they are currently fast.
32
35 namespace DataStructures
36 {
39 template <class key_type>
40 int defaultMapKeyComparison(const key_type &a, const key_type &b)
41 {
42 if (a<b) return -1; if (a==b) return 0; return 1;
43 }
44
46 template <class key_type, class data_type, int (*key_comparison_func)(const key_type&, const key_type&)=defaultMapKeyComparison<key_type> >
47 class RAK_DLL_EXPORT Map
48 {
49 public:
50 static void IMPLEMENT_DEFAULT_COMPARISON(void) {DataStructures::defaultMapKeyComparison<key_type>(key_type(),key_type());}
51
52 struct MapNode
53 {
54 MapNode() {}
55 MapNode(key_type _key, data_type _data) : mapNodeKey(_key), mapNodeData(_data) {}
56 MapNode& operator = ( const MapNode& input ) {mapNodeKey=input.mapNodeKey; mapNodeData=input.mapNodeData; return *this;}
57 MapNode( const MapNode & input) {mapNodeKey=input.mapNodeKey; mapNodeData=input.mapNodeData;}
58 key_type mapNodeKey;
59 data_type mapNodeData;
60 };
61
62 // Has to be a static because the comparison callback for DataStructures::OrderedList is a C function
63 static int NodeComparisonFunc(const key_type &a, const MapNode &b)
64 {
65 return key_comparison_func(a, b.mapNodeKey);
66 }
67
68 Map();
69 ~Map();
70 Map( const Map& original_copy );
71 Map& operator= ( const Map& original_copy );
72
73 data_type& Get(const key_type &key) const;
74 data_type Pop(const key_type &key);
75 // Add if needed
76 void Set(const key_type &key, const data_type &data);
77 // Must already exist
78 void SetExisting(const key_type &key, const data_type &data);
79 // Must add
80 void SetNew(const key_type &key, const data_type &data);
81 bool Has(const key_type &key) const;
82 bool Delete(const key_type &key);
83 data_type& operator[] ( const unsigned int position ) const;
84 key_type GetKeyAtIndex( const unsigned int position ) const;
85 unsigned GetIndexAtKey( const key_type &key );
86 void RemoveAtIndex(const unsigned index);
87 void Clear(void);
88 unsigned Size(void) const;
89
90 protected:
91 DataStructures::OrderedList< key_type,MapNode,&Map::NodeComparisonFunc > mapNodeList;
92
93 void SaveLastSearch(const key_type &key, unsigned index) const;
94 bool HasSavedSearchResult(const key_type &key) const;
95
96 unsigned lastSearchIndex;
97 key_type lastSearchKey;
98 bool lastSearchIndexValid;
99 };
100
101 template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
102 Map<key_type, data_type, key_comparison_func>::Map()
103 {
104 lastSearchIndexValid=false;
105 }
106
107 template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
108 Map<key_type, data_type, key_comparison_func>::~Map()
109 {
110 Clear();
111 }
112
113 template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
114 Map<key_type, data_type, key_comparison_func>::Map( const Map& original_copy )
115 {
116 mapNodeList=original_copy.mapNodeList;
117 lastSearchIndex=original_copy.lastSearchIndex;
118 lastSearchKey=original_copy.lastSearchKey;
119 lastSearchIndexValid=original_copy.lastSearchIndexValid;
120 }
121
122 template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
123 Map<key_type, data_type, key_comparison_func>& Map<key_type, data_type, key_comparison_func>::operator= ( const Map& original_copy )
124 {
125 mapNodeList=original_copy.mapNodeList;
126 lastSearchIndex=original_copy.lastSearchIndex;
127 lastSearchKey=original_copy.lastSearchKey;
128 lastSearchIndexValid=original_copy.lastSearchIndexValid;
129 return *this;
130 }
131
132 template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
133 data_type& Map<key_type, data_type, key_comparison_func>::Get(const key_type &key) const
134 {
135 if (HasSavedSearchResult(key))
136 return mapNodeList[lastSearchIndex].mapNodeData;
137
138 bool objectExists;
139 unsigned index;
140 index=mapNodeList.GetIndexFromKey(key, &objectExists);
141 RakAssert(objectExists);
142 SaveLastSearch(key,index);
143 return mapNodeList[index].mapNodeData;
144 }
145
146 template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
147 unsigned Map<key_type, data_type, key_comparison_func>::GetIndexAtKey( const key_type &key )
148 {
149 if (HasSavedSearchResult(key))
150 return lastSearchIndex;
151
152 bool objectExists;
153 unsigned index;
154 index=mapNodeList.GetIndexFromKey(key, &objectExists);
155 if (objectExists==false)
156 {
157 RakAssert(objectExists);
158 }
159 SaveLastSearch(key,index);
160 return index;
161 }
162
163 template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
164 void Map<key_type, data_type, key_comparison_func>::RemoveAtIndex(const unsigned index)
165 {
166 mapNodeList.RemoveAtIndex(index);
167 lastSearchIndexValid=false;
168 }
169
170 template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
171 data_type Map<key_type, data_type, key_comparison_func>::Pop(const key_type &key)
172 {
173 bool objectExists;
174 unsigned index;
175 if (HasSavedSearchResult(key))
176 index=lastSearchIndex;
177 else
178 {
179 index=mapNodeList.GetIndexFromKey(key, &objectExists);
180 RakAssert(objectExists);
181 }
182 data_type tmp = mapNodeList[index].mapNodeData;
183 mapNodeList.RemoveAtIndex(index);
184 lastSearchIndexValid=false;
185 return tmp;
186 }
187
188 template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
189 void Map<key_type, data_type, key_comparison_func>::Set(const key_type &key, const data_type &data)
190 {
191 bool objectExists;
192 unsigned index;
193
194 if (HasSavedSearchResult(key))
195 {
196 mapNodeList[lastSearchIndex].mapNodeData=data;
197 return;
198 }
199
200 index=mapNodeList.GetIndexFromKey(key, &objectExists);
201
202 if (objectExists)
203 {
204 SaveLastSearch(key,index);
205 mapNodeList[index].mapNodeData=data;
206 }
207 else
208 {
209 SaveLastSearch(key,mapNodeList.Insert(key,MapNode(key,data), true, _FILE_AND_LINE_));
210 }
211 }
212
213 template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
214 void Map<key_type, data_type, key_comparison_func>::SetExisting(const key_type &key, const data_type &data)
215 {
216 bool objectExists;
217 unsigned index;
218
219 if (HasSavedSearchResult(key))
220 {
221 index=lastSearchIndex;
222 }
223 else
224 {
225 index=mapNodeList.GetIndexFromKey(key, &objectExists);
226 RakAssert(objectExists);
227 SaveLastSearch(key,index);
228 }
229
230 mapNodeList[index].mapNodeData=data;
231 }
232
233 template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
234 void Map<key_type, data_type, key_comparison_func>::SetNew(const key_type &key, const data_type &data)
235 {
236 #ifdef _DEBUG
237 bool objectExists;
238 mapNodeList.GetIndexFromKey(key, &objectExists);
239 RakAssert(objectExists==false);
240 #endif
241 SaveLastSearch(key,mapNodeList.Insert(key,MapNode(key,data), true, _FILE_AND_LINE_));
242 }
243
244 template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
245 bool Map<key_type, data_type, key_comparison_func>::Has(const key_type &key) const
246 {
247 if (HasSavedSearchResult(key))
248 return true;
249
250 bool objectExists;
251 unsigned index;
252 index=mapNodeList.GetIndexFromKey(key, &objectExists);
253 if (objectExists)
254 SaveLastSearch(key,index);
255 return objectExists;
256 }
257
258 template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
259 bool Map<key_type, data_type, key_comparison_func>::Delete(const key_type &key)
260 {
261 if (HasSavedSearchResult(key))
262 {
263 lastSearchIndexValid=false;
264 mapNodeList.RemoveAtIndex(lastSearchIndex);
265 return true;
266 }
267
268 bool objectExists;
269 unsigned index;
270 index=mapNodeList.GetIndexFromKey(key, &objectExists);
271 if (objectExists)
272 {
273 lastSearchIndexValid=false;
274 mapNodeList.RemoveAtIndex(index);
275 return true;
276 }
277 else
278 return false;
279 }
280
281 template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
282 void Map<key_type, data_type, key_comparison_func>::Clear(void)
283 {
284 lastSearchIndexValid=false;
285 mapNodeList.Clear(false, _FILE_AND_LINE_);
286 }
287
288 template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
289 data_type& Map<key_type, data_type, key_comparison_func>::operator[]( const unsigned int position ) const
290 {
291 return mapNodeList[position].mapNodeData;
292 }
293
294 template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
295 key_type Map<key_type, data_type, key_comparison_func>::GetKeyAtIndex( const unsigned int position ) const
296 {
297 return mapNodeList[position].mapNodeKey;
298 }
299
300 template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
301 unsigned Map<key_type, data_type, key_comparison_func>::Size(void) const
302 {
303 return mapNodeList.Size();
304 }
305
306 template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
307 void Map<key_type, data_type, key_comparison_func>::SaveLastSearch(const key_type &key, const unsigned index) const
308 {
309 (void) key;
310 (void) index;
311
312 /*
313 lastSearchIndex=index;
314 lastSearchKey=key;
315 lastSearchIndexValid=true;
316 */
317 }
318
319 template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
320 bool Map<key_type, data_type, key_comparison_func>::HasSavedSearchResult(const key_type &key) const
321 {
322 (void) key;
323
324 // Not threadsafe!
325 return false;
326 // return lastSearchIndexValid && key_comparison_func(key,lastSearchKey)==0;
327 }
328 }
329
330 #endif