aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llcommon/llindexedqueue.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--linden/indra/llcommon/llindexedqueue.h156
1 files changed, 156 insertions, 0 deletions
diff --git a/linden/indra/llcommon/llindexedqueue.h b/linden/indra/llcommon/llindexedqueue.h
new file mode 100644
index 0000000..040de84
--- /dev/null
+++ b/linden/indra/llcommon/llindexedqueue.h
@@ -0,0 +1,156 @@
1/**
2 * @file llindexedqueue.h
3 * @brief An indexed FIFO queue, where only one element with each key
4 * can be in the queue.
5 *
6 * Copyright (c) 2003-2007, Linden Research, Inc.
7 *
8 * The source code in this file ("Source Code") is provided by Linden Lab
9 * to you under the terms of the GNU General Public License, version 2.0
10 * ("GPL"), unless you have obtained a separate licensing agreement
11 * ("Other License"), formally executed by you and Linden Lab. Terms of
12 * the GPL can be found in doc/GPL-license.txt in this distribution, or
13 * online at http://secondlife.com/developers/opensource/gplv2
14 *
15 * There are special exceptions to the terms and conditions of the GPL as
16 * it is applied to this Source Code. View the full text of the exception
17 * in the file doc/FLOSS-exception.txt in this software distribution, or
18 * online at http://secondlife.com/developers/opensource/flossexception
19 *
20 * By copying, modifying or distributing this software, you acknowledge
21 * that you have read and understood your obligations described above,
22 * and agree to abide by those obligations.
23 *
24 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
25 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
26 * COMPLETENESS OR PERFORMANCE.
27 */
28
29#ifndef LL_LLINDEXEDQUEUE_H
30#define LL_LLINDEXEDQUEUE_H
31
32// An indexed FIFO queue, where only one element with each key can be in the queue.
33// This is ONLY used in the interest list, you'll probably want to review this code
34// carefully if you want to use it elsewhere - Doug
35
36template <typename Type>
37class LLIndexedQueue
38{
39protected:
40 typedef std::deque<Type> type_deque;
41 type_deque mQueue;
42 std::set<Type> mKeySet;
43
44public:
45 LLIndexedQueue() {}
46
47 // move_if_there is an O(n) operation
48 bool push_back(const Type &value, bool move_if_there = false)
49 {
50 if (mKeySet.find(value) != mKeySet.end())
51 {
52 // Already on the queue
53 if (move_if_there)
54 {
55 // Remove the existing entry.
56 typename type_deque::iterator it;
57 for (it = mQueue.begin(); it != mQueue.end(); ++it)
58 {
59 if (*it == value)
60 {
61 break;
62 }
63 }
64
65 // This HAS to succeed, otherwise there's a serious bug in the keyset implementation
66 // (although this isn't thread safe, at all)
67
68 mQueue.erase(it);
69 }
70 else
71 {
72 // We're not moving it, leave it alone
73 return false;
74 }
75 }
76 else
77 {
78 // Doesn't exist, add it to the key set
79 mKeySet.insert(value);
80 }
81
82 mQueue.push_back(value);
83
84 // We succeeded in adding the new element.
85 return true;
86 }
87
88 bool push_front(const Type &value, bool move_if_there = false)
89 {
90 if (mKeySet.find(value) != mKeySet.end())
91 {
92 // Already on the queue
93 if (move_if_there)
94 {
95 // Remove the existing entry.
96 typename type_deque::iterator it;
97 for (it = mQueue.begin(); it != mQueue.end(); ++it)
98 {
99 if (*it == value)
100 {
101 break;
102 }
103 }
104
105 // This HAS to succeed, otherwise there's a serious bug in the keyset implementation
106 // (although this isn't thread safe, at all)
107
108 mQueue.erase(it);
109 }
110 else
111 {
112 // We're not moving it, leave it alone
113 return false;
114 }
115 }
116 else
117 {
118 // Doesn't exist, add it to the key set
119 mKeySet.insert(value);
120 }
121
122 mQueue.push_front(value);
123 return true;
124 }
125
126 void pop()
127 {
128 Type value = mQueue.front();
129 mKeySet.erase(value);
130 mQueue.pop_front();
131 }
132
133 Type &front()
134 {
135 return mQueue.front();
136 }
137
138 S32 size() const
139 {
140 return mQueue.size();
141 }
142
143 bool empty() const
144 {
145 return mQueue.empty();
146 }
147
148 void clear()
149 {
150 // Clear out all elements on the queue
151 mQueue.clear();
152 mKeySet.clear();
153 }
154};
155
156#endif // LL_LLINDEXEDQUEUE_H