diff options
author | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
commit | 38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch) | |
tree | adca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/llcommon/llptrskipmap.h | |
parent | README.txt (diff) | |
download | meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2 meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz |
Second Life viewer sources 1.13.2.12
Diffstat (limited to 'linden/indra/llcommon/llptrskipmap.h')
-rw-r--r-- | linden/indra/llcommon/llptrskipmap.h | 1238 |
1 files changed, 1238 insertions, 0 deletions
diff --git a/linden/indra/llcommon/llptrskipmap.h b/linden/indra/llcommon/llptrskipmap.h new file mode 100644 index 0000000..d4e4de3 --- /dev/null +++ b/linden/indra/llcommon/llptrskipmap.h | |||
@@ -0,0 +1,1238 @@ | |||
1 | /** | ||
2 | * @file llptrskipmap.h | ||
3 | * @brief Just like a LLSkipMap, but since it's pointers, you can call | ||
4 | * deleteAllData | ||
5 | * | ||
6 | * Copyright (c) 2003-2007, Linden Research, Inc. | ||
7 | * | ||
8 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
9 | * to you under the terms of the GNU General Public License, version 2.0 | ||
10 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
11 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
12 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
13 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
14 | * | ||
15 | * There are special exceptions to the terms and conditions of the GPL as | ||
16 | * it is applied to this Source Code. View the full text of the exception | ||
17 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
18 | * online at http://secondlife.com/developers/opensource/flossexception | ||
19 | * | ||
20 | * By copying, modifying or distributing this software, you acknowledge | ||
21 | * that you have read and understood your obligations described above, | ||
22 | * and agree to abide by those obligations. | ||
23 | * | ||
24 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
25 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
26 | * COMPLETENESS OR PERFORMANCE. | ||
27 | */ | ||
28 | #ifndef LL_LLPTRSKIPMAP_H | ||
29 | #define LL_LLPTRSKIPMAP_H | ||
30 | |||
31 | #include "llerror.h" | ||
32 | #include "llrand.h" | ||
33 | |||
34 | template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH = 8> | ||
35 | class LLPtrSkipMapNode | ||
36 | { | ||
37 | public: | ||
38 | LLPtrSkipMapNode() | ||
39 | { | ||
40 | S32 i; | ||
41 | for (i = 0; i < BINARY_DEPTH; i++) | ||
42 | { | ||
43 | mForward[i] = NULL; | ||
44 | } | ||
45 | |||
46 | U8 *zero = (U8 *)&mIndex; | ||
47 | |||
48 | for (i = 0; i < (S32)sizeof(INDEX_T); i++) | ||
49 | { | ||
50 | *(zero + i) = 0; | ||
51 | } | ||
52 | |||
53 | zero = (U8 *)&mData; | ||
54 | |||
55 | for (i = 0; i < (S32)sizeof(DATA_T); i++) | ||
56 | { | ||
57 | *(zero + i) = 0; | ||
58 | } | ||
59 | } | ||
60 | |||
61 | LLPtrSkipMapNode(const INDEX_T &index) | ||
62 | : mIndex(index) | ||
63 | { | ||
64 | |||
65 | S32 i; | ||
66 | for (i = 0; i < BINARY_DEPTH; i++) | ||
67 | { | ||
68 | mForward[i] = NULL; | ||
69 | } | ||
70 | |||
71 | U8 *zero = (U8 *)&mData; | ||
72 | |||
73 | for (i = 0; i < (S32)sizeof(DATA_T); i++) | ||
74 | { | ||
75 | *(zero + i) = 0; | ||
76 | } | ||
77 | } | ||
78 | |||
79 | LLPtrSkipMapNode(const INDEX_T &index, DATA_T datap) | ||
80 | : mIndex(index) | ||
81 | { | ||
82 | |||
83 | S32 i; | ||
84 | for (i = 0; i < BINARY_DEPTH; i++) | ||
85 | { | ||
86 | mForward[i] = NULL; | ||
87 | } | ||
88 | |||
89 | mData = datap; | ||
90 | } | ||
91 | |||
92 | ~LLPtrSkipMapNode() | ||
93 | { | ||
94 | } | ||
95 | |||
96 | // delete associated data and NULLs out pointer | ||
97 | void deleteData() | ||
98 | { | ||
99 | delete mData; | ||
100 | mData = 0; | ||
101 | } | ||
102 | |||
103 | // NULLs out pointer | ||
104 | void removeData() | ||
105 | { | ||
106 | mData = 0; | ||
107 | } | ||
108 | |||
109 | INDEX_T mIndex; | ||
110 | DATA_T mData; | ||
111 | LLPtrSkipMapNode *mForward[BINARY_DEPTH]; | ||
112 | |||
113 | private: | ||
114 | // Disallow copying of LLPtrSkipMapNodes by not implementing these methods. | ||
115 | LLPtrSkipMapNode(const LLPtrSkipMapNode &); | ||
116 | LLPtrSkipMapNode &operator=(const LLPtrSkipMapNode &rhs); | ||
117 | }; | ||
118 | |||
119 | //--------------------------------------------------------------------------- | ||
120 | |||
121 | template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH = 8> | ||
122 | class LLPtrSkipMap | ||
123 | { | ||
124 | public: | ||
125 | typedef BOOL (*compare)(const DATA_T& first, const DATA_T& second); | ||
126 | typedef compare insert_func; | ||
127 | typedef compare equals_func; | ||
128 | |||
129 | void init(); | ||
130 | |||
131 | // basic constructor | ||
132 | LLPtrSkipMap(); | ||
133 | |||
134 | // basic constructor including sorter | ||
135 | LLPtrSkipMap(insert_func insert_first, equals_func equals); | ||
136 | |||
137 | ~LLPtrSkipMap(); | ||
138 | |||
139 | void setInsertFirst(insert_func insert_first); | ||
140 | void setEquals(equals_func equals); | ||
141 | |||
142 | DATA_T &addData(const INDEX_T &index, DATA_T datap); | ||
143 | DATA_T &addData(const INDEX_T &index); | ||
144 | DATA_T &getData(const INDEX_T &index); | ||
145 | DATA_T &operator[](const INDEX_T &index); | ||
146 | |||
147 | // If index present, returns data. | ||
148 | // If index not present, adds <index,NULL> and returns NULL. | ||
149 | DATA_T &getData(const INDEX_T &index, BOOL &b_new_entry); | ||
150 | |||
151 | // returns data entry before and after index | ||
152 | BOOL getInterval(const INDEX_T &index, INDEX_T &index_before, INDEX_T &index_after, | ||
153 | DATA_T &data_before, DATA_T &data_after ); | ||
154 | |||
155 | // Returns TRUE if data present in map. | ||
156 | BOOL checkData(const INDEX_T &index); | ||
157 | |||
158 | // Returns TRUE if key is present in map. This is useful if you | ||
159 | // are potentially storing NULL pointers in the map | ||
160 | BOOL checkKey(const INDEX_T &index); | ||
161 | |||
162 | // If there, returns the data. | ||
163 | // If not, returns NULL. | ||
164 | // Never adds entries to the map. | ||
165 | DATA_T getIfThere(const INDEX_T &index); | ||
166 | |||
167 | INDEX_T reverseLookup(const DATA_T datap); | ||
168 | |||
169 | // returns number of items in the list | ||
170 | S32 getLength(); // WARNING! getLength is O(n), not O(1)! | ||
171 | |||
172 | BOOL removeData(const INDEX_T &index); | ||
173 | BOOL deleteData(const INDEX_T &index); | ||
174 | |||
175 | // remove all nodes from the list but do not delete data | ||
176 | void removeAllData(); | ||
177 | void deleteAllData(); | ||
178 | |||
179 | // place mCurrentp on first node | ||
180 | void resetList(); | ||
181 | |||
182 | // return the data currently pointed to | ||
183 | DATA_T getCurrentDataWithoutIncrement(); | ||
184 | |||
185 | // return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp | ||
186 | DATA_T getCurrentData(); | ||
187 | |||
188 | // same as getCurrentData() but a more intuitive name for the operation | ||
189 | DATA_T getNextData(); | ||
190 | |||
191 | INDEX_T getNextKey(); | ||
192 | |||
193 | // return the key currently pointed to | ||
194 | INDEX_T getCurrentKeyWithoutIncrement(); | ||
195 | |||
196 | // remove the Node at mCurentOperatingp | ||
197 | // leave mCurrentp and mCurentOperatingp on the next entry | ||
198 | void removeCurrentData(); | ||
199 | |||
200 | void deleteCurrentData(); | ||
201 | |||
202 | // reset the list and return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp | ||
203 | DATA_T getFirstData(); | ||
204 | |||
205 | INDEX_T getFirstKey(); | ||
206 | |||
207 | static BOOL defaultEquals(const INDEX_T &first, const INDEX_T &second) | ||
208 | { | ||
209 | return first == second; | ||
210 | } | ||
211 | |||
212 | private: | ||
213 | // don't generate implicit copy constructor or copy assignment | ||
214 | LLPtrSkipMap(const LLPtrSkipMap &); | ||
215 | LLPtrSkipMap &operator=(const LLPtrSkipMap &); | ||
216 | |||
217 | private: | ||
218 | LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> mHead; | ||
219 | LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *mUpdate[BINARY_DEPTH]; | ||
220 | LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *mCurrentp; | ||
221 | LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *mCurrentOperatingp; | ||
222 | S32 mLevel; | ||
223 | BOOL (*mInsertFirst)(const INDEX_T &first, const INDEX_T &second); | ||
224 | BOOL (*mEquals)(const INDEX_T &first, const INDEX_T &second); | ||
225 | S32 mNumberOfSteps; | ||
226 | }; | ||
227 | |||
228 | ////////////////////////////////////////////////// | ||
229 | // | ||
230 | // LLPtrSkipMap implementation | ||
231 | // | ||
232 | // | ||
233 | |||
234 | template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> | ||
235 | inline LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::LLPtrSkipMap() | ||
236 | : mInsertFirst(NULL), | ||
237 | mEquals(defaultEquals) | ||
238 | { | ||
239 | if (BINARY_DEPTH < 2) | ||
240 | { | ||
241 | llerrs << "Trying to create skip list with too little depth, " | ||
242 | "must be 2 or greater" << llendl; | ||
243 | } | ||
244 | S32 i; | ||
245 | for (i = 0; i < BINARY_DEPTH; i++) | ||
246 | { | ||
247 | mUpdate[i] = NULL; | ||
248 | } | ||
249 | mLevel = 1; | ||
250 | mCurrentp = *(mHead.mForward); | ||
251 | mCurrentOperatingp = *(mHead.mForward); | ||
252 | } | ||
253 | |||
254 | template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> | ||
255 | inline LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::LLPtrSkipMap(insert_func insert_first, | ||
256 | equals_func equals) | ||
257 | : mInsertFirst(insert_first), | ||
258 | mEquals(equals) | ||
259 | { | ||
260 | if (BINARY_DEPTH < 2) | ||
261 | { | ||
262 | llerrs << "Trying to create skip list with too little depth, " | ||
263 | "must be 2 or greater" << llendl; | ||
264 | } | ||
265 | mLevel = 1; | ||
266 | S32 i; | ||
267 | for (i = 0; i < BINARY_DEPTH; i++) | ||
268 | { | ||
269 | mHead.mForward[i] = NULL; | ||
270 | mUpdate[i] = NULL; | ||
271 | } | ||
272 | mCurrentp = *(mHead.mForward); | ||
273 | mCurrentOperatingp = *(mHead.mForward); | ||
274 | } | ||
275 | |||
276 | template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> | ||
277 | inline LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::~LLPtrSkipMap() | ||
278 | { | ||
279 | removeAllData(); | ||
280 | } | ||
281 | |||
282 | template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> | ||
283 | inline void LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::setInsertFirst(insert_func insert_first) | ||
284 | { | ||
285 | mInsertFirst = insert_first; | ||
286 | } | ||
287 | |||
288 | template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> | ||
289 | inline void LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::setEquals(equals_func equals) | ||
290 | { | ||
291 | mEquals = equals; | ||
292 | } | ||
293 | |||
294 | template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> | ||
295 | inline DATA_T &LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::addData(const INDEX_T &index, DATA_T datap) | ||
296 | { | ||
297 | S32 level; | ||
298 | LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *current = &mHead; | ||
299 | LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *temp; | ||
300 | |||
301 | // find the pointer one in front of the one we want | ||
302 | if (mInsertFirst) | ||
303 | { | ||
304 | for (level = mLevel - 1; level >= 0; level--) | ||
305 | { | ||
306 | temp = *(current->mForward + level); | ||
307 | while ( (temp) | ||
308 | &&(mInsertFirst(temp->mIndex, index))) | ||
309 | { | ||
310 | current = temp; | ||
311 | temp = *(current->mForward + level); | ||
312 | } | ||
313 | *(mUpdate + level) = current; | ||
314 | } | ||
315 | } | ||
316 | else | ||
317 | { | ||
318 | for (level = mLevel - 1; level >= 0; level--) | ||
319 | { | ||
320 | temp = *(current->mForward + level); | ||
321 | while ( (temp) | ||
322 | &&(temp->mIndex < index)) | ||
323 | { | ||
324 | current = temp; | ||
325 | temp = *(current->mForward + level); | ||
326 | } | ||
327 | *(mUpdate + level) = current; | ||
328 | } | ||
329 | } | ||
330 | |||
331 | // we're now just in front of where we want to be . . . take one step forward | ||
332 | current = *current->mForward; | ||
333 | |||
334 | // replace the existing data if a node is already there | ||
335 | if ( (current) | ||
336 | &&(mEquals(current->mIndex, index))) | ||
337 | { | ||
338 | current->mData = datap; | ||
339 | return current->mData; | ||
340 | } | ||
341 | |||
342 | // now add the new node | ||
343 | S32 newlevel; | ||
344 | for (newlevel = 1; newlevel <= mLevel && newlevel < BINARY_DEPTH; newlevel++) | ||
345 | { | ||
346 | if (frand(1.f) < 0.5f) | ||
347 | { | ||
348 | break; | ||
349 | } | ||
350 | } | ||
351 | |||
352 | LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *snode | ||
353 | = new LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH>(index, datap); | ||
354 | |||
355 | if (newlevel > mLevel) | ||
356 | { | ||
357 | mHead.mForward[mLevel] = NULL; | ||
358 | mUpdate[mLevel] = &mHead; | ||
359 | mLevel = newlevel; | ||
360 | } | ||
361 | |||
362 | for (level = 0; level < newlevel; level++) | ||
363 | { | ||
364 | snode->mForward[level] = mUpdate[level]->mForward[level]; | ||
365 | mUpdate[level]->mForward[level] = snode; | ||
366 | } | ||
367 | return snode->mData; | ||
368 | } | ||
369 | |||
370 | template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> | ||
371 | inline DATA_T &LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::addData(const INDEX_T &index) | ||
372 | { | ||
373 | S32 level; | ||
374 | LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *current = &mHead; | ||
375 | LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *temp; | ||
376 | |||
377 | // find the pointer one in front of the one we want | ||
378 | if (mInsertFirst) | ||
379 | { | ||
380 | for (level = mLevel - 1; level >= 0; level--) | ||
381 | { | ||
382 | temp = *(current->mForward + level); | ||
383 | while ( (temp) | ||
384 | &&(mInsertFirst(temp->mIndex, index))) | ||
385 | { | ||
386 | current = temp; | ||
387 | temp = *(current->mForward + level); | ||
388 | } | ||
389 | *(mUpdate + level) = current; | ||
390 | } | ||
391 | } | ||
392 | else | ||
393 | { | ||
394 | for (level = mLevel - 1; level >= 0; level--) | ||
395 | { | ||
396 | temp = *(current->mForward + level); | ||
397 | while ( (temp) | ||
398 | &&(temp->mIndex < index)) | ||
399 | { | ||
400 | current = temp; | ||
401 | temp = *(current->mForward + level); | ||
402 | } | ||
403 | *(mUpdate + level) = current; | ||
404 | } | ||
405 | } | ||
406 | |||
407 | // we're now just in front of where we want to be . . . take one step forward | ||
408 | current = *current->mForward; | ||
409 | |||
410 | // now add the new node | ||
411 | S32 newlevel; | ||
412 | for (newlevel = 1; newlevel <= mLevel && newlevel < BINARY_DEPTH; newlevel++) | ||
413 | { | ||
414 | if (frand(1.f) < 0.5f) | ||
415 | break; | ||
416 | } | ||
417 | |||
418 | LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *snode | ||
419 | = new LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH>(index); | ||
420 | |||
421 | if (newlevel > mLevel) | ||
422 | { | ||
423 | mHead.mForward[mLevel] = NULL; | ||
424 | mUpdate[mLevel] = &mHead; | ||
425 | mLevel = newlevel; | ||
426 | } | ||
427 | |||
428 | for (level = 0; level < newlevel; level++) | ||
429 | { | ||
430 | snode->mForward[level] = mUpdate[level]->mForward[level]; | ||
431 | mUpdate[level]->mForward[level] = snode; | ||
432 | } | ||
433 | return snode->mData; | ||
434 | } | ||
435 | |||
436 | template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> | ||
437 | inline DATA_T &LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getData(const INDEX_T &index) | ||
438 | { | ||
439 | S32 level; | ||
440 | LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *current = &mHead; | ||
441 | LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *temp; | ||
442 | |||
443 | mNumberOfSteps = 0; | ||
444 | |||
445 | // find the pointer one in front of the one we want | ||
446 | if (mInsertFirst) | ||
447 | { | ||
448 | for (level = mLevel - 1; level >= 0; level--) | ||
449 | { | ||
450 | temp = *(current->mForward + level); | ||
451 | while ( (temp) | ||
452 | &&(mInsertFirst(temp->mIndex, index))) | ||
453 | { | ||
454 | current = temp; | ||
455 | temp = *(current->mForward + level); | ||
456 | mNumberOfSteps++; | ||
457 | } | ||
458 | *(mUpdate + level) = current; | ||
459 | } | ||
460 | } | ||
461 | else | ||
462 | { | ||
463 | for (level = mLevel - 1; level >= 0; level--) | ||
464 | { | ||
465 | temp = *(current->mForward + level); | ||
466 | while ( (temp) | ||
467 | &&(temp->mIndex < index)) | ||
468 | { | ||
469 | current = temp; | ||
470 | temp = *(current->mForward + level); | ||
471 | mNumberOfSteps++; | ||
472 | } | ||
473 | *(mUpdate + level) = current; | ||
474 | } | ||
475 | } | ||
476 | |||
477 | // we're now just in front of where we want to be . . . take one step forward | ||
478 | current = *current->mForward; | ||
479 | mNumberOfSteps++; | ||
480 | |||
481 | if ( (current) | ||
482 | &&(mEquals(current->mIndex, index))) | ||
483 | { | ||
484 | |||
485 | return current->mData; | ||
486 | } | ||
487 | |||
488 | // now add the new node | ||
489 | S32 newlevel; | ||
490 | for (newlevel = 1; newlevel <= mLevel && newlevel < BINARY_DEPTH; newlevel++) | ||
491 | { | ||
492 | if (frand(1.f) < 0.5f) | ||
493 | break; | ||
494 | } | ||
495 | |||
496 | LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *snode | ||
497 | = new LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH>(index); | ||
498 | |||
499 | if (newlevel > mLevel) | ||
500 | { | ||
501 | mHead.mForward[mLevel] = NULL; | ||
502 | mUpdate[mLevel] = &mHead; | ||
503 | mLevel = newlevel; | ||
504 | } | ||
505 | |||
506 | for (level = 0; level < newlevel; level++) | ||
507 | { | ||
508 | snode->mForward[level] = mUpdate[level]->mForward[level]; | ||
509 | mUpdate[level]->mForward[level] = snode; | ||
510 | } | ||
511 | |||
512 | return snode->mData; | ||
513 | } | ||
514 | |||
515 | template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> | ||
516 | inline BOOL LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getInterval(const INDEX_T &index, | ||
517 | INDEX_T &index_before, | ||
518 | INDEX_T &index_after, | ||
519 | DATA_T &data_before, | ||
520 | DATA_T &data_after) | ||
521 | { | ||
522 | S32 level; | ||
523 | LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *current = &mHead; | ||
524 | LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *temp; | ||
525 | |||
526 | mNumberOfSteps = 0; | ||
527 | |||
528 | // find the pointer one in front of the one we want | ||
529 | if (mInsertFirst) | ||
530 | { | ||
531 | for (level = mLevel - 1; level >= 0; level--) | ||
532 | { | ||
533 | temp = *(current->mForward + level); | ||
534 | while ( (temp) | ||
535 | &&(mInsertFirst(temp->mIndex, index))) | ||
536 | { | ||
537 | current = temp; | ||
538 | temp = *(current->mForward + level); | ||
539 | mNumberOfSteps++; | ||
540 | } | ||
541 | *(mUpdate + level) = current; | ||
542 | } | ||
543 | } | ||
544 | else | ||
545 | { | ||
546 | for (level = mLevel - 1; level >= 0; level--) | ||
547 | { | ||
548 | temp = *(current->mForward + level); | ||
549 | while ( (temp) | ||
550 | &&(temp->mIndex < index)) | ||
551 | { | ||
552 | current = temp; | ||
553 | temp = *(current->mForward + level); | ||
554 | mNumberOfSteps++; | ||
555 | } | ||
556 | *(mUpdate + level) = current; | ||
557 | } | ||
558 | } | ||
559 | |||
560 | BOOL both_found = TRUE; | ||
561 | |||
562 | if (current != &mHead) | ||
563 | { | ||
564 | index_before = current->mIndex; | ||
565 | data_before = current->mData; | ||
566 | } | ||
567 | else | ||
568 | { | ||
569 | data_before = 0; | ||
570 | index_before = 0; | ||
571 | both_found = FALSE; | ||
572 | } | ||
573 | |||
574 | // we're now just in front of where we want to be . . . take one step forward | ||
575 | mNumberOfSteps++; | ||
576 | current = *current->mForward; | ||
577 | |||
578 | if (current) | ||
579 | { | ||
580 | data_after = current->mData; | ||
581 | index_after = current->mIndex; | ||
582 | } | ||
583 | else | ||
584 | { | ||
585 | data_after = 0; | ||
586 | index_after = 0; | ||
587 | both_found = FALSE; | ||
588 | } | ||
589 | |||
590 | return both_found; | ||
591 | } | ||
592 | |||
593 | |||
594 | template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> | ||
595 | inline DATA_T &LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::operator[](const INDEX_T &index) | ||
596 | { | ||
597 | |||
598 | return getData(index); | ||
599 | } | ||
600 | |||
601 | // If index present, returns data. | ||
602 | // If index not present, adds <index,NULL> and returns NULL. | ||
603 | template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> | ||
604 | inline DATA_T &LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getData(const INDEX_T &index, BOOL &b_new_entry) | ||
605 | { | ||
606 | S32 level; | ||
607 | LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *current = &mHead; | ||
608 | LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *temp; | ||
609 | |||
610 | mNumberOfSteps = 0; | ||
611 | |||
612 | // find the pointer one in front of the one we want | ||
613 | if (mInsertFirst) | ||
614 | { | ||
615 | for (level = mLevel - 1; level >= 0; level--) | ||
616 | { | ||
617 | temp = *(current->mForward + level); | ||
618 | while ( (temp) | ||
619 | &&(mInsertFirst(temp->mIndex, index))) | ||
620 | { | ||
621 | current = temp; | ||
622 | temp = *(current->mForward + level); | ||
623 | mNumberOfSteps++; | ||
624 | } | ||
625 | *(mUpdate + level) = current; | ||
626 | } | ||
627 | } | ||
628 | else | ||
629 | { | ||
630 | for (level = mLevel - 1; level >= 0; level--) | ||
631 | { | ||
632 | temp = *(current->mForward + level); | ||
633 | while ( (temp) | ||
634 | &&(temp->mIndex < index)) | ||
635 | { | ||
636 | current = temp; | ||
637 | temp = *(current->mForward + level); | ||
638 | mNumberOfSteps++; | ||
639 | } | ||
640 | *(mUpdate + level) = current; | ||
641 | } | ||
642 | } | ||
643 | |||
644 | // we're now just in front of where we want to be . . . take one step forward | ||
645 | mNumberOfSteps++; | ||
646 | current = *current->mForward; | ||
647 | |||
648 | if ( (current) | ||
649 | &&(mEquals(current->mIndex, index))) | ||
650 | { | ||
651 | |||
652 | return current->mData; | ||
653 | } | ||
654 | b_new_entry = TRUE; | ||
655 | addData(index); | ||
656 | |||
657 | return current->mData; | ||
658 | } | ||
659 | |||
660 | // Returns TRUE if data present in map. | ||
661 | template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> | ||
662 | inline BOOL LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::checkData(const INDEX_T &index) | ||
663 | { | ||
664 | S32 level; | ||
665 | LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *current = &mHead; | ||
666 | LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *temp; | ||
667 | |||
668 | // find the pointer one in front of the one we want | ||
669 | if (mInsertFirst) | ||
670 | { | ||
671 | for (level = mLevel - 1; level >= 0; level--) | ||
672 | { | ||
673 | temp = *(current->mForward + level); | ||
674 | while ( (temp) | ||
675 | &&(mInsertFirst(temp->mIndex, index))) | ||
676 | { | ||
677 | current = temp; | ||
678 | temp = *(current->mForward + level); | ||
679 | } | ||
680 | *(mUpdate + level) = current; | ||
681 | } | ||
682 | } | ||
683 | else | ||
684 | { | ||
685 | for (level = mLevel - 1; level >= 0; level--) | ||
686 | { | ||
687 | temp = *(current->mForward + level); | ||
688 | while ( (temp) | ||
689 | &&(temp->mIndex < index)) | ||
690 | { | ||
691 | current = temp; | ||
692 | temp = *(current->mForward + level); | ||
693 | } | ||
694 | *(mUpdate + level) = current; | ||
695 | } | ||
696 | } | ||
697 | |||
698 | // we're now just in front of where we want to be . . . take one step forward | ||
699 | current = *current->mForward; | ||
700 | |||
701 | if (current) | ||
702 | { | ||
703 | // Gets rid of some compiler ambiguity for the LLPointer<> templated class. | ||
704 | if (current->mData) | ||
705 | { | ||
706 | return mEquals(current->mIndex, index); | ||
707 | } | ||
708 | } | ||
709 | |||
710 | return FALSE; | ||
711 | } | ||
712 | |||
713 | // Returns TRUE if key is present in map. This is useful if you | ||
714 | // are potentially storing NULL pointers in the map | ||
715 | template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> | ||
716 | inline BOOL LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::checkKey(const INDEX_T &index) | ||
717 | { | ||
718 | S32 level; | ||
719 | LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *current = &mHead; | ||
720 | LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *temp; | ||
721 | |||
722 | // find the pointer one in front of the one we want | ||
723 | if (mInsertFirst) | ||
724 | { | ||
725 | for (level = mLevel - 1; level >= 0; level--) | ||
726 | { | ||
727 | temp = *(current->mForward + level); | ||
728 | while ( (temp) | ||
729 | &&(mInsertFirst(temp->mIndex, index))) | ||
730 | { | ||
731 | current = temp; | ||
732 | temp = *(current->mForward + level); | ||
733 | } | ||
734 | *(mUpdate + level) = current; | ||
735 | } | ||
736 | } | ||
737 | else | ||
738 | { | ||
739 | for (level = mLevel - 1; level >= 0; level--) | ||
740 | { | ||
741 | temp = *(current->mForward + level); | ||
742 | while ( (temp) | ||
743 | &&(temp->mIndex < index)) | ||
744 | { | ||
745 | current = temp; | ||
746 | temp = *(current->mForward + level); | ||
747 | } | ||
748 | *(mUpdate + level) = current; | ||
749 | } | ||
750 | } | ||
751 | |||
752 | // we're now just in front of where we want to be . . . take one step forward | ||
753 | current = *current->mForward; | ||
754 | |||
755 | if (current) | ||
756 | { | ||
757 | return mEquals(current->mIndex, index); | ||
758 | } | ||
759 | |||
760 | return FALSE; | ||
761 | } | ||
762 | |||
763 | // If there, returns the data. | ||
764 | // If not, returns NULL. | ||
765 | // Never adds entries to the map. | ||
766 | template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> | ||
767 | inline DATA_T LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getIfThere(const INDEX_T &index) | ||
768 | { | ||
769 | S32 level; | ||
770 | LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *current = &mHead; | ||
771 | LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *temp; | ||
772 | |||
773 | mNumberOfSteps = 0; | ||
774 | |||
775 | // find the pointer one in front of the one we want | ||
776 | if (mInsertFirst) | ||
777 | { | ||
778 | for (level = mLevel - 1; level >= 0; level--) | ||
779 | { | ||
780 | temp = *(current->mForward + level); | ||
781 | while ( (temp) | ||
782 | &&(mInsertFirst(temp->mIndex, index))) | ||
783 | { | ||
784 | current = temp; | ||
785 | temp = *(current->mForward + level); | ||
786 | mNumberOfSteps++; | ||
787 | } | ||
788 | *(mUpdate + level) = current; | ||
789 | } | ||
790 | } | ||
791 | else | ||
792 | { | ||
793 | for (level = mLevel - 1; level >= 0; level--) | ||
794 | { | ||
795 | temp = *(current->mForward + level); | ||
796 | while ( (temp) | ||
797 | &&(temp->mIndex < index)) | ||
798 | { | ||
799 | current = temp; | ||
800 | temp = *(current->mForward + level); | ||
801 | mNumberOfSteps++; | ||
802 | } | ||
803 | *(mUpdate + level) = current; | ||
804 | } | ||
805 | } | ||
806 | |||
807 | // we're now just in front of where we want to be . . . take one step forward | ||
808 | mNumberOfSteps++; | ||
809 | current = *current->mForward; | ||
810 | |||
811 | if (current) | ||
812 | { | ||
813 | if (mEquals(current->mIndex, index)) | ||
814 | { | ||
815 | return current->mData; | ||
816 | } | ||
817 | } | ||
818 | |||
819 | // Avoid Linux compiler warning on returning NULL. | ||
820 | return (DATA_T)0; | ||
821 | } | ||
822 | |||
823 | template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> | ||
824 | inline INDEX_T LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::reverseLookup(const DATA_T datap) | ||
825 | { | ||
826 | LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *current = &mHead; | ||
827 | |||
828 | while (current) | ||
829 | { | ||
830 | if (datap == current->mData) | ||
831 | { | ||
832 | |||
833 | return current->mIndex; | ||
834 | } | ||
835 | current = *current->mForward; | ||
836 | } | ||
837 | |||
838 | // not found! return NULL | ||
839 | return INDEX_T(); | ||
840 | } | ||
841 | |||
842 | // returns number of items in the list | ||
843 | template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> | ||
844 | inline S32 LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getLength() | ||
845 | { | ||
846 | U32 length = 0; | ||
847 | LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH>* temp; | ||
848 | for (temp = *(mHead.mForward); temp != NULL; temp = temp->mForward[0]) | ||
849 | { | ||
850 | length++; | ||
851 | } | ||
852 | |||
853 | return length; | ||
854 | } | ||
855 | |||
856 | template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> | ||
857 | inline BOOL LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::removeData(const INDEX_T &index) | ||
858 | { | ||
859 | S32 level; | ||
860 | LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *current = &mHead; | ||
861 | LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *temp; | ||
862 | |||
863 | // find the pointer one in front of the one we want | ||
864 | if (mInsertFirst) | ||
865 | { | ||
866 | for (level = mLevel - 1; level >= 0; level--) | ||
867 | { | ||
868 | temp = *(current->mForward + level); | ||
869 | while ( (temp) | ||
870 | &&(mInsertFirst(temp->mIndex, index))) | ||
871 | { | ||
872 | current = temp; | ||
873 | temp = *(current->mForward + level); | ||
874 | } | ||
875 | *(mUpdate + level) = current; | ||
876 | } | ||
877 | } | ||
878 | else | ||
879 | { | ||
880 | for (level = mLevel - 1; level >= 0; level--) | ||
881 | { | ||
882 | temp = *(current->mForward + level); | ||
883 | while ( (temp) | ||
884 | &&(temp->mIndex < index)) | ||
885 | { | ||
886 | current = temp; | ||
887 | temp = *(current->mForward + level); | ||
888 | } | ||
889 | *(mUpdate + level) = current; | ||
890 | } | ||
891 | } | ||
892 | |||
893 | // we're now just in front of where we want to be . . . take one step forward | ||
894 | current = *current->mForward; | ||
895 | |||
896 | if (!current) | ||
897 | { | ||
898 | // empty list or beyond the end! | ||
899 | |||
900 | return FALSE; | ||
901 | } | ||
902 | |||
903 | // is this the one we want? | ||
904 | if (!mEquals(current->mIndex, index)) | ||
905 | { | ||
906 | // nope! | ||
907 | |||
908 | return FALSE; | ||
909 | } | ||
910 | else | ||
911 | { | ||
912 | // do we need to fix current or currentop? | ||
913 | if (current == mCurrentp) | ||
914 | { | ||
915 | mCurrentp = *current->mForward; | ||
916 | } | ||
917 | |||
918 | if (current == mCurrentOperatingp) | ||
919 | { | ||
920 | mCurrentOperatingp = *current->mForward; | ||
921 | } | ||
922 | // yes it is! change pointers as required | ||
923 | for (level = 0; level < mLevel; level++) | ||
924 | { | ||
925 | if (*((*(mUpdate + level))->mForward + level) != current) | ||
926 | { | ||
927 | // cool, we've fixed all the pointers! | ||
928 | break; | ||
929 | } | ||
930 | *((*(mUpdate + level))->mForward + level) = *(current->mForward + level); | ||
931 | } | ||
932 | |||
933 | // clean up cuurent | ||
934 | current->removeData(); | ||
935 | delete current; | ||
936 | |||
937 | // clean up mHead | ||
938 | while ( (mLevel > 1) | ||
939 | &&(!*(mHead.mForward + mLevel - 1))) | ||
940 | { | ||
941 | mLevel--; | ||
942 | } | ||
943 | } | ||
944 | |||
945 | return TRUE; | ||
946 | } | ||
947 | |||
948 | template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> | ||
949 | inline BOOL LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::deleteData(const INDEX_T &index) | ||
950 | { | ||
951 | S32 level; | ||
952 | LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *current = &mHead; | ||
953 | LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *temp; | ||
954 | |||
955 | // find the pointer one in front of the one we want | ||
956 | if (mInsertFirst) | ||
957 | { | ||
958 | for (level = mLevel - 1; level >= 0; level--) | ||
959 | { | ||
960 | temp = *(current->mForward + level); | ||
961 | while ( (temp) | ||
962 | &&(mInsertFirst(temp->mIndex, index))) | ||
963 | { | ||
964 | current = temp; | ||
965 | temp = *(current->mForward + level); | ||
966 | } | ||
967 | *(mUpdate + level) = current; | ||
968 | } | ||
969 | } | ||
970 | else | ||
971 | { | ||
972 | for (level = mLevel - 1; level >= 0; level--) | ||
973 | { | ||
974 | temp = *(current->mForward + level); | ||
975 | while ( (temp) | ||
976 | &&(temp->mIndex < index)) | ||
977 | { | ||
978 | current = temp; | ||
979 | temp = *(current->mForward + level); | ||
980 | } | ||
981 | *(mUpdate + level) = current; | ||
982 | } | ||
983 | } | ||
984 | |||
985 | // we're now just in front of where we want to be . . . take one step forward | ||
986 | current = *current->mForward; | ||
987 | |||
988 | if (!current) | ||
989 | { | ||
990 | // empty list or beyond the end! | ||
991 | |||
992 | return FALSE; | ||
993 | } | ||
994 | |||
995 | // is this the one we want? | ||
996 | if (!mEquals(current->mIndex, index)) | ||
997 | { | ||
998 | // nope! | ||
999 | |||
1000 | return FALSE; | ||
1001 | } | ||
1002 | else | ||
1003 | { | ||
1004 | // do we need to fix current or currentop? | ||
1005 | if (current == mCurrentp) | ||
1006 | { | ||
1007 | mCurrentp = *current->mForward; | ||
1008 | } | ||
1009 | |||
1010 | if (current == mCurrentOperatingp) | ||
1011 | { | ||
1012 | mCurrentOperatingp = *current->mForward; | ||
1013 | } | ||
1014 | // yes it is! change pointers as required | ||
1015 | for (level = 0; level < mLevel; level++) | ||
1016 | { | ||
1017 | if (*((*(mUpdate + level))->mForward + level) != current) | ||
1018 | { | ||
1019 | // cool, we've fixed all the pointers! | ||
1020 | break; | ||
1021 | } | ||
1022 | *((*(mUpdate + level))->mForward + level) = *(current->mForward + level); | ||
1023 | } | ||
1024 | |||
1025 | // clean up cuurent | ||
1026 | current->deleteData(); | ||
1027 | delete current; | ||
1028 | |||
1029 | // clean up mHead | ||
1030 | while ( (mLevel > 1) | ||
1031 | &&(!*(mHead.mForward + mLevel - 1))) | ||
1032 | { | ||
1033 | mLevel--; | ||
1034 | } | ||
1035 | } | ||
1036 | |||
1037 | return TRUE; | ||
1038 | } | ||
1039 | |||
1040 | // remove all nodes from the list but do not delete data | ||
1041 | template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> | ||
1042 | void LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::removeAllData() | ||
1043 | { | ||
1044 | LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *temp; | ||
1045 | // reset mCurrentp | ||
1046 | mCurrentp = *(mHead.mForward); | ||
1047 | |||
1048 | while (mCurrentp) | ||
1049 | { | ||
1050 | temp = mCurrentp->mForward[0]; | ||
1051 | mCurrentp->removeData(); | ||
1052 | delete mCurrentp; | ||
1053 | mCurrentp = temp; | ||
1054 | } | ||
1055 | |||
1056 | S32 i; | ||
1057 | for (i = 0; i < BINARY_DEPTH; i++) | ||
1058 | { | ||
1059 | mHead.mForward[i] = NULL; | ||
1060 | mUpdate[i] = NULL; | ||
1061 | } | ||
1062 | |||
1063 | mCurrentp = *(mHead.mForward); | ||
1064 | mCurrentOperatingp = *(mHead.mForward); | ||
1065 | } | ||
1066 | |||
1067 | template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> | ||
1068 | inline void LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::deleteAllData() | ||
1069 | { | ||
1070 | LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *temp; | ||
1071 | // reset mCurrentp | ||
1072 | mCurrentp = *(mHead.mForward); | ||
1073 | |||
1074 | while (mCurrentp) | ||
1075 | { | ||
1076 | temp = mCurrentp->mForward[0]; | ||
1077 | mCurrentp->deleteData(); | ||
1078 | delete mCurrentp; | ||
1079 | mCurrentp = temp; | ||
1080 | } | ||
1081 | |||
1082 | S32 i; | ||
1083 | for (i = 0; i < BINARY_DEPTH; i++) | ||
1084 | { | ||
1085 | mHead.mForward[i] = NULL; | ||
1086 | mUpdate[i] = NULL; | ||
1087 | } | ||
1088 | |||
1089 | mCurrentp = *(mHead.mForward); | ||
1090 | mCurrentOperatingp = *(mHead.mForward); | ||
1091 | } | ||
1092 | |||
1093 | // place mCurrentp on first node | ||
1094 | template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> | ||
1095 | inline void LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::resetList() | ||
1096 | { | ||
1097 | mCurrentp = *(mHead.mForward); | ||
1098 | mCurrentOperatingp = *(mHead.mForward); | ||
1099 | } | ||
1100 | |||
1101 | |||
1102 | // return the data currently pointed to | ||
1103 | template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> | ||
1104 | inline DATA_T LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getCurrentDataWithoutIncrement() | ||
1105 | { | ||
1106 | if (mCurrentOperatingp) | ||
1107 | { | ||
1108 | return mCurrentOperatingp->mData; | ||
1109 | } | ||
1110 | else | ||
1111 | { | ||
1112 | //return NULL; // causes warning | ||
1113 | return (DATA_T)0; // equivalent, but no warning | ||
1114 | } | ||
1115 | } | ||
1116 | |||
1117 | // return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp | ||
1118 | template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> | ||
1119 | inline DATA_T LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getCurrentData() | ||
1120 | { | ||
1121 | if (mCurrentp) | ||
1122 | { | ||
1123 | mCurrentOperatingp = mCurrentp; | ||
1124 | mCurrentp = mCurrentp->mForward[0]; | ||
1125 | return mCurrentOperatingp->mData; | ||
1126 | } | ||
1127 | else | ||
1128 | { | ||
1129 | //return NULL; // causes warning | ||
1130 | return (DATA_T)0; // equivalent, but no warning | ||
1131 | } | ||
1132 | } | ||
1133 | |||
1134 | // same as getCurrentData() but a more intuitive name for the operation | ||
1135 | template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> | ||
1136 | inline DATA_T LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getNextData() | ||
1137 | { | ||
1138 | if (mCurrentp) | ||
1139 | { | ||
1140 | mCurrentOperatingp = mCurrentp; | ||
1141 | mCurrentp = mCurrentp->mForward[0]; | ||
1142 | return mCurrentOperatingp->mData; | ||
1143 | } | ||
1144 | else | ||
1145 | { | ||
1146 | //return NULL; // causes compile warning | ||
1147 | return (DATA_T)0; // equivalent, but removes warning | ||
1148 | } | ||
1149 | } | ||
1150 | |||
1151 | template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> | ||
1152 | inline INDEX_T LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getNextKey() | ||
1153 | { | ||
1154 | if (mCurrentp) | ||
1155 | { | ||
1156 | mCurrentOperatingp = mCurrentp; | ||
1157 | mCurrentp = mCurrentp->mForward[0]; | ||
1158 | return mCurrentOperatingp->mIndex; | ||
1159 | } | ||
1160 | else | ||
1161 | { | ||
1162 | return mHead.mIndex; | ||
1163 | } | ||
1164 | } | ||
1165 | |||
1166 | // return the key currently pointed to | ||
1167 | template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> | ||
1168 | inline INDEX_T LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getCurrentKeyWithoutIncrement() | ||
1169 | { | ||
1170 | if (mCurrentOperatingp) | ||
1171 | { | ||
1172 | return mCurrentOperatingp->mIndex; | ||
1173 | } | ||
1174 | else | ||
1175 | { | ||
1176 | //return NULL; // causes compile warning | ||
1177 | return (INDEX_T)0; // equivalent, but removes warning | ||
1178 | } | ||
1179 | } | ||
1180 | |||
1181 | |||
1182 | // remove the Node at mCurentOperatingp | ||
1183 | // leave mCurrentp and mCurentOperatingp on the next entry | ||
1184 | template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> | ||
1185 | inline void LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::removeCurrentData() | ||
1186 | { | ||
1187 | if (mCurrentOperatingp) | ||
1188 | { | ||
1189 | removeData(mCurrentOperatingp->mIndex); | ||
1190 | } | ||
1191 | } | ||
1192 | |||
1193 | template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> | ||
1194 | inline void LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::deleteCurrentData() | ||
1195 | { | ||
1196 | if (mCurrentOperatingp) | ||
1197 | { | ||
1198 | deleteData(mCurrentOperatingp->mIndex); | ||
1199 | } | ||
1200 | } | ||
1201 | |||
1202 | // reset the list and return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp | ||
1203 | template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> | ||
1204 | inline DATA_T LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getFirstData() | ||
1205 | { | ||
1206 | mCurrentp = *(mHead.mForward); | ||
1207 | mCurrentOperatingp = *(mHead.mForward); | ||
1208 | if (mCurrentp) | ||
1209 | { | ||
1210 | mCurrentOperatingp = mCurrentp; | ||
1211 | mCurrentp = mCurrentp->mForward[0]; | ||
1212 | return mCurrentOperatingp->mData; | ||
1213 | } | ||
1214 | else | ||
1215 | { | ||
1216 | //return NULL; // causes compile warning | ||
1217 | return (DATA_T)0; // equivalent, but removes warning | ||
1218 | } | ||
1219 | } | ||
1220 | |||
1221 | template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> | ||
1222 | inline INDEX_T LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getFirstKey() | ||
1223 | { | ||
1224 | mCurrentp = *(mHead.mForward); | ||
1225 | mCurrentOperatingp = *(mHead.mForward); | ||
1226 | if (mCurrentp) | ||
1227 | { | ||
1228 | mCurrentOperatingp = mCurrentp; | ||
1229 | mCurrentp = mCurrentp->mForward[0]; | ||
1230 | return mCurrentOperatingp->mIndex; | ||
1231 | } | ||
1232 | else | ||
1233 | { | ||
1234 | return mHead.mIndex; | ||
1235 | } | ||
1236 | } | ||
1237 | |||
1238 | #endif | ||