AMXX-BG.INFO celltravtrie.inc Raw include

celltravtrie.inc

Original include source with line numbers.

Back Download .inc
1 #if defined _cell_travtrie_included
2 #endinput
3 #endif
4 #define _cell_travtrie_included
5
6 #include <cellarray>
7 #include <celltrie>
8
9 enum TravTrie
10 {
11 Invalid_TravTrie = 0
12 }
13
14 #define TRAVTRIE_MAX_KEY_LEN 1024
15
16 stock g_Key[TRAVTRIE_MAX_KEY_LEN]
17 stock g_Value[TRAVTRIE_MAX_KEY_LEN]
18
19 stock TravTrie:TravTrieCreate(keylength = 64, startsize = 32)
20 {
21 new Trie:tmp = TrieCreate();
22 TrieSetCell(tmp, "", _:ArrayCreate(keylength, startsize));
23 return TravTrie:tmp;
24 }
25
26 stock TravTrieDestroy(&TravTrie:trie)
27 {
28 new Array:iter;
29 if(!TrieGetCell(Trie:trie,"",any:iter)) { TrieDestroy(Trie:trie); return; }
30
31 ArrayDestroy(iter);
32 TrieDestroy(Trie:trie);
33 }
34
35 stock bool:TravTrieSetCell(TravTrie:trie, const key[], any:value)
36 {
37 if(key[0] == '^n') return false;
38
39 new any:val;
40 if(!TravTrieGetCell(trie, key, val) )
41 {
42 new Array:iter;
43 if(!TrieGetCell(Trie:trie,"",any:iter)) return false;
44
45 ArrayPushString(Array:iter,key);
46 }
47 if(key[0] == '^n') return false;
48
49 TrieSetCell(Trie:trie,key,value);
50 return true;
51 }
52
53 stock bool:TravTrieSetArray(TravTrie:trie, const key[], const array[], num_items)
54 {
55 if(key[0] == '^n') return false;
56
57 new val[2];
58 // string/array duality - bad idea but there's a bug
59 if(!TravTrieGetArray(trie, key, val,sizeof(val)) )
60 {
61 new Array:iter;
62 if(!TrieGetCell(Trie:trie,"",any:iter)) return false;
63
64 ArrayPushArray(iter,key);
65 }
66
67 if(key[0] == '^n') return false;
68
69 TrieSetArray(Trie:trie,key,array,num_items);
70 return true;
71 }
72
73 stock bool:TravTrieSetString(TravTrie:trie, const key[], const value[])
74 {
75 if(key[0] == '^n') return false;
76
77 new val[4];
78 if(!TravTrieGetString(trie, key, val,sizeof(val)) )
79 {
80 new Array:iter;
81 if(!TrieGetCell(Trie:trie,"",any:iter)) return false;
82
83 ArrayPushString(iter,key);
84 }
85
86 if(key[0] == '^n') return false;
87
88 TrieSetString(Trie:trie,key,value);
89 return true;
90 }
91
92 stock bool:TravTrieGetCell(TravTrie:trie, const key[], &any:value)
93 {
94 return (key[0] == '^n') ? false : TrieGetCell(Trie:trie,key,value);
95 }
96
97 stock bool:TravTrieKeyExists(TravTrie:trie, const key[])
98 {
99 return (key[0] == '^n') ? false : TrieKeyExists(Trie:trie,key);
100 }
101
102 stock bool:TravTrieGetArray(TravTrie:trie, const key[], any:array[], num_items)
103 {
104 return (key[0] == '^n') ? false : TrieGetArray(Trie:trie,key,array,num_items);
105 }
106
107 stock bool:TravTrieGetString(TravTrie:trie, const key[], value[], max_size)
108 {
109 return (key[0] == '^n') ? false : TrieGetString(Trie:trie,key,value,max_size);
110 }
111
112 stock bool:TravTrieDeleteKey(TravTrie:trie, const key[])
113 {
114 if(key[0] != '^n' && TrieDeleteKey(Trie:trie,key) )
115 {
116 new Array:iter;
117 if(!TrieGetCell(Trie:trie,"",any:iter)) return false;
118
119 static tmp[TRAVTRIE_MAX_KEY_LEN];
120 new index = 0;
121
122 while(index < ArraySize(iter) )
123 {
124 ArrayGetString(iter, index, tmp, TRAVTRIE_MAX_KEY_LEN - 1);
125 if(equal(tmp,key)) return (ArrayDeleteItem(iter, index) == 1);
126 index++;
127 }
128 }
129 return false;
130 }
131
132 stock TravTrieClear(TravTrie:trie)
133 {
134 new Array:iter;
135 if(!TrieGetCell(Trie:trie,"",any:iter)) { TrieClear(Trie:trie); return; }
136
137 ArrayClear(iter);
138 TrieClear(Trie:trie);
139 }
140
141 //stock TravTrieSize(TravTrie:trie) return TrieGetSize(trie) - 1;
142
143 // Rukia: Use this to prepare the TravTrie for SORTED traversal
144 // If you do not use this, it will be traversed in FIFO order
145 stock bool:PrepareTravTrie(TravTrie:trie)
146 {
147 new Array:iter;
148 if(!TrieGetCell(Trie:trie,"",any:iter)) { TrieClear(Trie:trie); return; }
149
150 ArraySort(iter, "SortADTArrayDesc");
151 }
152
153 public SortADTArrayDesc(Array:array, item1, item2, const data[], data_size)
154 {
155 static item1str[TRAVTRIE_MAX_KEY_LEN], item2str[TRAVTRIE_MAX_KEY_LEN]
156 ArrayGetString(array,item1,item1str,TRAVTRIE_MAX_KEY_LEN - 1);
157 ArrayGetString(array,item2,item2str,TRAVTRIE_MAX_KEY_LEN - 1);
158
159 return strcmp( item1str,item2str );
160 }
161
162 // Rukia: Get a mutable iterator to the travtrie
163 // This Handle MUST be closed using CloseHandle, and delete/insert will invalidate iterator
164 stock travTrieIter:GetTravTrieIterator(TravTrie:trie)
165 {
166 new Array:dp = ArrayCreate();
167 ArrayPushCell(dp,_:trie);
168 ArrayPushCell(dp,0);
169 return travTrieIter:dp;
170 }
171
172 // Rukia: Read the string key that the iterator points to.
173 // WILL NOT INCREMENT ITERATOR
174 stock bool:ReadTravTrieKey(travTrieIter:dp,key[],len)
175 {
176 new Trie:trie = Trie:ArrayGetCell(Array:dp,0);
177
178 new Array:iter;
179 if(!TrieGetCell(trie,"",_:iter)) return false;
180
181 new index = ArrayGetCell(Array:dp,1);
182 ArrayGetString(iter,index,key,len);
183
184 return true;
185 }
186
187 stock TravTrieSize(TravTrie:trie)
188 {
189 new Array:iter;
190 if(!TravTrieGetCell(trie,"",_:iter)) return false;
191
192 return ArraySize(iter);
193 }
194
195 // Rukia: These functions read from the travtrie via the iterator
196 // They WILL INCREMENT THE ITERATOR
197
198 stock bool:ReadTravTrieCell(travTrieIter:dp,&any:value)
199 {
200 static tmp[TRAVTRIE_MAX_KEY_LEN];
201 new TravTrie:trie = TravTrieIteratorHandler(Array:dp,tmp,TRAVTRIE_MAX_KEY_LEN - 1);
202
203 return TravTrieGetCell(trie,tmp,value);
204 }
205
206 stock bool:ReadTravTrieArray(travTrieIter:dp, value[], max_num)
207 {
208 static tmp[TRAVTRIE_MAX_KEY_LEN];
209 new TravTrie:trie = TravTrieIteratorHandler(Array:dp,tmp,TRAVTRIE_MAX_KEY_LEN - 1);
210
211 return TravTrieGetArray(trie,tmp,value,max_num);
212 }
213
214 stock bool:ReadTravTrieString(travTrieIter:dp, value[], max_num)
215 {
216 static tmp[TRAVTRIE_MAX_KEY_LEN];
217 new TravTrie:trie = TravTrieIteratorHandler(Array:dp,tmp,TRAVTRIE_MAX_KEY_LEN - 1);
218
219 return TravTrieGetString(trie,tmp,value,max_num);
220 }
221
222 stock TravTrie:TravTrieIteratorHandler(Array:dp,pos[],len)
223 {
224 new Trie:trie = Trie:ArrayGetCell(dp,0);
225
226 new Array:iter;
227 if(!TrieGetCell(trie,"",any:iter)) return TravTrie:Invalid_Trie;
228
229 new index = ArrayGetCell(dp,1);
230 ArrayGetString(iter,index,pos,len);
231
232 ArraySetCell(dp,1,index + 1);
233
234 return TravTrie:trie;
235 }
236
237 // Rukia: Returns true if there is more to read from the iterator
238
239 stock bool:MoreTravTrie(travTrieIter:dp)
240 {
241 new Trie:trie = Trie:ArrayGetCell(Array:dp,0);
242
243 new Array:iter;
244 if(!TrieGetCell(trie,"",any:iter)) return false;
245
246 new index = _:ArrayGetCell(Array:dp,1);
247 if(ArraySize(iter) <= index) return false;
248
249 return true;
250 }
251
252 stock DestroyTravTrieIterator(&travTrieIter:dp)
253 {
254 return ArrayDestroy(Array:dp);
255 }
256
257 stock bool:TravTrieDeleteKeyEx(TravTrie:trie, key)
258 {
259 formatex(g_Key,TRAVTRIE_MAX_KEY_LEN - 1,"%d",key);
260
261 return TravTrieDeleteKey(trie,g_Key);
262 }
263
264 //stock TravTrieSize(TravTrie:trie) return TrieGetSize(trie) - 1;
265
266 // Hawk: Gets the nth key, starting at 0
267
268 stock bool:TravTrieNth(TravTrie:trie, nth, key[], len)
269 {
270 new Array:iter;
271 PrepareTravTrie(trie);
272 if(!TravTrieGetCell(trie,"",iter)) return false;
273
274 new value[TRAVTRIE_MAX_KEY_LEN], result = ArrayGetString(iter,nth,value,TRAVTRIE_MAX_KEY_LEN - 1);
275 copy(key,len,value);
276
277 return bool:result;
278 }
279
280 stock bool:TravTrieNthEx(TravTrie:trie,nth,&key)
281 {
282 new bool:result = TravTrieNth(trie,nth,g_Key,TRAVTRIE_MAX_KEY_LEN - 1);
283 key = str_to_num(g_Key);
284
285 return result;
286 }
287
288 // Hawk: Extended functions for passing an integer as a key
289
290 stock bool:TravTrieGetCellEx(TravTrie:trie, key, &any:value)
291 {
292 formatex(g_Key,TRAVTRIE_MAX_KEY_LEN - 1,"%d",key);
293 new tempvalue, bool:result = TravTrieGetCell(trie,g_Key,tempvalue);
294 value = tempvalue;
295 return result;
296 }
297
298 stock bool:TravTrieGetStringEx(TravTrie:trie, key, value[], len)
299 {
300 formatex(g_Key,TRAVTRIE_MAX_KEY_LEN - 1,"%d",key);
301 new bool:result = TravTrieGetString(trie,g_Key,g_Value,TRAVTRIE_MAX_KEY_LEN - 1);
302 copy(value,abs(min(len,TRAVTRIE_MAX_KEY_LEN - 1)),g_Value);
303
304 return result;
305 }
306
307 stock bool:TravTrieGetArrayEx(TravTrie:trie, key, any:value[], len)
308 {
309 formatex(g_Key,TRAVTRIE_MAX_KEY_LEN - 1,"%d",key);
310 new result = TravTrieGetArray(trie,g_Key,g_Value,abs(min(TRAVTRIE_MAX_KEY_LEN,len)));
311 for(new count; count < len; count++)
312 value[count] = g_Value[count];
313
314 return result;
315 }
316
317 stock bool:TravTrieSetCellEx(TravTrie:trie, key, any:value)
318 {
319 formatex(g_Key,TRAVTRIE_MAX_KEY_LEN - 1,"%d",key);
320 return TravTrieSetCell(trie,g_Key,value);
321 }
322
323 stock bool:TravTrieSetStringEx(TravTrie:trie, key, const value[])
324 {
325 formatex(g_Key,TRAVTRIE_MAX_KEY_LEN - 1,"%d",key);
326 return TravTrieSetString(trie,g_Key,value);
327 }
328
329 stock bool:TravTrieSetArrayEx(TravTrie:trie, key, any:value[], len)
330 {
331 formatex(g_Key,TRAVTRIE_MAX_KEY_LEN - 1,"%d",key);
332 return TravTrieSetArray(trie,g_Key,value,len);
333 }
334
335 /*
336 #define TravTrieSetCellEx(%1,%2,%3) format(g_Key,TRAVTRIE_MAX_KEY_LEN - 1,"%d",%2); TravTrieSetCell(%1,g_Key,%3);
337 #define TravTrieSetArrayEx(%1,%2,%3,%4) format(g_Key,TRAVTRIE_MAX_KEY_LEN - 1,"%d",%2); TravTrieSetArray(%1,g_Key,%3,%4);
338 #define TravTrieSetStringEx(%1,%2,%3) format(g_Key,TRAVTRIE_MAX_KEY_LEN - 1,"%d",%2); TravTrieSetString(%1,g_Key,%3);
339 #define TravTrieGetCellEx(%1,%2,%3) format(g_Key,TRAVTRIE_MAX_KEY_LEN - 1,"%d",%2); TravTrieGetCell(%1,g_Key,%3);
340 #define TravTrieGetArrayEx(%1,%2,%3,%4) format(g_Key,TRAVTRIE_MAX_KEY_LEN - 1,"%d",%2); TravTrieGetArray(%1,g_Key,%3,%4);
341 #define TravTrieGetStringEx(%1,%2,%3,%4) format(g_Key,TRAVTRIE_MAX_KEY_LEN - 1,"%d",%2); TravTrieGetString(%1,g_Key,%3,%4);
342 */
343
344 stock bool:ReadTravTrieKeyEx(travTrieIter:dp,&key)
345 {
346 new bool:result = ReadTravTrieKey(dp,g_Key,TRAVTRIE_MAX_KEY_LEN - 1);
347 key = str_to_num(g_Key);
348
349 return result;
350 }
351