PageRenderTime 47ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/llcommon/llptrskipmap.h

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