AMXX-BG.INFO hashx.inc Raw include

hashx.inc

Original include source with line numbers.

Back Download .inc
1 /*
2 Trie (HashX) abstraction layer
3 by Zefir<[email protected]>
4 developed for Cerberus project
5 http://cerberus.cstrike.in.ua/
6 5 december 2009 (c) Zefir
7
8 HashXKeyType return
9 HASH_X_TYPE_STRING for string
10 HASH_X_TYPE_CELL for cell
11 other value > 0 is size of array
12
13
14 'L' - array of keys for enumerate and traverse
15 'S' - position keys in array 'L'
16 'T' - type of cell
17 */
18
19 #if defined _hashX_included
20 #endinput
21 #endif
22 #define _hashX_included
23
24 #include <hash>
25
26 // Size of key in hash
27 #define HASH_KEY_SIZE 64
28
29 // Types of item
30 // if Type >= HASH_X_TYPE_ARRAY, item ined Array with this size
31 #define HASH_X_TYPE_NONE -3
32 #define HASH_X_TYPE_STRING -2
33 #define HASH_X_TYPE_CELL -1
34 #define HASH_X_TYPE_ARRAY 0
35
36
37 #define HashX Hash
38 #define HashXCreate() HashCreate()
39
40 #define HashXKeyExists(%1,%2) HashKeyExists(%1, %2)
41
42
43 #define HashXGetCell(%1,%2,%3) HashGetCell(%1, %2, %3)
44 #define HashXGetString(%1,%2,%3) HashGetString(%1, %2, %3)
45 #define HashXGetArray(%1,%2,%3,%4) HashGetArray(%1, %2, %3, %4)
46
47 stock HashXClear(HashX:handle) {
48 new Array:arr, Trie:hash, Trie:types;
49 if(HashGetCell(handle, {10, 30, 'L', 0}, arr) && arr)
50 ArrayClear(arr);
51 if(HashGetCell(handle, {10, 30, 'S', 0}, hash) && hash)
52 TrieClear(hash);
53 if(HashGetCell(handle, {10, 30, 'T', 0}, types) && types)
54 TrieClear(types);
55 new rtv = HashClear(handle);
56 HashSetCell(handle, {10, 30, 'L', 0}, arr);
57 HashSetCell(handle, {10, 30, 'S', 0}, hash);
58 HashSetCell(handle, {10, 30, 'T', 0}, types);
59 return rtv;
60 }
61
62 stock HashXDestroy(&HashX:handle) {
63 new Array:arr, Trie:hash;
64 if(HashGetCell(handle, {10, 30, 'L', 0}, arr))
65 ArrayDestroy(arr);
66 if(HashGetCell(handle, {10, 30, 'S', 0}, hash))
67 TrieDestroy(hash);
68 if(HashGetCell(handle, {10, 30, 'T', 0}, hash))
69 TrieDestroy(hash);
70
71 return HashDestroy(handle);
72 }
73
74 stock bool:HashXDeleteKey(HashX:handle, const key[]) {
75
76 new Array:arr, Trie:hash, pos;
77 if(HashGetCell(handle, {10, 30, 'S', 0}, hash)
78 && HashGetCell(handle, {10, 30, 'L', 0}, arr)
79 && TrieGetCell(hash, key, pos))
80 {
81 ArrayDeleteItem(arr, pos);
82 TrieDeleteKey(hash, key);
83
84 new key[HASH_KEY_SIZE], size = ArraySize(arr);
85 for(new i = pos; i < size; i++) {
86 ArrayGetString(arr, i, key, charsmax(key));
87 TrieSetCell(hash, key, i);
88 }
89 }
90 if(HashGetCell(handle, {10, 30, 'T', 0}, hash))
91 TrieDeleteKey(hash, key);
92
93 return HashDeleteKey(handle, key);
94 }
95
96 stock __HashXSetKey(HashX:handle, const key[], type) {
97 new Array:arr, Trie:hash, Trie:types, pos;
98 if (!HashGetCell(handle, {10, 30, 'S', 0}, hash)) {
99 hash = TrieCreate();
100 HashSetCell(handle, {10, 30, 'S', 0}, hash);
101 }
102
103 if (!HashGetCell(handle, {10, 30, 'T', 0}, types)) {
104 types = TrieCreate();
105 HashSetCell(handle, {10, 30, 'T', 0}, types);
106 }
107
108 if (!HashGetCell(handle, {10, 30, 'L', 0}, arr)) {
109 arr = ArrayCreate(HASH_KEY_SIZE);
110 HashSetCell(handle, {10, 30, 'L', 0}, arr);
111 }
112
113
114 TrieSetCell(types, key, type);
115 if (!TrieKeyExists(hash, key)) {
116 TrieSetCell(hash, key, ArraySize(arr));
117 ArrayPushString(arr, key);
118 } else {
119 TrieGetCell(hash, key, pos);
120 ArraySetString(arr, pos, key);
121 }
122
123 }
124
125 stock HashXSetCell(HashX:handle, const key[], any:value) {
126 __HashXSetKey(handle, key, HASH_X_TYPE_CELL);
127 return HashSetCell(handle, key, value);
128 }
129
130 stock HashXSetString(HashX:handle, const key[], const value[]) {
131 __HashXSetKey(handle, key, HASH_X_TYPE_STRING);
132 return HashSetString(handle, key, value);
133 }
134
135 stock HashXSetArray(HashX:handle, const key[], const any:buffer[], size) {
136 __HashXSetKey(handle, key, size);
137 return HashSetArray(handle, key, buffer, size);
138 }
139
140 stock HashXKeyType(HashX:handle, key[]) {
141 new Trie:types, type;
142 if(HashGetCell(handle, {10, 30, 'T', 0}, types) && TrieGetCell(types, key, type))
143 return type;
144 return HASH_X_TYPE_NONE;
145 }
146
147 /*
148 callback function get 2 or 3 parameters
149 1 - HashX handle
150 2 - key
151 3 - type if call HashXForEach with hashx_types > 0
152
153 example:
154
155 new HaxhX:trie_cells
156
157 my_func(id, key[]) {
158 new value
159 HashXGetCell(trie_cells, key, value)
160 server_print("Key: %s, Value: %s", key, value)
161 }
162
163 HashXForEach(trie_cells, "my_func")
164
165 or
166
167 new HaxhX:trie
168
169 my_func(id, key[], type) {
170 new value, string[512], Array:arr
171 switch (type) {
172 case HASH_X_TYPE_NONE: {
173 server_print("Key: %s is EMPTY", key)
174 }
175 case HASH_X_TYPE_CELL: {
176 HashXGetCell(trie, key, value)
177 server_print("Key: %s, Value: %d", key, value)
178 }
179 case HASH_X_TYPE_STRING: {
180 HashXGetString(trie, key, string)
181 server_print("Key: %s, Value: %s", key, string)
182 }
183 default: {
184 HashXGetArray(trie, key, arr)
185 server_print("Key: %s, ArraySize: %d", key, type)
186 }
187 }
188 }
189
190 HashXForEach(0, "my_func", 1)
191 */
192
193 stock HashXForEach({HashX,_}:id, HashX:handle, func[], hashx_types = 0) {
194 new Array:arr, arr_size = 0, key[HASH_KEY_SIZE];
195 new Trie:types, type;
196 new func_id = get_func_id(func);
197
198 if (hashx_types)
199 HashGetCell(handle, {10, 30, 'T', 0}, types);
200
201 if (func_id > -1 && HashGetCell(handle, {10, 30, 'L', 0}, arr) && arr && (arr_size = ArraySize(arr))) {
202 for (new i = 0; i < arr_size; i++) {
203 ArrayGetString(arr, i, key, charsmax(key));
204 if (callfunc_begin_i(func_id) > -1) {
205 callfunc_push_int(int:id);
206 callfunc_push_str(key);
207 if (hashx_types) {
208 TrieGetCell(types, key, type);
209 callfunc_push_int(type);
210 }
211 if (callfunc_end()) break;
212 }
213 }
214 }
215 }
216
217 stock Array:HashXGetKeys(HashX:handle) {
218 new Array:arr, Array:new_arr, arr_size, key[HASH_KEY_SIZE], i;
219 if (HashGetCell(handle, {10, 30, 'L', 0}, arr) && arr && (arr_size = ArraySize(arr))) {
220 new_arr = ArrayCreate(HASH_KEY_SIZE, arr_size);
221 for (i = 0; i < arr_size; i++) {
222 ArrayGetString(arr, i, key, charsmax(key));
223 ArrayPushString(new_arr, key);
224 }
225 } else
226 new_arr = ArrayCreate(HASH_KEY_SIZE);
227
228 return new_arr;
229 }
230
231 stock HashXSize(HashX:handle) {
232 new Array:arr;
233 if (HashGetCell(handle, {10, 30, 'L', 0}, arr))
234 return ArraySize(arr)
235 }