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

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llskiplist.h
  3.  * @brief skip list implementation
  4.  *
  5.  * $LicenseInfo:firstyear=2001&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2001-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_LLSKIPLIST_H
  33. #define LL_LLSKIPLIST_H
  34. #include "llrand.h"
  35. #include "llrand.h"
  36. // NOTA BENE: Insert first needs to be < NOT <=
  37. // Binary depth must be >= 2
  38. template <class DATA_TYPE, S32 BINARY_DEPTH = 10>
  39. class LLSkipList
  40. {
  41. public:
  42. typedef BOOL (*compare)(const DATA_TYPE& first, const DATA_TYPE& second);
  43. typedef compare insert_func;
  44. typedef compare equals_func;
  45. void init();
  46. // basic constructor
  47. LLSkipList();
  48. // basic constructor including sorter
  49. LLSkipList(insert_func insert_first, equals_func equals);
  50. ~LLSkipList();
  51. inline void setInsertFirst(insert_func insert_first);
  52. inline void setEquals(equals_func equals);
  53. inline BOOL addData(const DATA_TYPE& data);
  54. inline BOOL checkData(const DATA_TYPE& data);
  55. // returns number of items in the list
  56. inline S32 getLength() const; // NOT a constant time operation, traverses entire list!
  57. inline BOOL moveData(const DATA_TYPE& data, LLSkipList *newlist);
  58. inline BOOL removeData(const DATA_TYPE& data);
  59. // remove all nodes from the list but do not delete data
  60. inline void removeAllNodes();
  61. // place mCurrentp on first node
  62. inline void resetList();
  63. // return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp
  64. inline DATA_TYPE getCurrentData();
  65. // same as getCurrentData() but a more intuitive name for the operation
  66. inline DATA_TYPE getNextData();
  67. // remove the Node at mCurentOperatingp
  68. // leave mCurrentp and mCurentOperatingp on the next entry
  69. inline void removeCurrentData();
  70. // reset the list and return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp
  71. inline DATA_TYPE getFirstData();
  72. class LLSkipNode
  73. {
  74. public:
  75. LLSkipNode()
  76. : mData(0)
  77. {
  78. S32 i;
  79. for (i = 0; i < BINARY_DEPTH; i++)
  80. {
  81. mForward[i] = NULL;
  82. }
  83. }
  84. LLSkipNode(DATA_TYPE data)
  85. : mData(data)
  86. {
  87. S32 i;
  88. for (i = 0; i < BINARY_DEPTH; i++)
  89. {
  90. mForward[i] = NULL;
  91. }
  92. }
  93. ~LLSkipNode()
  94. {
  95. }
  96. DATA_TYPE mData;
  97. LLSkipNode *mForward[BINARY_DEPTH];
  98. private:
  99. // Disallow copying of LLSkipNodes by not implementing these methods.
  100. LLSkipNode(const LLSkipNode &);
  101. LLSkipNode &operator=(const LLSkipNode &);
  102. };
  103. static BOOL defaultEquals(const DATA_TYPE& first, const DATA_TYPE& second)
  104. {
  105. return first == second;
  106. }
  107. private:
  108. LLSkipNode mHead;
  109. LLSkipNode *mUpdate[BINARY_DEPTH];
  110. LLSkipNode *mCurrentp;
  111. LLSkipNode *mCurrentOperatingp;
  112. S32 mLevel;
  113. insert_func mInsertFirst;
  114. equals_func mEquals;
  115. private:
  116. // Disallow copying of LLSkipNodes by not implementing these methods.
  117. LLSkipList(const LLSkipList &);
  118. LLSkipList &operator=(const LLSkipList &);
  119. };
  120. ///////////////////////
  121. //
  122. // Implementation
  123. //
  124. // Binary depth must be >= 2
  125. template <class DATA_TYPE, S32 BINARY_DEPTH>
  126. inline void LLSkipList<DATA_TYPE, BINARY_DEPTH>::init()
  127. {
  128. S32 i;
  129. for (i = 0; i < BINARY_DEPTH; i++)
  130. {
  131. mHead.mForward[i] = NULL;
  132. mUpdate[i] = NULL;
  133. }
  134. mLevel = 1;
  135. mCurrentp = *(mHead.mForward);
  136. mCurrentOperatingp = *(mHead.mForward);
  137. }
  138. // basic constructor
  139. template <class DATA_TYPE, S32 BINARY_DEPTH>
  140. inline LLSkipList<DATA_TYPE, BINARY_DEPTH>::LLSkipList()
  141. : mInsertFirst(NULL), 
  142. mEquals(defaultEquals)
  143. {
  144. init();
  145. }
  146. // basic constructor including sorter
  147. template <class DATA_TYPE, S32 BINARY_DEPTH>
  148. inline LLSkipList<DATA_TYPE, BINARY_DEPTH>::LLSkipList(insert_func insert,
  149.    equals_func equals)
  150. : mInsertFirst(insert), 
  151. mEquals(equals)
  152. {
  153. init();
  154. }
  155. template <class DATA_TYPE, S32 BINARY_DEPTH>
  156. inline LLSkipList<DATA_TYPE, BINARY_DEPTH>::~LLSkipList()
  157. {
  158. removeAllNodes();
  159. }
  160. template <class DATA_TYPE, S32 BINARY_DEPTH>
  161. inline void LLSkipList<DATA_TYPE, BINARY_DEPTH>::setInsertFirst(insert_func insert_first)
  162. {
  163. mInsertFirst = insert_first;
  164. }
  165. template <class DATA_TYPE, S32 BINARY_DEPTH>
  166. inline void LLSkipList<DATA_TYPE, BINARY_DEPTH>::setEquals(equals_func equals)
  167. {
  168. mEquals = equals;
  169. }
  170. template <class DATA_TYPE, S32 BINARY_DEPTH>
  171. inline BOOL LLSkipList<DATA_TYPE, BINARY_DEPTH>::addData(const DATA_TYPE& data)
  172. {
  173. S32 level;
  174. LLSkipNode *current = &mHead;
  175. LLSkipNode *temp;
  176. // find the pointer one in front of the one we want
  177. if (mInsertFirst)
  178. {
  179. for (level = mLevel - 1; level >= 0; level--)
  180. {
  181. temp = *(current->mForward + level);
  182. while (  (temp)
  183.    &&(mInsertFirst(temp->mData, data)))
  184. {
  185. current = temp;
  186. temp = *(current->mForward + level);
  187. }
  188. *(mUpdate + level) = current;
  189. }
  190. }
  191. else
  192. {
  193. for (level = mLevel - 1; level >= 0; level--)
  194. {
  195. temp = *(current->mForward + level);
  196. while (  (temp)
  197.    &&(temp->mData < data))
  198. {
  199. current = temp;
  200. temp = *(current->mForward + level);
  201. }
  202. *(mUpdate + level) = current;
  203. }
  204. }
  205. // we're now just in front of where we want to be . . . take one step forward
  206. current = *current->mForward;
  207. // now add the new node
  208. S32 newlevel;
  209. for (newlevel = 1; newlevel <= mLevel && newlevel < BINARY_DEPTH; newlevel++)
  210. {
  211. if (ll_frand() < 0.5f)
  212. break;
  213. }
  214. LLSkipNode *snode = new LLSkipNode(data);
  215. if (newlevel > mLevel)
  216. {
  217. mHead.mForward[mLevel] = NULL;
  218. mUpdate[mLevel] = &mHead;
  219. mLevel = newlevel;
  220. }
  221. for (level = 0; level < newlevel; level++)
  222. {
  223. snode->mForward[level] = mUpdate[level]->mForward[level];
  224. mUpdate[level]->mForward[level] = snode;
  225. }
  226. return TRUE;
  227. }
  228. template <class DATA_TYPE, S32 BINARY_DEPTH>
  229. inline BOOL LLSkipList<DATA_TYPE, BINARY_DEPTH>::checkData(const DATA_TYPE& data)
  230. {
  231. S32 level;
  232. LLSkipNode *current = &mHead;
  233. LLSkipNode *temp;
  234. // find the pointer one in front of the one we want
  235. if (mInsertFirst)
  236. {
  237. for (level = mLevel - 1; level >= 0; level--)
  238. {
  239. temp = *(current->mForward + level);
  240. while (  (temp)
  241.    &&(mInsertFirst(temp->mData, data)))
  242. {
  243. current = temp;
  244. temp = *(current->mForward + level);
  245. }
  246. *(mUpdate + level) = current;
  247. }
  248. }
  249. else
  250. {
  251. for (level = mLevel - 1; level >= 0; level--)
  252. {
  253. temp = *(current->mForward + level);
  254. while (  (temp)
  255.    &&(temp->mData < data))
  256. {
  257. current = temp;
  258. temp = *(current->mForward + level);
  259. }
  260. *(mUpdate + level) = current;
  261. }
  262. }
  263. // we're now just in front of where we want to be . . . take one step forward
  264. current = *current->mForward;
  265. if (current)
  266. {
  267. return mEquals(current->mData, data);
  268. }
  269. return FALSE;
  270. }
  271. // returns number of items in the list
  272. template <class DATA_TYPE, S32 BINARY_DEPTH>
  273. inline S32 LLSkipList<DATA_TYPE, BINARY_DEPTH>::getLength() const
  274. {
  275. U32 length = 0;
  276. for (LLSkipNode* temp = *(mHead.mForward); temp != NULL; temp = temp->mForward[0])
  277. {
  278. length++;
  279. }
  280. return length;
  281. }
  282. template <class DATA_TYPE, S32 BINARY_DEPTH>
  283. inline BOOL LLSkipList<DATA_TYPE, BINARY_DEPTH>::moveData(const DATA_TYPE& data, LLSkipList *newlist)
  284. {
  285. BOOL removed = removeData(data);
  286. BOOL added = newlist->addData(data);
  287. return removed && added;
  288. }
  289. template <class DATA_TYPE, S32 BINARY_DEPTH>
  290. inline BOOL LLSkipList<DATA_TYPE, BINARY_DEPTH>::removeData(const DATA_TYPE& data)
  291. {
  292. S32 level;
  293. LLSkipNode *current = &mHead;
  294. LLSkipNode *temp;
  295. // find the pointer one in front of the one we want
  296. if (mInsertFirst)
  297. {
  298. for (level = mLevel - 1; level >= 0; level--)
  299. {
  300. temp = *(current->mForward + level);
  301. while (  (temp)
  302.    &&(mInsertFirst(temp->mData, data)))
  303. {
  304. current = temp;
  305. temp = *(current->mForward + level);
  306. }
  307. *(mUpdate + level) = current;
  308. }
  309. }
  310. else
  311. {
  312. for (level = mLevel - 1; level >= 0; level--)
  313. {
  314. temp = *(current->mForward + level);
  315. while (  (temp)
  316.    &&(temp->mData < data))
  317. {
  318. current = temp;
  319. temp = *(current->mForward + level);
  320. }
  321. *(mUpdate + level) = current;
  322. }
  323. }
  324. // we're now just in front of where we want to be . . . take one step forward
  325. current = *current->mForward;
  326. if (!current)
  327. {
  328. // empty list or beyond the end!
  329. return FALSE;
  330. }
  331. // is this the one we want?
  332. if (!mEquals(current->mData, data))
  333. {
  334. // nope!
  335. return FALSE;
  336. }
  337. else
  338. {
  339. // do we need to fix current or currentop?
  340. if (current == mCurrentp)
  341. {
  342. mCurrentp = current->mForward[0];
  343. }
  344. if (current == mCurrentOperatingp)
  345. {
  346. mCurrentOperatingp = current->mForward[0];
  347. }
  348. // yes it is!  change pointers as required
  349. for (level = 0; level < mLevel; level++)
  350. {
  351. if (mUpdate[level]->mForward[level] != current)
  352. {
  353. // cool, we've fixed all the pointers!
  354. break;
  355. }
  356. mUpdate[level]->mForward[level] = current->mForward[level];
  357. }
  358. // clean up cuurent
  359. delete current;
  360. // clean up mHead
  361. while (  (mLevel > 1)
  362.    &&(!mHead.mForward[mLevel - 1]))
  363. {
  364. mLevel--;
  365. }
  366. }
  367. return TRUE;
  368. }
  369. // remove all nodes from the list but do not delete data
  370. template <class DATA_TYPE, S32 BINARY_DEPTH>
  371. inline void LLSkipList<DATA_TYPE, BINARY_DEPTH>::removeAllNodes()
  372. {
  373. LLSkipNode *temp;
  374. // reset mCurrentp
  375. mCurrentp = *(mHead.mForward);
  376. while (mCurrentp)
  377. {
  378. temp = mCurrentp->mForward[0];
  379. delete mCurrentp;
  380. mCurrentp = temp;
  381. }
  382. S32 i;
  383. for (i = 0; i < BINARY_DEPTH; i++)
  384. {
  385. mHead.mForward[i] = NULL;
  386. mUpdate[i] = NULL;
  387. }
  388. mCurrentp = *(mHead.mForward);
  389. mCurrentOperatingp = *(mHead.mForward);
  390. }
  391. // place mCurrentp on first node
  392. template <class DATA_TYPE, S32 BINARY_DEPTH>
  393. inline void LLSkipList<DATA_TYPE, BINARY_DEPTH>::resetList()
  394. {
  395. mCurrentp = *(mHead.mForward);
  396. mCurrentOperatingp = *(mHead.mForward);
  397. }
  398. // return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp
  399. template <class DATA_TYPE, S32 BINARY_DEPTH>
  400. inline DATA_TYPE LLSkipList<DATA_TYPE, BINARY_DEPTH>::getCurrentData()
  401. {
  402. if (mCurrentp)
  403. {
  404. mCurrentOperatingp = mCurrentp;
  405. mCurrentp = mCurrentp->mForward[0];
  406. return mCurrentOperatingp->mData;
  407. }
  408. else
  409. {
  410. //return NULL; // causes compile warning
  411. return (DATA_TYPE)0;  // equivalent, but no warning
  412. }
  413. }
  414. // same as getCurrentData() but a more intuitive name for the operation
  415. template <class DATA_TYPE, S32 BINARY_DEPTH>
  416. inline DATA_TYPE LLSkipList<DATA_TYPE, BINARY_DEPTH>::getNextData()
  417. {
  418. if (mCurrentp)
  419. {
  420. mCurrentOperatingp = mCurrentp;
  421. mCurrentp = mCurrentp->mForward[0];
  422. return mCurrentOperatingp->mData;
  423. }
  424. else
  425. {
  426. //return NULL; // causes compile warning
  427. return (DATA_TYPE)0;  // equivalent, but no warning
  428. }
  429. }
  430. // remove the Node at mCurentOperatingp
  431. // leave mCurrentp and mCurentOperatingp on the next entry
  432. template <class DATA_TYPE, S32 BINARY_DEPTH>
  433. inline void LLSkipList<DATA_TYPE, BINARY_DEPTH>::removeCurrentData()
  434. {
  435. if (mCurrentOperatingp)
  436. {
  437. removeData(mCurrentOperatingp->mData);
  438. }
  439. }
  440. // reset the list and return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp
  441. template <class DATA_TYPE, S32 BINARY_DEPTH>
  442. inline DATA_TYPE LLSkipList<DATA_TYPE, BINARY_DEPTH>::getFirstData()
  443. {
  444. mCurrentp = *(mHead.mForward);
  445. mCurrentOperatingp = *(mHead.mForward);
  446. if (mCurrentp)
  447. {
  448. mCurrentOperatingp = mCurrentp;
  449. mCurrentp = mCurrentp->mForward[0];
  450. return mCurrentOperatingp->mData;
  451. }
  452. else
  453. {
  454. //return NULL; // causes compile warning
  455. return (DATA_TYPE)0;  // equivalent, but no warning
  456. }
  457. }
  458. #endif