00001
00032 #ifndef LL_LLPTRSKIPLIST_H
00033 #define LL_LLPTRSKIPLIST_H
00034
00035 #include "llerror.h"
00036
00037
00039
00040
00041
00042
00043 template <class DATA_TYPE, S32 BINARY_DEPTH = 8>
00044 class LLPtrSkipList
00045 {
00046 public:
00047 friend class LLPtrSkipNode;
00048
00049
00050 LLPtrSkipList();
00051
00052 LLPtrSkipList(BOOL (*insert_first)(DATA_TYPE *first, DATA_TYPE *second),
00053 BOOL (*equals)(DATA_TYPE *first, DATA_TYPE *second));
00054 ~LLPtrSkipList();
00055
00056 inline void setInsertFirst(BOOL (*insert_first)(const DATA_TYPE *first, const DATA_TYPE *second));
00057 inline void setEquals(BOOL (*equals)(const DATA_TYPE *first, const DATA_TYPE *second));
00058
00059 inline BOOL addData(DATA_TYPE *data);
00060
00061 inline BOOL checkData(const DATA_TYPE *data);
00062
00063 inline S32 getLength();
00064
00065 inline BOOL removeData(const DATA_TYPE *data);
00066
00067
00068 inline BOOL moveData(const DATA_TYPE *data, LLPtrSkipList *newlist, BOOL b_sort);
00069
00070 inline BOOL moveCurrentData(LLPtrSkipList *newlist, BOOL b_sort);
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 inline void removeAllNodes();
00081
00082 inline BOOL deleteData(const DATA_TYPE *data);
00083
00084
00085 inline void deleteAllData();
00086
00087
00088 inline void resetList();
00089
00090
00091 inline DATA_TYPE *getCurrentData();
00092
00093
00094 inline DATA_TYPE *getNextData();
00095
00096
00097
00098 inline void removeCurrentData();
00099
00100
00101
00102 inline void deleteCurrentData();
00103
00104
00105 inline DATA_TYPE *getFirstData();
00106
00107
00108 inline BOOL corrupt();
00109
00110 protected:
00111 class LLPtrSkipNode
00112 {
00113 public:
00114 LLPtrSkipNode()
00115 : mData(NULL)
00116 {
00117 S32 i;
00118 for (i = 0; i < BINARY_DEPTH; i++)
00119 {
00120 mForward[i] = NULL;
00121 }
00122 }
00123
00124 LLPtrSkipNode(DATA_TYPE *data)
00125 : mData(data)
00126 {
00127 S32 i;
00128 for (i = 0; i < BINARY_DEPTH; i++)
00129 {
00130 mForward[i] = NULL;
00131 }
00132 }
00133
00134 ~LLPtrSkipNode()
00135 {
00136 if (mData)
00137 {
00138 llerror("Attempting to call LLPtrSkipNode destructor with a non-null mDatap!", 1);
00139 }
00140 }
00141
00142
00143 void deleteData()
00144 {
00145 delete mData;
00146 mData = NULL;
00147 }
00148
00149
00150 void removeData()
00151 {
00152 mData = NULL;
00153 }
00154
00155 DATA_TYPE *mData;
00156 LLPtrSkipNode *mForward[BINARY_DEPTH];
00157 };
00158
00159 static BOOL defaultEquals(const DATA_TYPE *first, const DATA_TYPE *second)
00160 {
00161 return first == second;
00162 }
00163
00164
00165 LLPtrSkipNode mHead;
00166 LLPtrSkipNode *mUpdate[BINARY_DEPTH];
00167 LLPtrSkipNode *mCurrentp;
00168 LLPtrSkipNode *mCurrentOperatingp;
00169 S32 mLevel;
00170 BOOL (*mInsertFirst)(const DATA_TYPE *first, const DATA_TYPE *second);
00171 BOOL (*mEquals)(const DATA_TYPE *first, const DATA_TYPE *second);
00172 };
00173
00174
00175
00176 template <class DATA_TYPE, S32 BINARY_DEPTH>
00177 LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::LLPtrSkipList()
00178 : mInsertFirst(NULL), mEquals(defaultEquals)
00179 {
00180 if (BINARY_DEPTH < 2)
00181 {
00182 llerrs << "Trying to create skip list with too little depth, "
00183 "must be 2 or greater" << llendl;
00184 }
00185 S32 i;
00186 for (i = 0; i < BINARY_DEPTH; i++)
00187 {
00188 mUpdate[i] = NULL;
00189 }
00190 mLevel = 1;
00191 mCurrentp = *(mHead.mForward);
00192 mCurrentOperatingp = *(mHead.mForward);
00193 }
00194
00195
00196 template <class DATA_TYPE, S32 BINARY_DEPTH>
00197 LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::LLPtrSkipList(BOOL (*insert_first)(DATA_TYPE *first, DATA_TYPE *second),
00198 BOOL (*equals)(DATA_TYPE *first, DATA_TYPE *second))
00199 :mInsertFirst(insert_first), mEquals(equals)
00200 {
00201 if (BINARY_DEPTH < 2)
00202 {
00203 llerrs << "Trying to create skip list with too little depth, "
00204 "must be 2 or greater" << llendl;
00205 }
00206 mLevel = 1;
00207 S32 i;
00208 for (i = 0; i < BINARY_DEPTH; i++)
00209 {
00210 mHead.mForward[i] = NULL;
00211 mUpdate[i] = NULL;
00212 }
00213 mCurrentp = *(mHead.mForward);
00214 mCurrentOperatingp = *(mHead.mForward);
00215 }
00216
00217 template <class DATA_TYPE, S32 BINARY_DEPTH>
00218 inline LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::~LLPtrSkipList()
00219 {
00220 removeAllNodes();
00221 }
00222
00223 template <class DATA_TYPE, S32 BINARY_DEPTH>
00224 inline void LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::setInsertFirst(BOOL (*insert_first)(const DATA_TYPE *first, const DATA_TYPE *second))
00225 {
00226 mInsertFirst = insert_first;
00227 }
00228
00229 template <class DATA_TYPE, S32 BINARY_DEPTH>
00230 inline void LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::setEquals(BOOL (*equals)(const DATA_TYPE *first, const DATA_TYPE *second))
00231 {
00232 mEquals = equals;
00233 }
00234
00235 template <class DATA_TYPE, S32 BINARY_DEPTH>
00236 inline BOOL LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::addData(DATA_TYPE *data)
00237 {
00238 S32 level;
00239 LLPtrSkipNode *current = &mHead;
00240 LLPtrSkipNode *temp;
00241
00242
00243 if (mInsertFirst)
00244 {
00245 for (level = mLevel - 1; level >= 0; level--)
00246 {
00247 temp = *(current->mForward + level);
00248 while ( (temp)
00249 &&(mInsertFirst(temp->mData, data)))
00250 {
00251 current = temp;
00252 temp = *(current->mForward + level);
00253 }
00254 *(mUpdate + level) = current;
00255 }
00256 }
00257 else
00258 {
00259 for (level = mLevel - 1; level >= 0; level--)
00260 {
00261 temp = *(current->mForward + level);
00262 while ( (temp)
00263 &&(temp->mData < data))
00264 {
00265 current = temp;
00266 temp = *(current->mForward + level);
00267 }
00268 *(mUpdate + level) = current;
00269 }
00270 }
00271
00272
00273
00274 current = *current->mForward;
00275
00276
00277 S32 newlevel;
00278 for (newlevel = 1; newlevel <= mLevel && newlevel < BINARY_DEPTH; newlevel++)
00279 {
00280 if (ll_frand() < 0.5f)
00281 break;
00282 }
00283
00284 LLPtrSkipNode *snode = new LLPtrSkipNode(data);
00285
00286 if (newlevel > mLevel)
00287 {
00288 mHead.mForward[mLevel] = NULL;
00289 mUpdate[mLevel] = &mHead;
00290 mLevel = newlevel;
00291 }
00292
00293 for (level = 0; level < newlevel; level++)
00294 {
00295 snode->mForward[level] = mUpdate[level]->mForward[level];
00296 mUpdate[level]->mForward[level] = snode;
00297 }
00298 return TRUE;
00299 }
00300
00301 template <class DATA_TYPE, S32 BINARY_DEPTH>
00302 inline BOOL LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::checkData(const DATA_TYPE *data)
00303 {
00304 S32 level;
00305 LLPtrSkipNode *current = &mHead;
00306 LLPtrSkipNode *temp;
00307
00308
00309 if (mInsertFirst)
00310 {
00311 for (level = mLevel - 1; level >= 0; level--)
00312 {
00313 temp = *(current->mForward + level);
00314 while ( (temp)
00315 &&(mInsertFirst(temp->mData, data)))
00316 {
00317 current = temp;
00318 temp = *(current->mForward + level);
00319 }
00320 *(mUpdate + level) = current;
00321 }
00322 }
00323 else
00324 {
00325 for (level = mLevel - 1; level >= 0; level--)
00326 {
00327 temp = *(current->mForward + level);
00328 while ( (temp)
00329 &&(temp->mData < data))
00330 {
00331 current = temp;
00332 temp = *(current->mForward + level);
00333 }
00334 *(mUpdate + level) = current;
00335 }
00336 }
00337
00338
00339
00340 current = *current->mForward;
00341
00342 if (current)
00343 {
00344 return mEquals(current->mData, data);
00345 }
00346 else
00347 {
00348 return FALSE;
00349 }
00350 }
00351
00352
00353 template <class DATA_TYPE, S32 BINARY_DEPTH>
00354 inline S32 LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::getLength()
00355 {
00356 U32 length = 0;
00357 for (LLPtrSkipNode* temp = *(mHead.mForward); temp != NULL; temp = temp->mForward[0])
00358 {
00359 length++;
00360 }
00361 return length;
00362 }
00363
00364 template <class DATA_TYPE, S32 BINARY_DEPTH>
00365 inline BOOL LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::removeData(const DATA_TYPE *data)
00366 {
00367 S32 level;
00368 LLPtrSkipNode *current = &mHead;
00369 LLPtrSkipNode *temp;
00370
00371
00372 if (mInsertFirst)
00373 {
00374 for (level = mLevel - 1; level >= 0; level--)
00375 {
00376 temp = *(current->mForward + level);
00377 while ( (temp)
00378 &&(mInsertFirst(temp->mData, data)))
00379 {
00380 current = temp;
00381 temp = *(current->mForward + level);
00382 }
00383 *(mUpdate + level) = current;
00384 }
00385 }
00386 else
00387 {
00388 for (level = mLevel - 1; level >= 0; level--)
00389 {
00390 temp = *(current->mForward + level);
00391 while ( (temp)
00392 &&(temp->mData < data))
00393 {
00394 current = temp;
00395 temp = *(current->mForward + level);
00396 }
00397 *(mUpdate + level) = current;
00398 }
00399 }
00400
00401
00402
00403 current = *current->mForward;
00404
00405 if (!current)
00406 {
00407
00408 return FALSE;
00409 }
00410
00411
00412 if (!mEquals(current->mData, data))
00413 {
00414
00415 return FALSE;
00416 }
00417 else
00418 {
00419
00420 for (level = 0; level < mLevel; level++)
00421 {
00422 if (mUpdate[level]->mForward[level] != current)
00423 {
00424
00425 break;
00426 }
00427 mUpdate[level]->mForward[level] = current->mForward[level];
00428 }
00429
00430
00431 current->removeData();
00432 delete current;
00433
00434
00435 while ( (mLevel > 1)
00436 &&(!mHead.mForward[mLevel - 1]))
00437 {
00438 mLevel--;
00439 }
00440 }
00441 return TRUE;
00442 }
00443
00444
00445 template <class DATA_TYPE, S32 BINARY_DEPTH>
00446 inline BOOL LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::moveData(const DATA_TYPE *data, LLPtrSkipList *newlist, BOOL b_sort)
00447 {
00448 BOOL removed = removeData(data);
00449 BOOL added = newlist->addData(data);
00450 return removed && added;
00451 }
00452
00453 template <class DATA_TYPE, S32 BINARY_DEPTH>
00454 inline BOOL LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::moveCurrentData(LLPtrSkipList *newlist, BOOL b_sort)
00455 {
00456 if (mCurrentOperatingp)
00457 {
00458 mCurrentp = mCurrentOperatingp->mForward[0];
00459 BOOL removed = removeData(mCurrentOperatingp);
00460 BOOL added = newlist->addData(mCurrentOperatingp);
00461 mCurrentOperatingp = mCurrentp;
00462 return removed && added;
00463 }
00464 return FALSE;
00465 }
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479 template <class DATA_TYPE, S32 BINARY_DEPTH>
00480 inline void LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::removeAllNodes()
00481 {
00482 LLPtrSkipNode *temp;
00483
00484 mCurrentp = *(mHead.mForward);
00485
00486 while (mCurrentp)
00487 {
00488 temp = mCurrentp->mForward[0];
00489 mCurrentp->removeData();
00490 delete mCurrentp;
00491 mCurrentp = temp;
00492 }
00493
00494 S32 i;
00495 for (i = 0; i < BINARY_DEPTH; i++)
00496 {
00497 mHead.mForward[i] = NULL;
00498 mUpdate[i] = NULL;
00499 }
00500
00501 mCurrentp = *(mHead.mForward);
00502 mCurrentOperatingp = *(mHead.mForward);
00503 }
00504
00505 template <class DATA_TYPE, S32 BINARY_DEPTH>
00506 inline BOOL LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::deleteData(const DATA_TYPE *data)
00507 {
00508 S32 level;
00509 LLPtrSkipNode *current = &mHead;
00510 LLPtrSkipNode *temp;
00511
00512
00513 if (mInsertFirst)
00514 {
00515 for (level = mLevel - 1; level >= 0; level--)
00516 {
00517 temp = *(current->mForward + level);
00518 while ( (temp)
00519 &&(mInsertFirst(temp->mData, data)))
00520 {
00521 current = temp;
00522 temp = *(current->mForward + level);
00523 }
00524 *(mUpdate + level) = current;
00525 }
00526 }
00527 else
00528 {
00529 for (level = mLevel - 1; level >= 0; level--)
00530 {
00531 temp = *(current->mForward + level);
00532 while ( (temp)
00533 &&(temp->mData < data))
00534 {
00535 current = temp;
00536 temp = *(current->mForward + level);
00537 }
00538 *(mUpdate + level) = current;
00539 }
00540 }
00541
00542
00543
00544 current = *current->mForward;
00545
00546 if (!current)
00547 {
00548
00549 return FALSE;
00550 }
00551
00552
00553 if (!mEquals(current->mData, data))
00554 {
00555
00556 return FALSE;
00557 }
00558 else
00559 {
00560
00561 if (current == mCurrentp)
00562 {
00563 mCurrentp = current->mForward[0];
00564 }
00565
00566 if (current == mCurrentOperatingp)
00567 {
00568 mCurrentOperatingp = current->mForward[0];
00569 }
00570
00571
00572 for (level = 0; level < mLevel; level++)
00573 {
00574 if (mUpdate[level]->mForward[level] != current)
00575 {
00576
00577 break;
00578 }
00579 mUpdate[level]->mForward[level] = current->mForward[level];
00580 }
00581
00582
00583 current->deleteData();
00584 delete current;
00585
00586
00587 while ( (mLevel > 1)
00588 &&(!mHead.mForward[mLevel - 1]))
00589 {
00590 mLevel--;
00591 }
00592 }
00593 return TRUE;
00594 }
00595
00596
00597 template <class DATA_TYPE, S32 BINARY_DEPTH>
00598 inline void LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::deleteAllData()
00599 {
00600 LLPtrSkipNode *temp;
00601
00602 mCurrentp = *(mHead.mForward);
00603
00604 while (mCurrentp)
00605 {
00606 temp = mCurrentp->mForward[0];
00607 mCurrentp->deleteData();
00608 delete mCurrentp;
00609 mCurrentp = temp;
00610 }
00611
00612 S32 i;
00613 for (i = 0; i < BINARY_DEPTH; i++)
00614 {
00615 mHead.mForward[i] = NULL;
00616 mUpdate[i] = NULL;
00617 }
00618
00619 mCurrentp = *(mHead.mForward);
00620 mCurrentOperatingp = *(mHead.mForward);
00621 }
00622
00623
00624 template <class DATA_TYPE, S32 BINARY_DEPTH>
00625 inline void LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::resetList()
00626 {
00627 mCurrentp = *(mHead.mForward);
00628 mCurrentOperatingp = *(mHead.mForward);
00629 }
00630
00631
00632 template <class DATA_TYPE, S32 BINARY_DEPTH>
00633 inline DATA_TYPE *LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::getCurrentData()
00634 {
00635 if (mCurrentp)
00636 {
00637 mCurrentOperatingp = mCurrentp;
00638 mCurrentp = *mCurrentp->mForward;
00639 return mCurrentOperatingp->mData;
00640 }
00641 else
00642 {
00643
00644 return 0;
00645 }
00646 }
00647
00648
00649 template <class DATA_TYPE, S32 BINARY_DEPTH>
00650 inline DATA_TYPE *LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::getNextData()
00651 {
00652 if (mCurrentp)
00653 {
00654 mCurrentOperatingp = mCurrentp;
00655 mCurrentp = *mCurrentp->mForward;
00656 return mCurrentOperatingp->mData;
00657 }
00658 else
00659 {
00660
00661 return 0;
00662 }
00663 }
00664
00665
00666
00667 template <class DATA_TYPE, S32 BINARY_DEPTH>
00668 inline void LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::removeCurrentData()
00669 {
00670 if (mCurrentOperatingp)
00671 {
00672 removeData(mCurrentOperatingp->mData);
00673 }
00674 }
00675
00676
00677
00678 template <class DATA_TYPE, S32 BINARY_DEPTH>
00679 inline void LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::deleteCurrentData()
00680 {
00681 if (mCurrentOperatingp)
00682 {
00683 deleteData(mCurrentOperatingp->mData);
00684 }
00685 }
00686
00687
00688 template <class DATA_TYPE, S32 BINARY_DEPTH>
00689 inline DATA_TYPE *LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::getFirstData()
00690 {
00691 mCurrentp = *(mHead.mForward);
00692 mCurrentOperatingp = *(mHead.mForward);
00693 if (mCurrentp)
00694 {
00695 mCurrentOperatingp = mCurrentp;
00696 mCurrentp = mCurrentp->mForward[0];
00697 return mCurrentOperatingp->mData;
00698 }
00699 else
00700 {
00701
00702 return 0;
00703 }
00704 }
00705
00706 template <class DATA_TYPE, S32 BINARY_DEPTH>
00707 inline BOOL LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::corrupt()
00708 {
00709 LLPtrSkipNode *previous = mHead.mForward[0];
00710
00711
00712 if (!previous) return FALSE;
00713
00714 LLPtrSkipNode *current = previous->mForward[0];
00715 while(current)
00716 {
00717 if (!mInsertFirst(previous->mData, current->mData))
00718 {
00719
00720 return TRUE;
00721 }
00722 current = current->mForward[0];
00723 }
00724 return FALSE;
00725 }
00726
00727 #endif