llptrskipmap.h
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:28k
源码类别:

游戏引擎

开发平台:

C++ Builder

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