aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llcommon/llpriqueuemap.h
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/llcommon/llpriqueuemap.h')
-rw-r--r--linden/indra/llcommon/llpriqueuemap.h146
1 files changed, 146 insertions, 0 deletions
diff --git a/linden/indra/llcommon/llpriqueuemap.h b/linden/indra/llcommon/llpriqueuemap.h
new file mode 100644
index 0000000..20cbc6b
--- /dev/null
+++ b/linden/indra/llcommon/llpriqueuemap.h
@@ -0,0 +1,146 @@
1/**
2 * @file llpriqueuemap.h
3 * @brief Priority queue implementation
4 *
5 * Copyright (c) 2003-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27#ifndef LL_LLPRIQUEUEMAP_H
28#define LL_LLPRIQUEUEMAP_H
29
30#include <map>
31
32//
33// Priority queue, implemented under the hood as a
34// map. Needs to be done this way because none of the
35// standard STL containers provide a representation
36// where it's easy to reprioritize.
37//
38
39template <class DATA>
40class LLPQMKey
41{
42public:
43 LLPQMKey(const F32 priority, DATA data) : mPriority(priority), mData(data)
44 {
45 }
46
47 bool operator<(const LLPQMKey &b) const
48 {
49 if (mPriority > b.mPriority)
50 {
51 return TRUE;
52 }
53 if (mPriority < b.mPriority)
54 {
55 return FALSE;
56 }
57 if (mData > b.mData)
58 {
59 return TRUE;
60 }
61 return FALSE;
62 }
63
64 F32 mPriority;
65 DATA mData;
66};
67
68template <class DATA_TYPE>
69class LLPriQueueMap
70{
71public:
72 typedef typename std::map<LLPQMKey<DATA_TYPE>, DATA_TYPE>::iterator pqm_iter;
73 typedef std::pair<LLPQMKey<DATA_TYPE>, DATA_TYPE> pqm_pair;
74 typedef void (*set_pri_fn)(DATA_TYPE &data, const F32 priority);
75 typedef F32 (*get_pri_fn)(DATA_TYPE &data);
76
77
78 LLPriQueueMap(set_pri_fn set_pri, get_pri_fn get_pri) : mSetPriority(set_pri), mGetPriority(get_pri)
79 {
80 }
81
82 void push(const F32 priority, DATA_TYPE data)
83 {
84#ifdef _DEBUG
85 pqm_iter iter = mMap.find(LLPQMKey<DATA_TYPE>(priority, data));
86 if (iter != mMap.end())
87 {
88 llerrs << "Pushing already existing data onto queue!" << llendl;
89 }
90#endif
91 mMap.insert(pqm_pair(LLPQMKey<DATA_TYPE>(priority, data), data));
92 }
93
94 BOOL pop(DATA_TYPE *datap)
95 {
96 pqm_iter iter;
97 iter = mMap.begin();
98 if (iter == mMap.end())
99 {
100 return FALSE;
101 }
102 *datap = (*(iter)).second;
103 mMap.erase(iter);
104
105 return TRUE;
106 }
107
108 void reprioritize(const F32 new_priority, DATA_TYPE data)
109 {
110 pqm_iter iter;
111 F32 cur_priority = mGetPriority(data);
112 LLPQMKey<DATA_TYPE> cur_key(cur_priority, data);
113 iter = mMap.find(cur_key);
114 if (iter == mMap.end())
115 {
116 llwarns << "Data not on priority queue!" << llendl;
117 // OK, try iterating through all of the data and seeing if we just screwed up the priority
118 // somehow.
119 for (iter = mMap.begin(); iter != mMap.end(); iter++)
120 {
121 if ((*(iter)).second == data)
122 {
123 llerrs << "Data on priority queue but priority not matched!" << llendl;
124 }
125 }
126 return;
127 }
128
129 mMap.erase(iter);
130 mSetPriority(data, new_priority);
131 push(new_priority, data);
132 }
133
134 S32 getLength() const
135 {
136 return (S32)mMap.size();
137 }
138
139 // Hack: public for use by the transfer manager, ugh.
140 std::map<LLPQMKey<DATA_TYPE>, DATA_TYPE> mMap;
141protected:
142 void (*mSetPriority)(DATA_TYPE &data, const F32 priority);
143 F32 (*mGetPriority)(DATA_TYPE &data);
144};
145
146#endif // LL_LLPRIQUEUEMAP_H