diff options
Diffstat (limited to 'linden/indra/llcommon/llmap.h')
-rw-r--r-- | linden/indra/llcommon/llmap.h | 250 |
1 files changed, 250 insertions, 0 deletions
diff --git a/linden/indra/llcommon/llmap.h b/linden/indra/llcommon/llmap.h new file mode 100644 index 0000000..2bda851 --- /dev/null +++ b/linden/indra/llcommon/llmap.h | |||
@@ -0,0 +1,250 @@ | |||
1 | /** | ||
2 | * @file llmap.h | ||
3 | * @brief LLMap class header file | ||
4 | * | ||
5 | * Copyright (c) 2001-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 | |||
28 | #ifndef LL_LLMAP_H | ||
29 | #define LL_LLMAP_H | ||
30 | |||
31 | #include <stdio.h> | ||
32 | #include <utility> | ||
33 | #include <map> | ||
34 | |||
35 | // llmap uses the fast stl library code in a manner consistant with LLSkipMap, et. al. | ||
36 | |||
37 | template<class INDEX_TYPE, class MAPPED_TYPE> class LLMap | ||
38 | { | ||
39 | private: | ||
40 | typedef typename std::map<INDEX_TYPE, MAPPED_TYPE> stl_map_t; | ||
41 | typedef typename stl_map_t::iterator stl_iter_t; | ||
42 | typedef typename stl_map_t::value_type stl_value_t; | ||
43 | |||
44 | stl_map_t mStlMap; | ||
45 | stl_iter_t mCurIter; // *iterator = pair<const INDEX_TYPE, MAPPED_TYPE> | ||
46 | MAPPED_TYPE dummy_data; | ||
47 | INDEX_TYPE dummy_index; | ||
48 | |||
49 | public: | ||
50 | LLMap() : mStlMap() | ||
51 | { | ||
52 | memset((void*)(&dummy_data), 0x0, sizeof(MAPPED_TYPE)); | ||
53 | memset((void*)(&dummy_index), 0x0, sizeof(INDEX_TYPE)); | ||
54 | mCurIter = mStlMap.begin(); | ||
55 | } | ||
56 | ~LLMap() | ||
57 | { | ||
58 | mStlMap.clear(); | ||
59 | } | ||
60 | |||
61 | // use these functions to itterate through a list | ||
62 | void resetMap() | ||
63 | { | ||
64 | mCurIter = mStlMap.begin(); | ||
65 | } | ||
66 | |||
67 | // get the current data and bump mCurrentp | ||
68 | // This is kind of screwy since it returns a reference; | ||
69 | // We have to have a dummy value for when we reach the end | ||
70 | // or in case we have an empty list. Presumably, this value | ||
71 | // will initialize to some NULL value that will end the iterator. | ||
72 | // We really shouldn't be using getNextData() or getNextKey() anyway... | ||
73 | MAPPED_TYPE &getNextData() | ||
74 | { | ||
75 | if (mCurIter == mStlMap.end()) | ||
76 | { | ||
77 | return dummy_data; | ||
78 | } | ||
79 | else | ||
80 | { | ||
81 | return (*mCurIter++).second; | ||
82 | } | ||
83 | } | ||
84 | |||
85 | const INDEX_TYPE &getNextKey() | ||
86 | { | ||
87 | if (mCurIter == mStlMap.end()) | ||
88 | { | ||
89 | return dummy_index; | ||
90 | } | ||
91 | else | ||
92 | { | ||
93 | return (*mCurIter++).first; | ||
94 | } | ||
95 | } | ||
96 | |||
97 | MAPPED_TYPE &getFirstData() | ||
98 | { | ||
99 | resetMap(); | ||
100 | return getNextData(); | ||
101 | } | ||
102 | |||
103 | const INDEX_TYPE &getFirstKey() | ||
104 | { | ||
105 | resetMap(); | ||
106 | return getNextKey(); | ||
107 | } | ||
108 | |||
109 | S32 getLength() | ||
110 | { | ||
111 | return mStlMap.size(); | ||
112 | } | ||
113 | |||
114 | void addData(const INDEX_TYPE &index, MAPPED_TYPE pointed_to) | ||
115 | { | ||
116 | mStlMap.insert(stl_value_t(index, pointed_to)); | ||
117 | } | ||
118 | |||
119 | void addData(const INDEX_TYPE &index) | ||
120 | { | ||
121 | mStlMap.insert(stl_value_t(index, dummy_data)); | ||
122 | } | ||
123 | |||
124 | // if index doesn't exist, then insert a new node and return it | ||
125 | MAPPED_TYPE &getData(const INDEX_TYPE &index) | ||
126 | { | ||
127 | std::pair<stl_iter_t, bool> res; | ||
128 | res = mStlMap.insert(stl_value_t(index, dummy_data)); | ||
129 | return res.first->second; | ||
130 | } | ||
131 | |||
132 | // if index doesn't exist, then insert a new node, return it, and set b_new_entry to true | ||
133 | MAPPED_TYPE &getData(const INDEX_TYPE &index, BOOL &b_new_entry) | ||
134 | { | ||
135 | std::pair<stl_iter_t, bool> res; | ||
136 | res = mStlMap.insert(stl_value_t(index, dummy_data)); | ||
137 | b_new_entry = res.second; | ||
138 | return res.first->second; | ||
139 | } | ||
140 | |||
141 | // If there, returns the data. | ||
142 | // If not, returns NULL. | ||
143 | // Never adds entries to the map. | ||
144 | MAPPED_TYPE getIfThere(const INDEX_TYPE &index) | ||
145 | { | ||
146 | stl_iter_t iter; | ||
147 | iter = mStlMap.find(index); | ||
148 | if (iter == mStlMap.end()) | ||
149 | { | ||
150 | return (MAPPED_TYPE)0; | ||
151 | } | ||
152 | else | ||
153 | { | ||
154 | return (*iter).second; | ||
155 | } | ||
156 | } | ||
157 | |||
158 | |||
159 | // if index doesn't exist, then make a new node and return it | ||
160 | MAPPED_TYPE &operator[](const INDEX_TYPE &index) | ||
161 | { | ||
162 | return getData(index); | ||
163 | } | ||
164 | |||
165 | // do a reverse look-up, return NULL if failed | ||
166 | INDEX_TYPE reverseLookup(const MAPPED_TYPE data) | ||
167 | { | ||
168 | stl_iter_t iter; | ||
169 | stl_iter_t end_iter; | ||
170 | iter = mStlMap.begin(); | ||
171 | end_iter = mStlMap.end(); | ||
172 | while (iter != end_iter) | ||
173 | { | ||
174 | if ((*iter).second == data) | ||
175 | return (*iter).first; | ||
176 | iter++; | ||
177 | } | ||
178 | return (INDEX_TYPE)0; | ||
179 | } | ||
180 | |||
181 | BOOL removeData(const INDEX_TYPE &index) | ||
182 | { | ||
183 | mCurIter = mStlMap.find(index); | ||
184 | if (mCurIter == mStlMap.end()) | ||
185 | { | ||
186 | return FALSE; | ||
187 | } | ||
188 | else | ||
189 | { | ||
190 | stl_iter_t iter = mCurIter++; // incrament mCurIter to the next element | ||
191 | mStlMap.erase(iter); | ||
192 | return TRUE; | ||
193 | } | ||
194 | } | ||
195 | |||
196 | // does this index exist? | ||
197 | BOOL checkData(const INDEX_TYPE &index) | ||
198 | { | ||
199 | stl_iter_t iter; | ||
200 | iter = mStlMap.find(index); | ||
201 | if (iter == mStlMap.end()) | ||
202 | { | ||
203 | return FALSE; | ||
204 | } | ||
205 | else | ||
206 | { | ||
207 | mCurIter = iter; | ||
208 | return TRUE; | ||
209 | } | ||
210 | } | ||
211 | |||
212 | BOOL deleteData(const INDEX_TYPE &index) | ||
213 | { | ||
214 | mCurIter = mStlMap.find(index); | ||
215 | if (mCurIter == mStlMap.end()) | ||
216 | { | ||
217 | return FALSE; | ||
218 | } | ||
219 | else | ||
220 | { | ||
221 | stl_iter_t iter = mCurIter++; // incrament mCurIter to the next element | ||
222 | delete (*iter).second; | ||
223 | mStlMap.erase(iter); | ||
224 | return TRUE; | ||
225 | } | ||
226 | } | ||
227 | |||
228 | void deleteAllData() | ||
229 | { | ||
230 | stl_iter_t iter; | ||
231 | stl_iter_t end_iter; | ||
232 | iter = mStlMap.begin(); | ||
233 | end_iter = mStlMap.end(); | ||
234 | while (iter != end_iter) | ||
235 | { | ||
236 | delete (*iter).second; | ||
237 | iter++; | ||
238 | } | ||
239 | mStlMap.clear(); | ||
240 | mCurIter = mStlMap.end(); | ||
241 | } | ||
242 | |||
243 | void removeAllData() | ||
244 | { | ||
245 | mStlMap.clear(); | ||
246 | } | ||
247 | }; | ||
248 | |||
249 | |||
250 | #endif | ||