PageRenderTime 33ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/llcommon/lllinkedqueue.h

https://bitbucket.org/lindenlab/viewer-beta/
C++ Header | 309 lines | 188 code | 61 blank | 60 comment | 15 complexity | e14e272453f7640390fe89e6fc97435f MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file lllinkedqueue.h
  3. * @brief Declaration of linked queue classes.
  4. *
  5. * $LicenseInfo:firstyear=2003&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #ifndef LL_LLLINKEDQUEUE_H
  27. #define LL_LLLINKEDQUEUE_H
  28. #include "llerror.h"
  29. // node that actually contains the data
  30. template <class DATA_TYPE> class LLLinkedQueueNode
  31. {
  32. public:
  33. DATA_TYPE mData;
  34. LLLinkedQueueNode *mNextp;
  35. LLLinkedQueueNode *mPrevp;
  36. public:
  37. LLLinkedQueueNode();
  38. LLLinkedQueueNode(const DATA_TYPE data);
  39. // destructor does not, by default, destroy associated data
  40. // however, the mDatap must be NULL to ensure that we aren't causing memory leaks
  41. ~LLLinkedQueueNode();
  42. };
  43. template <class DATA_TYPE> class LLLinkedQueue
  44. {
  45. public:
  46. LLLinkedQueue();
  47. // destructor destroys list and nodes, but not data in nodes
  48. ~LLLinkedQueue();
  49. // Puts at end of FIFO
  50. void push(const DATA_TYPE data);
  51. // Takes off front of FIFO
  52. BOOL pop(DATA_TYPE &data);
  53. BOOL peek(DATA_TYPE &data);
  54. void reset();
  55. S32 getLength() const;
  56. BOOL isEmpty() const;
  57. BOOL remove(const DATA_TYPE data);
  58. BOOL checkData(const DATA_TYPE data) const;
  59. private:
  60. // add node to end of list
  61. // set mCurrentp to mQueuep
  62. void addNodeAtEnd(LLLinkedQueueNode<DATA_TYPE> *nodep);
  63. private:
  64. LLLinkedQueueNode<DATA_TYPE> mHead; // head node
  65. LLLinkedQueueNode<DATA_TYPE> mTail; // tail node
  66. S32 mLength;
  67. };
  68. //
  69. // Nodes
  70. //
  71. template <class DATA_TYPE>
  72. LLLinkedQueueNode<DATA_TYPE>::LLLinkedQueueNode() :
  73. mData(), mNextp(NULL), mPrevp(NULL)
  74. { }
  75. template <class DATA_TYPE>
  76. LLLinkedQueueNode<DATA_TYPE>::LLLinkedQueueNode(const DATA_TYPE data) :
  77. mData(data), mNextp(NULL), mPrevp(NULL)
  78. { }
  79. template <class DATA_TYPE>
  80. LLLinkedQueueNode<DATA_TYPE>::~LLLinkedQueueNode()
  81. { }
  82. //
  83. // Queue itself
  84. //
  85. template <class DATA_TYPE>
  86. LLLinkedQueue<DATA_TYPE>::LLLinkedQueue()
  87. : mHead(),
  88. mTail(),
  89. mLength(0)
  90. { }
  91. // destructor destroys list and nodes, but not data in nodes
  92. template <class DATA_TYPE>
  93. LLLinkedQueue<DATA_TYPE>::~LLLinkedQueue()
  94. {
  95. reset();
  96. }
  97. // put data into a node and stick it at the end of the list
  98. template <class DATA_TYPE>
  99. void LLLinkedQueue<DATA_TYPE>::push(const DATA_TYPE data)
  100. {
  101. // make the new node
  102. LLLinkedQueueNode<DATA_TYPE> *nodep = new LLLinkedQueueNode<DATA_TYPE>(data);
  103. addNodeAtEnd(nodep);
  104. }
  105. // search the list starting at mHead.mNextp and remove the link with mDatap == data
  106. // set mCurrentp to mQueuep, or NULL if mQueuep points to node with mDatap == data
  107. // return TRUE if found, FALSE if not found
  108. template <class DATA_TYPE>
  109. BOOL LLLinkedQueue<DATA_TYPE>::remove(const DATA_TYPE data)
  110. {
  111. BOOL b_found = FALSE;
  112. LLLinkedQueueNode<DATA_TYPE> *currentp = mHead.mNextp;
  113. while (currentp)
  114. {
  115. if (currentp->mData == data)
  116. {
  117. b_found = TRUE;
  118. // if there is a next one, fix it
  119. if (currentp->mNextp)
  120. {
  121. currentp->mNextp->mPrevp = currentp->mPrevp;
  122. }
  123. else // we are at end of list
  124. {
  125. mTail.mPrevp = currentp->mPrevp;
  126. }
  127. // if there is a previous one, fix it
  128. if (currentp->mPrevp)
  129. {
  130. currentp->mPrevp->mNextp = currentp->mNextp;
  131. }
  132. else // we are at beginning of list
  133. {
  134. mHead.mNextp = currentp->mNextp;
  135. }
  136. // remove the node
  137. delete currentp;
  138. mLength--;
  139. break;
  140. }
  141. currentp = currentp->mNextp;
  142. }
  143. return b_found;
  144. }
  145. // remove all nodes from the list but do not delete associated data
  146. template <class DATA_TYPE>
  147. void LLLinkedQueue<DATA_TYPE>::reset()
  148. {
  149. LLLinkedQueueNode<DATA_TYPE> *currentp;
  150. LLLinkedQueueNode<DATA_TYPE> *nextp;
  151. currentp = mHead.mNextp;
  152. while (currentp)
  153. {
  154. nextp = currentp->mNextp;
  155. delete currentp;
  156. currentp = nextp;
  157. }
  158. // reset mHead and mCurrentp
  159. mHead.mNextp = NULL;
  160. mTail.mPrevp = NULL;
  161. mLength = 0;
  162. }
  163. template <class DATA_TYPE>
  164. S32 LLLinkedQueue<DATA_TYPE>::getLength() const
  165. {
  166. return mLength;
  167. }
  168. template <class DATA_TYPE>
  169. BOOL LLLinkedQueue<DATA_TYPE>::isEmpty() const
  170. {
  171. return mLength <= 0;
  172. }
  173. // check to see if data is in list
  174. // set mCurrentp and mQueuep to the target of search if found, otherwise set mCurrentp to mQueuep
  175. // return TRUE if found, FALSE if not found
  176. template <class DATA_TYPE>
  177. BOOL LLLinkedQueue<DATA_TYPE>::checkData(const DATA_TYPE data) const
  178. {
  179. LLLinkedQueueNode<DATA_TYPE> *currentp = mHead.mNextp;
  180. while (currentp)
  181. {
  182. if (currentp->mData == data)
  183. {
  184. return TRUE;
  185. }
  186. currentp = currentp->mNextp;
  187. }
  188. return FALSE;
  189. }
  190. template <class DATA_TYPE>
  191. BOOL LLLinkedQueue<DATA_TYPE>::pop(DATA_TYPE &data)
  192. {
  193. LLLinkedQueueNode<DATA_TYPE> *currentp;
  194. currentp = mHead.mNextp;
  195. if (!currentp)
  196. {
  197. return FALSE;
  198. }
  199. mHead.mNextp = currentp->mNextp;
  200. if (currentp->mNextp)
  201. {
  202. currentp->mNextp->mPrevp = currentp->mPrevp;
  203. }
  204. else
  205. {
  206. mTail.mPrevp = currentp->mPrevp;
  207. }
  208. data = currentp->mData;
  209. delete currentp;
  210. mLength--;
  211. return TRUE;
  212. }
  213. template <class DATA_TYPE>
  214. BOOL LLLinkedQueue<DATA_TYPE>::peek(DATA_TYPE &data)
  215. {
  216. LLLinkedQueueNode<DATA_TYPE> *currentp;
  217. currentp = mHead.mNextp;
  218. if (!currentp)
  219. {
  220. return FALSE;
  221. }
  222. data = currentp->mData;
  223. return TRUE;
  224. }
  225. //////////////////////////////////////////////////////////////////////////////////////////
  226. // private members
  227. //////////////////////////////////////////////////////////////////////////////////////////
  228. // add node to end of list
  229. // set mCurrentp to mQueuep
  230. template <class DATA_TYPE>
  231. void LLLinkedQueue<DATA_TYPE>::addNodeAtEnd(LLLinkedQueueNode<DATA_TYPE> *nodep)
  232. {
  233. // add the node to the end of the list
  234. nodep->mNextp = NULL;
  235. nodep->mPrevp = mTail.mPrevp;
  236. mTail.mPrevp = nodep;
  237. // if there's something in the list, fix its back pointer
  238. if (nodep->mPrevp)
  239. {
  240. nodep->mPrevp->mNextp = nodep;
  241. }
  242. else // otherwise fix the head node
  243. {
  244. mHead.mNextp = nodep;
  245. }
  246. mLength++;
  247. }
  248. #endif