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

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llskipmap.h
  3.  * @brief Associative container based on the skiplist algorithm.
  4.  *
  5.  * $LicenseInfo:firstyear=2003&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2003-2010, Linden Research, Inc.
  8.  * 
  9.  * Second Life Viewer Source Code
  10.  * The source code in this file ("Source Code") is provided by Linden Lab
  11.  * to you under the terms of the GNU General Public License, version 2.0
  12.  * ("GPL"), unless you have obtained a separate licensing agreement
  13.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  14.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16.  * 
  17.  * There are special exceptions to the terms and conditions of the GPL as
  18.  * it is applied to this Source Code. View the full text of the exception
  19.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  20.  * online at
  21.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22.  * 
  23.  * By copying, modifying or distributing this software, you acknowledge
  24.  * that you have read and understood your obligations described above,
  25.  * and agree to abide by those obligations.
  26.  * 
  27.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29.  * COMPLETENESS OR PERFORMANCE.
  30.  * $/LicenseInfo$
  31.  */
  32. #ifndef LL_LLSKIPMAP_H
  33. #define LL_LLSKIPMAP_H
  34. #include "llerror.h"
  35. template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH = 8> 
  36. class LLSkipMap
  37. {
  38. public:
  39. // basic constructor
  40. LLSkipMap();
  41. // basic constructor including sorter
  42. LLSkipMap(BOOL (*insert_first)(const INDEX_TYPE &first, const INDEX_TYPE &second), 
  43.    BOOL (*equals)(const INDEX_TYPE &first, const INDEX_TYPE &second));
  44. ~LLSkipMap();
  45. void setInsertFirst(BOOL (*insert_first)(const INDEX_TYPE &first, const INDEX_TYPE &second));
  46. void setEquals(BOOL (*equals)(const INDEX_TYPE &first, const INDEX_TYPE &second));
  47. DATA_TYPE &addData(const INDEX_TYPE &index, DATA_TYPE datap);
  48. DATA_TYPE &addData(const INDEX_TYPE &index);
  49. DATA_TYPE &getData(const INDEX_TYPE &index);
  50. DATA_TYPE &operator[](const INDEX_TYPE &index);
  51. // If index present, returns data.
  52. // If index not present, adds <index,NULL> and returns NULL.
  53. DATA_TYPE &getData(const INDEX_TYPE &index, BOOL &b_new_entry);
  54. // Returns TRUE if data present in map.
  55. BOOL checkData(const INDEX_TYPE &index);
  56. // Returns TRUE if key is present in map. This is useful if you
  57. // are potentially storing NULL pointers in the map
  58. BOOL checkKey(const INDEX_TYPE &index);
  59. // If there, returns the data.
  60. // If not, returns NULL.
  61. // Never adds entries to the map.
  62. DATA_TYPE getIfThere(const INDEX_TYPE &index);
  63. INDEX_TYPE reverseLookup(const DATA_TYPE datap);
  64. // returns number of items in the list
  65. S32 getLength(); // WARNING!  getLength is O(n), not O(1)!
  66. BOOL removeData(const INDEX_TYPE &index);
  67. // remove all nodes from the list but do not delete data
  68. void removeAllData();
  69. // place mCurrentp on first node
  70. void resetList();
  71. // return the data currently pointed to
  72. DATA_TYPE getCurrentDataWithoutIncrement();
  73. // return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp
  74. DATA_TYPE getCurrentData();
  75. // same as getCurrentData() but a more intuitive name for the operation
  76. DATA_TYPE getNextData();
  77. INDEX_TYPE getNextKey();
  78. // return the key currently pointed to
  79. INDEX_TYPE getCurrentKeyWithoutIncrement();
  80. // The internal iterator is at the end of the list.
  81. BOOL notDone() const;
  82. // remove the Node at mCurentOperatingp
  83. // leave mCurrentp and mCurentOperatingp on the next entry
  84. void removeCurrentData();
  85. void deleteCurrentData();
  86. // reset the list and return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp
  87. DATA_TYPE getFirstData();
  88. INDEX_TYPE getFirstKey();
  89. class LLSkipMapNode
  90. {
  91. public:
  92. LLSkipMapNode()
  93. {
  94. S32 i;
  95. for (i = 0; i < BINARY_DEPTH; i++)
  96. {
  97. mForward[i] = NULL;
  98. }
  99. U8  *zero = (U8 *)&mIndex;
  100. for (i = 0; i < (S32)sizeof(INDEX_TYPE); i++)
  101. {
  102. *(zero + i) = 0;
  103. }
  104. zero = (U8 *)&mData;
  105. for (i = 0; i < (S32)sizeof(DATA_TYPE); i++)
  106. {
  107. *(zero + i) = 0;
  108. }
  109. }
  110. LLSkipMapNode(const INDEX_TYPE &index)
  111. : mIndex(index)
  112. {
  113. S32 i;
  114. for (i = 0; i < BINARY_DEPTH; i++)
  115. {
  116. mForward[i] = NULL;
  117. }
  118. U8 *zero = (U8 *)&mData;
  119. for (i = 0; i < (S32)sizeof(DATA_TYPE); i++)
  120. {
  121. *(zero + i) = 0;
  122. }
  123. }
  124. LLSkipMapNode(const INDEX_TYPE &index, DATA_TYPE datap)
  125. : mIndex(index)
  126. {
  127. S32 i;
  128. for (i = 0; i < BINARY_DEPTH; i++)
  129. {
  130. mForward[i] = NULL;
  131. }
  132. mData = datap;
  133. }
  134. ~LLSkipMapNode()
  135. {
  136. }
  137. INDEX_TYPE mIndex;
  138. DATA_TYPE mData;
  139. LLSkipMapNode *mForward[BINARY_DEPTH];
  140. private:
  141. // Disallow copying of LLSkipMapNodes by not implementing these methods.
  142. LLSkipMapNode(const LLSkipMapNode &);
  143. LLSkipMapNode &operator=(const LLSkipMapNode &rhs);
  144. };
  145. static BOOL defaultEquals(const INDEX_TYPE &first, const INDEX_TYPE &second)
  146. {
  147. return first == second;
  148. }
  149. private:
  150. // don't generate implicit copy constructor or copy assignment
  151. LLSkipMap(const LLSkipMap &);
  152. LLSkipMap &operator=(const LLSkipMap &);
  153. private:
  154. LLSkipMapNode mHead;
  155. LLSkipMapNode *mUpdate[BINARY_DEPTH];
  156. LLSkipMapNode *mCurrentp;
  157. LLSkipMapNode *mCurrentOperatingp;
  158. S32 mLevel;
  159. BOOL (*mInsertFirst)(const INDEX_TYPE &first, const INDEX_TYPE &second);
  160. BOOL (*mEquals)(const INDEX_TYPE &first, const INDEX_TYPE &second);
  161. S32 mNumberOfSteps;
  162. };
  163. //////////////////////////////////////////////////
  164. //
  165. // LLSkipMap implementation
  166. //
  167. template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
  168. inline LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::LLSkipMap()
  169. : mInsertFirst(NULL),
  170. mEquals(defaultEquals)
  171. {
  172. // Skipmaps must have binary depth of at least 2
  173. cassert(BINARY_DEPTH >= 2);
  174. S32 i;
  175. for (i = 0; i < BINARY_DEPTH; i++)
  176. {
  177. mUpdate[i] = NULL;
  178. }
  179. mLevel = 1;
  180. mCurrentp = *(mHead.mForward);
  181. mCurrentOperatingp = *(mHead.mForward);
  182. }
  183. template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
  184. inline LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::LLSkipMap(BOOL (*insert_first)(const INDEX_TYPE &first, const INDEX_TYPE &second), 
  185.    BOOL (*equals)(const INDEX_TYPE &first, const INDEX_TYPE &second)) 
  186. : mInsertFirst(insert_first),
  187. mEquals(equals)
  188. {
  189. // Skipmaps must have binary depth of at least 2
  190. cassert(BINARY_DEPTH >= 2);
  191. mLevel = 1;
  192. S32 i;
  193. for (i = 0; i < BINARY_DEPTH; i++)
  194. {
  195. mHead.mForward[i] = NULL;
  196. mUpdate[i] = NULL;
  197. }
  198. mCurrentp = *(mHead.mForward);
  199. mCurrentOperatingp = *(mHead.mForward);
  200. }
  201. template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
  202. inline LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::~LLSkipMap()
  203. {
  204. removeAllData();
  205. }
  206. template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
  207. inline void LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::setInsertFirst(BOOL (*insert_first)(const INDEX_TYPE &first, const INDEX_TYPE &second))
  208. {
  209. mInsertFirst = insert_first;
  210. }
  211. template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
  212. inline void LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::setEquals(BOOL (*equals)(const INDEX_TYPE &first, const INDEX_TYPE &second))
  213. {
  214. mEquals = equals;
  215. }
  216. template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
  217. inline DATA_TYPE &LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::addData(const INDEX_TYPE &index, DATA_TYPE datap)
  218. {
  219. S32 level;
  220. LLSkipMapNode *current = &mHead;
  221. LLSkipMapNode *temp;
  222. // find the pointer one in front of the one we want
  223. if (mInsertFirst)
  224. {
  225. for (level = mLevel - 1; level >= 0; level--)
  226. {
  227. temp = *(current->mForward + level);
  228. while (  (temp)
  229.    &&(mInsertFirst(temp->mIndex, index)))
  230. {
  231. current = temp;
  232. temp = *(current->mForward + level);
  233. }
  234. *(mUpdate + level) = current;
  235. }
  236. }
  237. else
  238. {
  239. for (level = mLevel - 1; level >= 0; level--)
  240. {
  241. temp = *(current->mForward + level);
  242. while (  (temp)
  243.    &&(temp->mIndex < index))
  244. {
  245. current = temp;
  246. temp = *(current->mForward + level);
  247. }
  248. *(mUpdate + level) = current;
  249. }
  250. }
  251. // we're now just in front of where we want to be . . . take one step forward
  252. current = *current->mForward;
  253. // replace the existing data if a node is already there
  254. if (  (current)
  255. &&(mEquals(current->mIndex, index)))
  256. {
  257. current->mData = datap;
  258. return current->mData;
  259. }
  260. // now add the new node
  261. S32 newlevel;
  262. for (newlevel = 1; newlevel <= mLevel && newlevel < BINARY_DEPTH; newlevel++)
  263. {
  264. if (rand() & 1)
  265. {
  266. break;
  267. }
  268. }
  269. LLSkipMapNode *snode = new LLSkipMapNode(index, datap);
  270. if (newlevel > mLevel)
  271. {
  272. mHead.mForward[mLevel] = NULL;
  273. mUpdate[mLevel] = &mHead;
  274. mLevel = newlevel;
  275. }
  276. for (level = 0; level < newlevel; level++)
  277. {
  278. snode->mForward[level] = mUpdate[level]->mForward[level];
  279. mUpdate[level]->mForward[level] = snode;
  280. }
  281. return snode->mData;
  282. }
  283. template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
  284. inline DATA_TYPE &LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::addData(const INDEX_TYPE &index)
  285. {
  286. S32 level;
  287. LLSkipMapNode *current = &mHead;
  288. LLSkipMapNode *temp;
  289. // find the pointer one in front of the one we want
  290. if (mInsertFirst)
  291. {
  292. for (level = mLevel - 1; level >= 0; level--)
  293. {
  294. temp = *(current->mForward + level);
  295. while (  (temp)
  296.    &&(mInsertFirst(temp->mIndex, index)))
  297. {
  298. current = temp;
  299. temp = *(current->mForward + level);
  300. }
  301. *(mUpdate + level) = current;
  302. }
  303. }
  304. else
  305. {
  306. for (level = mLevel - 1; level >= 0; level--)
  307. {
  308. temp = *(current->mForward + level);
  309. while (  (temp)
  310.    &&(temp->mIndex < index))
  311. {
  312. current = temp;
  313. temp = *(current->mForward + level);
  314. }
  315. *(mUpdate + level) = current;
  316. }
  317. }
  318. // we're now just in front of where we want to be . . . take one step forward
  319. current = *current->mForward;
  320. // now add the new node
  321. S32 newlevel;
  322. for (newlevel = 1; newlevel <= mLevel && newlevel < BINARY_DEPTH; newlevel++)
  323. {
  324. if (rand() & 1)
  325. break;
  326. }
  327. LLSkipMapNode *snode = new LLSkipMapNode(index);
  328. if (newlevel > mLevel)
  329. {
  330. mHead.mForward[mLevel] = NULL;
  331. mUpdate[mLevel] = &mHead;
  332. mLevel = newlevel;
  333. }
  334. for (level = 0; level < newlevel; level++)
  335. {
  336. snode->mForward[level] = mUpdate[level]->mForward[level];
  337. mUpdate[level]->mForward[level] = snode;
  338. }
  339. return snode->mData;
  340. }
  341. template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
  342. inline DATA_TYPE &LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::getData(const INDEX_TYPE &index)
  343. {
  344. S32 level;
  345. LLSkipMapNode *current = &mHead;
  346. LLSkipMapNode *temp;
  347. mNumberOfSteps = 0;
  348. // find the pointer one in front of the one we want
  349. if (mInsertFirst)
  350. {
  351. for (level = mLevel - 1; level >= 0; level--)
  352. {
  353. temp = *(current->mForward + level);
  354. while (  (temp)
  355.    &&(mInsertFirst(temp->mIndex, index)))
  356. {
  357. current = temp;
  358. temp = *(current->mForward + level);
  359. mNumberOfSteps++;
  360. }
  361. *(mUpdate + level) = current;
  362. }
  363. }
  364. else
  365. {
  366. for (level = mLevel - 1; level >= 0; level--)
  367. {
  368. temp = *(current->mForward + level);
  369. while (  (temp)
  370.    &&(temp->mIndex < index))
  371. {
  372. current = temp;
  373. temp = *(current->mForward + level);
  374. mNumberOfSteps++;
  375. }
  376. *(mUpdate + level) = current;
  377. }
  378. }
  379. // we're now just in front of where we want to be . . . take one step forward
  380. current = *current->mForward;
  381. mNumberOfSteps++;
  382. if (  (current)
  383. &&(mEquals(current->mIndex, index)))
  384. {
  385. return current->mData;
  386. }
  387. // now add the new node
  388. S32 newlevel;
  389. for (newlevel = 1; newlevel <= mLevel && newlevel < BINARY_DEPTH; newlevel++)
  390. {
  391. if (rand() & 1)
  392. break;
  393. }
  394. LLSkipMapNode *snode = new LLSkipMapNode(index);
  395. if (newlevel > mLevel)
  396. {
  397. mHead.mForward[mLevel] = NULL;
  398. mUpdate[mLevel] = &mHead;
  399. mLevel = newlevel;
  400. }
  401. for (level = 0; level < newlevel; level++)
  402. {
  403. snode->mForward[level] = mUpdate[level]->mForward[level];
  404. mUpdate[level]->mForward[level] = snode;
  405. }
  406. return snode->mData;
  407. }
  408. template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
  409. inline DATA_TYPE &LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::operator[](const INDEX_TYPE &index)
  410. {
  411. return getData(index);
  412. }
  413. // If index present, returns data.
  414. // If index not present, adds <index,NULL> and returns NULL.
  415. template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
  416. inline DATA_TYPE &LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::getData(const INDEX_TYPE &index, BOOL &b_new_entry)
  417. {
  418. S32 level;
  419. LLSkipMapNode *current = &mHead;
  420. LLSkipMapNode *temp;
  421. mNumberOfSteps = 0;
  422. // find the pointer one in front of the one we want
  423. if (mInsertFirst)
  424. {
  425. for (level = mLevel - 1; level >= 0; level--)
  426. {
  427. temp = *(current->mForward + level);
  428. while (  (temp)
  429.    &&(mInsertFirst(temp->mIndex, index)))
  430. {
  431. current = temp;
  432. temp = *(current->mForward + level);
  433. mNumberOfSteps++;
  434. }
  435. *(mUpdate + level) = current;
  436. }
  437. }
  438. else
  439. {
  440. for (level = mLevel - 1; level >= 0; level--)
  441. {
  442. temp = *(current->mForward + level);
  443. while (  (temp)
  444.    &&(temp->mIndex < index))
  445. {
  446. current = temp;
  447. temp = *(current->mForward + level);
  448. mNumberOfSteps++;
  449. }
  450. *(mUpdate + level) = current;
  451. }
  452. }
  453. // we're now just in front of where we want to be . . . take one step forward
  454. mNumberOfSteps++;
  455. current = *current->mForward;
  456. if (  (current)
  457. &&(mEquals(current->mIndex, index)))
  458. {
  459. return current->mData;
  460. }
  461. b_new_entry = TRUE;
  462. addData(index);
  463. return current->mData;
  464. }
  465. // Returns TRUE if data present in map.
  466. template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
  467. inline BOOL LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::checkData(const INDEX_TYPE &index)
  468. {
  469. S32 level;
  470. LLSkipMapNode *current = &mHead;
  471. LLSkipMapNode *temp;
  472. // find the pointer one in front of the one we want
  473. if (mInsertFirst)
  474. {
  475. for (level = mLevel - 1; level >= 0; level--)
  476. {
  477. temp = *(current->mForward + level);
  478. while (  (temp)
  479.    &&(mInsertFirst(temp->mIndex, index)))
  480. {
  481. current = temp;
  482. temp = *(current->mForward + level);
  483. }
  484. *(mUpdate + level) = current;
  485. }
  486. }
  487. else
  488. {
  489. for (level = mLevel - 1; level >= 0; level--)
  490. {
  491. temp = *(current->mForward + level);
  492. while (  (temp)
  493.    &&(temp->mIndex < index))
  494. {
  495. current = temp;
  496. temp = *(current->mForward + level);
  497. }
  498. *(mUpdate + level) = current;
  499. }
  500. }
  501. // we're now just in front of where we want to be . . . take one step forward
  502. current = *current->mForward;
  503. if (current)
  504. {
  505. // Gets rid of some compiler ambiguity for the LLPointer<> templated class.
  506. if (current->mData)
  507. {
  508. return mEquals(current->mIndex, index);
  509. }
  510. }
  511. return FALSE;
  512. }
  513. // Returns TRUE if key is present in map. This is useful if you
  514. // are potentially storing NULL pointers in the map
  515. template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
  516. inline BOOL LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::checkKey(const INDEX_TYPE &index)
  517. {
  518. S32 level;
  519. LLSkipMapNode *current = &mHead;
  520. LLSkipMapNode *temp;
  521. // find the pointer one in front of the one we want
  522. if (mInsertFirst)
  523. {
  524. for (level = mLevel - 1; level >= 0; level--)
  525. {
  526. temp = *(current->mForward + level);
  527. while (  (temp)
  528.    &&(mInsertFirst(temp->mIndex, index)))
  529. {
  530. current = temp;
  531. temp = *(current->mForward + level);
  532. }
  533. *(mUpdate + level) = current;
  534. }
  535. }
  536. else
  537. {
  538. for (level = mLevel - 1; level >= 0; level--)
  539. {
  540. temp = *(current->mForward + level);
  541. while (  (temp)
  542.    &&(temp->mIndex < index))
  543. {
  544. current = temp;
  545. temp = *(current->mForward + level);
  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. current = *current->mForward;
  552. if (current)
  553. {
  554. return mEquals(current->mIndex, index);
  555. }
  556. return FALSE;
  557. }
  558. // If there, returns the data.
  559. // If not, returns NULL.
  560. // Never adds entries to the map.
  561. template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
  562. inline DATA_TYPE LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::getIfThere(const INDEX_TYPE &index)
  563. {
  564. S32 level;
  565. LLSkipMapNode *current = &mHead;
  566. LLSkipMapNode *temp;
  567. mNumberOfSteps = 0;
  568. // find the pointer one in front of the one we want
  569. if (mInsertFirst)
  570. {
  571. for (level = mLevel - 1; level >= 0; level--)
  572. {
  573. temp = *(current->mForward + level);
  574. while (  (temp)
  575.    &&(mInsertFirst(temp->mIndex, index)))
  576. {
  577. current = temp;
  578. temp = *(current->mForward + level);
  579. mNumberOfSteps++;
  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. mNumberOfSteps++;
  595. }
  596. *(mUpdate + level) = current;
  597. }
  598. }
  599. // we're now just in front of where we want to be . . . take one step forward
  600. mNumberOfSteps++;
  601. current = *current->mForward;
  602. if (current)
  603. {
  604. if (mEquals(current->mIndex, index))
  605. {
  606. return current->mData;
  607. }
  608. }
  609. // Avoid Linux compiler warning on returning NULL.
  610. return DATA_TYPE();
  611. }
  612. template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
  613. inline INDEX_TYPE LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::reverseLookup(const DATA_TYPE datap)
  614. {
  615. LLSkipMapNode *current = &mHead;
  616. while (current)
  617. {
  618. if (datap == current->mData)
  619. {
  620. return current->mIndex;
  621. }
  622. current = *current->mForward;
  623. }
  624. // not found! return NULL
  625. return INDEX_TYPE();
  626. }
  627. // returns number of items in the list
  628. template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
  629. inline S32 LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::getLength()
  630. {
  631. U32 length = 0;
  632. for (LLSkipMapNode* temp = *(mHead.mForward); temp != NULL; temp = temp->mForward[0])
  633. {
  634. length++;
  635. }
  636. return length;
  637. }
  638. template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
  639. inline BOOL LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::removeData(const INDEX_TYPE &index)
  640. {
  641. S32 level;
  642. LLSkipMapNode *current = &mHead;
  643. LLSkipMapNode *temp;
  644. // find the pointer one in front of the one we want
  645. if (mInsertFirst)
  646. {
  647. for (level = mLevel - 1; level >= 0; level--)
  648. {
  649. temp = *(current->mForward + level);
  650. while (  (temp)
  651.    &&(mInsertFirst(temp->mIndex, index)))
  652. {
  653. current = temp;
  654. temp = *(current->mForward + level);
  655. }
  656. *(mUpdate + level) = current;
  657. }
  658. }
  659. else
  660. {
  661. for (level = mLevel - 1; level >= 0; level--)
  662. {
  663. temp = *(current->mForward + level);
  664. while (  (temp)
  665.    &&(temp->mIndex < index))
  666. {
  667. current = temp;
  668. temp = *(current->mForward + level);
  669. }
  670. *(mUpdate + level) = current;
  671. }
  672. }
  673. // we're now just in front of where we want to be . . . take one step forward
  674. current = *current->mForward;
  675. if (!current)
  676. {
  677. // empty list or beyond the end!
  678. return FALSE;
  679. }
  680. // is this the one we want?
  681. if (!mEquals(current->mIndex, index))
  682. {
  683. // nope!
  684. return FALSE;
  685. }
  686. else
  687. {
  688. // do we need to fix current or currentop?
  689. if (current == mCurrentp)
  690. {
  691. mCurrentp = *current->mForward;
  692. }
  693. if (current == mCurrentOperatingp)
  694. {
  695. mCurrentOperatingp = *current->mForward;
  696. }
  697. // yes it is!  change pointers as required
  698. for (level = 0; level < mLevel; level++)
  699. {
  700. if (*((*(mUpdate + level))->mForward + level) != current)
  701. {
  702. // cool, we've fixed all the pointers!
  703. break;
  704. }
  705. *((*(mUpdate + level))->mForward + level) = *(current->mForward + level);
  706. }
  707. delete current;
  708. // clean up mHead
  709. while (  (mLevel > 1)
  710.    &&(!*(mHead.mForward + mLevel - 1)))
  711. {
  712. mLevel--;
  713. }
  714. }
  715. return TRUE;
  716. }
  717. // remove all nodes from the list but do not delete data
  718. template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
  719. void LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::removeAllData()
  720. {
  721. LLSkipMapNode *temp;
  722. // reset mCurrentp
  723. mCurrentp = *(mHead.mForward);
  724. while (mCurrentp)
  725. {
  726. temp = mCurrentp->mForward[0];
  727. delete mCurrentp;
  728. mCurrentp = temp;
  729. }
  730. S32 i;
  731. for (i = 0; i < BINARY_DEPTH; i++)
  732. {
  733. mHead.mForward[i] = NULL;
  734. mUpdate[i] = NULL;
  735. }
  736. mCurrentp = *(mHead.mForward);
  737. mCurrentOperatingp = *(mHead.mForward);
  738. }
  739. // place mCurrentp on first node
  740. template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
  741. inline void LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::resetList()
  742. {
  743. mCurrentp = *(mHead.mForward);
  744. mCurrentOperatingp = *(mHead.mForward);
  745. }
  746. // return the data currently pointed to
  747. template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
  748. inline DATA_TYPE LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::getCurrentDataWithoutIncrement()
  749. {
  750. if (mCurrentOperatingp)
  751. {
  752. return mCurrentOperatingp->mData;
  753. }
  754. else
  755. {
  756. return DATA_TYPE();
  757. }
  758. }
  759. // return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp
  760. template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
  761. inline DATA_TYPE LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::getCurrentData()
  762. {
  763. if (mCurrentp)
  764. {
  765. mCurrentOperatingp = mCurrentp;
  766. mCurrentp = mCurrentp->mForward[0];
  767. return mCurrentOperatingp->mData;
  768. }
  769. else
  770. {
  771. // Basic types, like int, have default constructors that initialize
  772. // them to zero.  g++ 2.95 supports this.  "int()" is zero.
  773. // This also is nice for LLUUID()
  774. return DATA_TYPE();
  775. }
  776. }
  777. // same as getCurrentData() but a more intuitive name for the operation
  778. template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
  779. inline DATA_TYPE LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::getNextData()
  780. {
  781. if (mCurrentp)
  782. {
  783. mCurrentOperatingp = mCurrentp;
  784. mCurrentp = mCurrentp->mForward[0];
  785. return mCurrentOperatingp->mData;
  786. }
  787. else
  788. {
  789. // Basic types, like int, have default constructors that initialize
  790. // them to zero.  g++ 2.95 supports this.  "int()" is zero.
  791. // This also is nice for LLUUID()
  792. return DATA_TYPE();
  793. }
  794. }
  795. template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
  796. inline INDEX_TYPE LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::getNextKey()
  797. {
  798. if (mCurrentp)
  799. {
  800. mCurrentOperatingp = mCurrentp;
  801. mCurrentp = mCurrentp->mForward[0];
  802. return mCurrentOperatingp->mIndex;
  803. }
  804. else
  805. {
  806. return mHead.mIndex;
  807. }
  808. }
  809. // return the key currently pointed to
  810. template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
  811. inline INDEX_TYPE LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::getCurrentKeyWithoutIncrement()
  812. {
  813. if (mCurrentOperatingp)
  814. {
  815. return mCurrentOperatingp->mIndex;
  816. }
  817. else
  818. {
  819. // See comment for getNextData()
  820. return INDEX_TYPE();
  821. }
  822. }
  823. template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
  824. inline BOOL LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::notDone() const
  825. {
  826. if (mCurrentOperatingp)
  827. {
  828. return TRUE;
  829. }
  830. else
  831. {
  832. return FALSE;
  833. }
  834. }
  835. // remove the Node at mCurentOperatingp
  836. // leave mCurrentp and mCurentOperatingp on the next entry
  837. template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
  838. inline void LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::removeCurrentData()
  839. {
  840. if (mCurrentOperatingp)
  841. {
  842. removeData(mCurrentOperatingp->mIndex);
  843. }
  844. }
  845. template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
  846. inline void LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::deleteCurrentData()
  847. {
  848. if (mCurrentOperatingp)
  849. {
  850. deleteData(mCurrentOperatingp->mIndex);
  851. }
  852. }
  853. // reset the list and return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp
  854. template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
  855. inline DATA_TYPE LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::getFirstData()
  856. {
  857. mCurrentp = *(mHead.mForward);
  858. mCurrentOperatingp = *(mHead.mForward);
  859. if (mCurrentp)
  860. {
  861. mCurrentOperatingp = mCurrentp;
  862. mCurrentp = mCurrentp->mForward[0];
  863. return mCurrentOperatingp->mData;
  864. }
  865. else
  866. {
  867. // See comment for getNextData()
  868. return DATA_TYPE();
  869. }
  870. }
  871. template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
  872. inline INDEX_TYPE LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::getFirstKey()
  873. {
  874. mCurrentp = *(mHead.mForward);
  875. mCurrentOperatingp = *(mHead.mForward);
  876. if (mCurrentp)
  877. {
  878. mCurrentOperatingp = mCurrentp;
  879. mCurrentp = mCurrentp->mForward[0];
  880. return mCurrentOperatingp->mIndex;
  881. }
  882. else
  883. {
  884. return mHead.mIndex;
  885. }
  886. }
  887. #endif