/src/ntopng/fuzz/stub/RedisStub.cpp
Line | Count | Source |
1 | | /* |
2 | | * |
3 | | * (C) 2013-23 - ntop.org |
4 | | * |
5 | | * |
6 | | * This program is free software; you can redistribute it and/or modify |
7 | | * it under the terms of the GNU General Public License as published by |
8 | | * the Free Software Foundation; either version 3 of the License, or |
9 | | * (at your option) any later version. |
10 | | * |
11 | | * This program is distributed in the hope that it will be useful, |
12 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | | * GNU General Public License for more details. |
15 | | * |
16 | | * You should have received a copy of the GNU General Public License |
17 | | * along with this program; if not, write to the Free Software Foundation, |
18 | | * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
19 | | * |
20 | | */ |
21 | | |
22 | | #include "ntop_includes.h" |
23 | | |
24 | | Redis::Redis(const char* redis_host, |
25 | | const char* redis_password, u_int16_t redis_port, |
26 | | u_int8_t _redis_db_id, bool giveup_on_failure, |
27 | | const char* tls_ca_cert, const char* tls_cert, |
28 | 20 | const char* tls_key, bool tls_skip_verify) { |
29 | 20 | this->redisVersion = "RedisStub"; |
30 | 20 | this->localToResolve = |
31 | 20 | std::make_unique<StringFifoQueue>(MAX_NUM_QUEUED_ADDRS); |
32 | 20 | this->remoteToResolve = |
33 | 20 | std::make_unique<StringFifoQueue>(MAX_NUM_QUEUED_ADDRS); |
34 | | |
35 | 20 | memset(&stats, 0, sizeof(stats)); |
36 | 20 | } |
37 | | |
38 | 15 | bool Redis::checkList(std::string key) { |
39 | 15 | return (this->store.find(key) == this->store.end() && |
40 | 15 | this->setStore.find(key) == this->setStore.end()); |
41 | 15 | } |
42 | | |
43 | 0 | bool Redis::checkSet(std::string key) { |
44 | 0 | return (this->store.find(key) == this->store.end() && |
45 | 0 | this->listStore.find(key) == this->listStore.end()); |
46 | 0 | } |
47 | | |
48 | 0 | char *Redis::getVersion() { return (char *)this->redisVersion.c_str(); } |
49 | | |
50 | 0 | u_int32_t Redis::getNumVersion() { return 1; } |
51 | | |
52 | 0 | bool Redis::hasRedisDump() { return false; } |
53 | | |
54 | 10 | void Redis::setDefaults() {} |
55 | | |
56 | 6 | bool Redis::isOperational() { return true; } |
57 | | |
58 | 10 | void Redis::setInitializationComplete() {} |
59 | | |
60 | 0 | int Redis::info(char *rsp, u_int rsp_len) { |
61 | 0 | if (rsp_len == 0) return -1; |
62 | | |
63 | 0 | stats.num_other++; |
64 | 0 | if(rsp_len == 0) |
65 | 0 | return -1; |
66 | | |
67 | 0 | rsp[0] = 0; |
68 | 0 | return 0; |
69 | 0 | } |
70 | | |
71 | 0 | u_int Redis::dbsize() { |
72 | 0 | stats.num_other++; |
73 | 0 | return this->store.size(); |
74 | 0 | } |
75 | | |
76 | 0 | int Redis::expire(char *key, u_int expire_sec) { |
77 | 0 | stats.num_expire++; |
78 | 0 | return 0; |
79 | 0 | } |
80 | | |
81 | 0 | char* Redis::getWithAlloc(char *key, bool cache_it) { |
82 | 0 | char *ret = NULL; |
83 | |
|
84 | 0 | stats.num_get++; |
85 | 0 | std::string strKey(key); |
86 | 0 | if (this->store.find(strKey) != this->store.end()) { |
87 | 0 | ret = strdup(this->store[strKey].c_str()); |
88 | 0 | } |
89 | |
|
90 | 0 | return ret; |
91 | 0 | } |
92 | | |
93 | | int Redis::get(char *key, char *rsp, u_int rsp_len, |
94 | 59.2k | bool cache_it /* = false */) { |
95 | 59.2k | if (rsp_len == 0) return -1; |
96 | | |
97 | 59.2k | stats.num_get++; |
98 | 59.2k | std::string strKey(key); |
99 | 59.2k | if (this->store.find(strKey) == this->store.end() || |
100 | 59.2k | snprintf(rsp, rsp_len, "%s", this->store[strKey].c_str()) < 0) { |
101 | 59.2k | rsp[0] = 0; |
102 | 59.2k | return -1; |
103 | 59.2k | } |
104 | | |
105 | 0 | return 0; |
106 | 59.2k | } |
107 | | |
108 | 0 | char* Redis::getset(const char *key, const char *value, u_int expire_secs) { |
109 | 0 | stats.num_get++; |
110 | 0 | std::string strKey(key); |
111 | 0 | char *old_value = NULL; |
112 | |
|
113 | 0 | if (this->store.find(strKey) != this->store.end()) |
114 | 0 | old_value = strdup(this->store[strKey].c_str()); |
115 | |
|
116 | 0 | this->store[strKey] = std::string(value); |
117 | |
|
118 | 0 | return old_value; |
119 | 0 | } |
120 | | |
121 | | int Redis::hashGet(const char *key, const char *member, char *const rsp, |
122 | 4.69k | u_int rsp_len) { |
123 | 4.69k | if (rsp_len == 0) return -1; |
124 | | |
125 | 4.69k | std::stringstream ss; |
126 | 4.69k | ss << key << "@" << member; |
127 | 4.69k | std::string strKey = ss.str(); |
128 | 4.69k | if (this->store.find(strKey) == this->store.end() || |
129 | 4.65k | snprintf(rsp, rsp_len, "%s", this->store[strKey].c_str()) < 0) { |
130 | 44 | rsp[0] = 0; |
131 | 44 | return -1; |
132 | 44 | } |
133 | | |
134 | 4.65k | return 0; |
135 | 4.69k | } |
136 | | |
137 | 0 | int Redis::hashDel(const char *key, const char *field) { |
138 | 0 | std::stringstream ss; |
139 | 0 | ss << key << "@" << field; |
140 | 0 | std::string strKey = ss.str(); |
141 | 0 | this->store.erase(strKey); |
142 | 0 | return 0; |
143 | 0 | } |
144 | | |
145 | 687k | int Redis::hashSet(const char *key, const char *field, const char *value) { |
146 | 687k | std::stringstream ss; |
147 | 687k | ss << key << "@" << field; |
148 | 687k | std::string strKey = ss.str(); |
149 | 687k | this->store[strKey] = std::string(value); |
150 | 687k | return 0; |
151 | 687k | } |
152 | | |
153 | | int Redis::set(const char *key, const char *value, |
154 | 4.29k | u_int expire_secs /* = 0 */) { |
155 | 4.29k | std::string strKey(key); |
156 | 4.29k | this->store[strKey] = std::string(value); |
157 | 4.29k | return 0; |
158 | 4.29k | } |
159 | | |
160 | | /* setnx = set if not existing */ |
161 | | int Redis::setnx(const char *key, const char *value, |
162 | 0 | u_int expire_secs /* = 0 */) { |
163 | 0 | std::string strKey(key); |
164 | 0 | if (this->store.find(strKey) != this->store.end()) return -1; |
165 | | |
166 | 0 | this->store[strKey] = std::string(value); |
167 | 0 | return 0; |
168 | 0 | } |
169 | | |
170 | 6 | int Redis::keys(const char *pattern, char ***keys_p) { |
171 | 6 | *keys_p = NULL; |
172 | 6 | return 0; |
173 | 6 | } |
174 | | |
175 | 0 | int Redis::hashKeys(const char *pattern, char ***keys_p) { |
176 | 0 | *keys_p = NULL; |
177 | 0 | return 0; |
178 | 0 | } |
179 | | |
180 | 9.33k | int Redis::hashGetAll(const char *key, char ***keys_p, char ***values_p) { |
181 | 9.33k | *keys_p = NULL; |
182 | 9.33k | return 0; |
183 | 9.33k | } |
184 | | |
185 | 6 | int Redis::del(char *key) { |
186 | 6 | std::string strKey(key); |
187 | 6 | stats.num_del++; |
188 | 6 | this->store.erase(strKey); |
189 | 6 | return 0; |
190 | 6 | } |
191 | | |
192 | 0 | int Redis::rename(char *key, char *new_key) { |
193 | 0 | return 0; |
194 | 0 | } |
195 | | |
196 | | int Redis::pushHostToResolve(char *hostname, bool dont_check_for_existence, |
197 | 1.74k | bool localHost) { |
198 | 1.74k | if (!ntop->getPrefs()->is_dns_resolution_enabled()) return 0; |
199 | 1.74k | if (hostname == NULL) return -1; |
200 | | |
201 | 1.74k | if (!Utils::shouldResolveHost(hostname)) return -1; |
202 | | |
203 | 1.74k | std::stringstream ss; |
204 | 1.74k | ss << DNS_CACHE << "." << hostname; |
205 | 1.74k | std::string strKey = ss.str(); |
206 | | |
207 | | /* Add only if the address has not been resolved yet */ |
208 | 1.74k | if (dont_check_for_existence || |
209 | 1.74k | this->store.find(strKey) == this->store.end()) { |
210 | 1.74k | auto &q = localHost ? localToResolve : remoteToResolve; |
211 | 1.74k | q->enqueue(hostname); |
212 | | |
213 | 1.74k | return 0; |
214 | 1.74k | } |
215 | | |
216 | 0 | return -1; |
217 | 1.74k | } |
218 | | |
219 | 0 | int Redis::popHostToResolve(char *hostname, u_int hostname_len) { |
220 | 0 | char *item = localToResolve->dequeue(); |
221 | 0 | int rv = -1; |
222 | |
|
223 | 0 | if (!item) item = remoteToResolve->dequeue(); |
224 | |
|
225 | 0 | if (item) { |
226 | 0 | strncpy(hostname, item, hostname_len); |
227 | 0 | hostname[hostname_len - 1] = 0; |
228 | 0 | free(item); |
229 | 0 | rv = 0; |
230 | 0 | } |
231 | |
|
232 | 0 | return rv; |
233 | 0 | } |
234 | | |
235 | | int Redis::getAddress(char *numeric_ip, char *rsp, u_int rsp_len, |
236 | 1.74k | bool queue_if_not_found) { |
237 | 1.74k | if (rsp_len == 0) return -1; |
238 | | |
239 | 1.74k | int rc; |
240 | 1.74k | char key[CONST_MAX_LEN_REDIS_KEY]; |
241 | 1.74k | bool already_in_bloom; |
242 | | |
243 | 1.74k | rsp[0] = 0; |
244 | 1.74k | snprintf(key, sizeof(key), "%s.%s", DNS_CACHE, numeric_ip); |
245 | | |
246 | 1.74k | if (!ntop->getResolutionBloom()->isSetBit(numeric_ip)) { |
247 | 1.74k | already_in_bloom = false; |
248 | 1.74k | rc = -1; /* No way to find it */ |
249 | 1.74k | } else { |
250 | 0 | already_in_bloom = true; |
251 | 0 | rc = this->get(key, rsp, rsp_len); |
252 | 0 | } |
253 | | |
254 | 1.74k | if (rc != 0) { |
255 | 1.74k | if (queue_if_not_found) { |
256 | 1.74k | if (already_in_bloom) |
257 | 0 | ntop->getResolutionBloom()->unsetBit( |
258 | 0 | numeric_ip); /* Expired key ? */ |
259 | | |
260 | 1.74k | this->pushHostToResolve(numeric_ip, true, false); |
261 | 1.74k | } |
262 | 1.74k | } else { |
263 | | /* We need to extend expire */ |
264 | 0 | if (!already_in_bloom) |
265 | 0 | ntop->getResolutionBloom()->setBit( |
266 | 0 | numeric_ip); /* Previously cached ? */ |
267 | |
|
268 | 0 | this->expire(key, DNS_CACHE_DURATION /* expire */); |
269 | 0 | } |
270 | | |
271 | 1.74k | return rc; |
272 | 1.74k | } |
273 | | |
274 | 0 | int Redis::setResolvedAddress(char *numeric_ip, char *symbolic_ip) { |
275 | 0 | char key[CONST_MAX_LEN_REDIS_KEY], numeric[256], *w, *h; |
276 | 0 | int rc = 0; |
277 | |
|
278 | 0 | snprintf(numeric, sizeof(numeric), "%s", numeric_ip); |
279 | |
|
280 | 0 | h = strtok_r(numeric, ";", &w); |
281 | |
|
282 | 0 | while (h != NULL) { |
283 | 0 | snprintf(key, sizeof(key), "%s.%s", DNS_CACHE, h); |
284 | 0 | ntop->getResolutionBloom()->setBit(h); |
285 | 0 | rc = this->set(key, symbolic_ip, DNS_CACHE_DURATION); |
286 | 0 | h = strtok_r(NULL, ";", &w); |
287 | 0 | } |
288 | |
|
289 | 0 | return rc; |
290 | 0 | } |
291 | | |
292 | 0 | int Redis::sadd(const char *set_name, char *item) { |
293 | 0 | std::string strKey(set_name); |
294 | 0 | if (!this->checkSet(strKey)) return -1; |
295 | 0 | if (this->setStore.find(strKey) == this->setStore.end()) |
296 | 0 | this->setStore[strKey] = std::set<std::string>(); |
297 | |
|
298 | 0 | auto result = this->setStore[strKey].insert(std::string(item)); |
299 | 0 | return (result.second ? 1 : 0); |
300 | 0 | } |
301 | | |
302 | 0 | int Redis::srem(const char *set_name, char *item) { |
303 | 0 | std::string strKey(set_name); |
304 | 0 | if (!this->checkSet(strKey)) return -1; |
305 | 0 | if (this->setStore.find(strKey) == this->setStore.end()) return 0; |
306 | | |
307 | 0 | return this->setStore[strKey].erase(std::string(item)); |
308 | 0 | } |
309 | | |
310 | 0 | int Redis::smembers(lua_State *vm, char *setName) { |
311 | 0 | stats.num_other++; |
312 | 0 | std::string strKey(setName); |
313 | 0 | if (!this->checkSet(strKey)) return -1; |
314 | 0 | if (this->setStore.find(strKey) == this->setStore.end()) return 0; |
315 | | |
316 | 0 | int k = 0; |
317 | 0 | const auto &values = this->setStore[strKey]; |
318 | 0 | for (const auto &val : values) { |
319 | 0 | lua_pushstring(vm, val.c_str()); |
320 | 0 | lua_rawseti(vm, -2, k + 1); |
321 | 0 | ++k; |
322 | 0 | } |
323 | |
|
324 | 0 | return 0; |
325 | 0 | } |
326 | | |
327 | 4.66k | int Redis::smembers(const char *set_name, char ***members) { |
328 | 4.66k | std::string strKey(set_name); |
329 | 4.66k | if (this->setStore.find(strKey) == this->setStore.end()) { |
330 | 4.66k | *members = NULL; |
331 | 4.66k | return -1; |
332 | 4.66k | } |
333 | | |
334 | 0 | int k = 0; |
335 | 0 | const auto &values = this->setStore[strKey]; |
336 | 0 | if ((*members = (char **)malloc(values.size() * sizeof(char *))) != NULL) |
337 | 0 | for (auto val : values) (*members)[k++] = strdup(val.c_str()); |
338 | |
|
339 | 0 | return values.size(); |
340 | 4.66k | } |
341 | | |
342 | 0 | bool Redis::sismember(const char *set_name, const char *member) { |
343 | 0 | stats.num_other++; |
344 | 0 | std::string strKey(set_name); |
345 | 0 | if (this->setStore.find(strKey) == this->setStore.end()) return false; |
346 | | |
347 | 0 | return (this->setStore[strKey].find(std::string(member)) == |
348 | 0 | this->setStore[strKey].end()); |
349 | 0 | } |
350 | | |
351 | | int Redis::lpush(const char *queue_name, const char *msg, u_int queue_trim_size, |
352 | 15 | bool trace_errors /* = true */) { |
353 | 15 | stats.num_lpush_rpush++; |
354 | 15 | std::string strKey(queue_name); |
355 | 15 | if (!this->checkList(strKey)) return -1; |
356 | | |
357 | 15 | if (this->listStore.find(strKey) == this->listStore.end()) |
358 | 13 | this->listStore[strKey] = std::vector<std::string>(); |
359 | | |
360 | 15 | this->listStore[strKey].insert(this->listStore[strKey].begin(), |
361 | 15 | std::string(msg)); |
362 | | |
363 | 15 | if (queue_trim_size > 0) { |
364 | 3 | stats.num_trim++; |
365 | 3 | if (this->ltrim(queue_name, -queue_trim_size, -1) == -1) return -1; |
366 | 3 | } |
367 | | |
368 | 15 | return this->listStore[strKey].size(); |
369 | 15 | } |
370 | | |
371 | | int Redis::rpush(const char *queue_name, const char *msg, |
372 | 0 | u_int queue_trim_size) { |
373 | 0 | stats.num_lpush_rpush++; |
374 | 0 | std::string strKey(queue_name); |
375 | 0 | if (!this->checkList(strKey)) return -1; |
376 | | |
377 | 0 | if (this->listStore.find(strKey) == this->listStore.end()) |
378 | 0 | this->listStore[strKey] = std::vector<std::string>(); |
379 | |
|
380 | 0 | this->listStore[strKey].push_back(std::string(msg)); |
381 | |
|
382 | 0 | if (queue_trim_size > 0) { |
383 | 0 | stats.num_trim++; |
384 | 0 | if (this->ltrim(queue_name, -queue_trim_size, -1) == -1) return -1; |
385 | 0 | } |
386 | | |
387 | 0 | return this->listStore[strKey].size(); |
388 | 0 | } |
389 | | |
390 | 0 | int Redis::lindex(const char *queue_name, int idx, char *buf, u_int buf_len) { |
391 | 0 | if (buf_len == 0) return -1; |
392 | 0 | stats.num_other++; |
393 | 0 | std::string strKey(queue_name); |
394 | 0 | if (this->listStore.find(strKey) == this->listStore.end()) { |
395 | 0 | buf[0] = 0; |
396 | 0 | return -1; |
397 | 0 | } |
398 | | |
399 | 0 | const auto &list = this->listStore[strKey]; |
400 | |
|
401 | 0 | if (idx < 0) idx += (int)list.size(); |
402 | 0 | if (idx < 0 || idx >= (int)list.size()) { |
403 | 0 | buf[0] = 0; |
404 | 0 | return -1; |
405 | 0 | } |
406 | | |
407 | 0 | snprintf(buf, buf_len, "%s", list[idx].c_str()); |
408 | |
|
409 | 0 | return 0; |
410 | 0 | } |
411 | | |
412 | 3 | int Redis::ltrim(const char *queue_name, int start_idx, int end_idx) { |
413 | 3 | stats.num_other++; |
414 | 3 | std::string strKey(queue_name); |
415 | 3 | if (this->listStore.find(strKey) == this->listStore.end()) return -1; |
416 | | |
417 | 3 | auto &list = this->listStore[strKey]; |
418 | 3 | if (start_idx < 0) start_idx += list.size(); |
419 | 3 | if (end_idx < 0) end_idx += list.size(); |
420 | 3 | int k = 0; |
421 | 9 | for (auto it = list.begin(); it != list.end(); ++k) { |
422 | 6 | if (k < start_idx || k > end_idx) |
423 | 0 | list.erase(it); |
424 | 6 | else |
425 | 6 | ++it; |
426 | 6 | } |
427 | | |
428 | 3 | return 0; |
429 | 3 | } |
430 | | |
431 | 0 | u_int Redis::hstrlen(const char *key, const char *value) { |
432 | 0 | stats.num_other++; |
433 | 0 | std::stringstream ss; |
434 | 0 | ss << key << "@" << value; |
435 | 0 | std::string strKey = ss.str(); |
436 | 0 | if (this->store.find(strKey) == this->store.end()) return 0; |
437 | | |
438 | 0 | return this->store[strKey].size(); |
439 | 0 | } |
440 | | |
441 | 6 | u_int Redis::len(const char *key) { |
442 | 6 | std::string strKey(key); |
443 | 6 | if (this->store.find(strKey) == this->store.end()) return 0; |
444 | | |
445 | 0 | return this->store[strKey].size(); |
446 | 6 | } |
447 | | |
448 | 3 | u_int Redis::llen(const char *queue_name) { |
449 | 3 | stats.num_llen++; |
450 | 3 | std::string strKey(queue_name); |
451 | 3 | if (this->listStore.find(strKey) == this->listStore.end()) return 0; |
452 | | |
453 | 2 | return this->listStore[strKey].size(); |
454 | 3 | } |
455 | | |
456 | 0 | int Redis::lset(const char *queue_name, u_int32_t idx, const char *value) { |
457 | 0 | return -1; |
458 | 0 | } |
459 | | |
460 | 12 | int Redis::lrem(const char *queue_name, const char *value) { |
461 | 12 | stats.num_other++; |
462 | 12 | std::string strKey(queue_name); |
463 | 12 | if (this->listStore.find(strKey) == this->listStore.end()) return 0; |
464 | | |
465 | 0 | for (auto it = this->listStore[strKey].begin(); |
466 | 0 | it != this->listStore[strKey].end();) { |
467 | 0 | if (strncmp(it->c_str(), value, it->size()) == 0) |
468 | 0 | this->listStore[strKey].erase(it); |
469 | 0 | else |
470 | 0 | ++it; |
471 | 0 | } |
472 | 0 | return 0; |
473 | 12 | } |
474 | | |
475 | | int Redis::lrange(const char *list_name, char ***elements, int start_offset, |
476 | 0 | int end_offset) { |
477 | 0 | stats.num_other++; |
478 | 0 | std::string strKey(list_name); |
479 | 0 | if (this->listStore.find(strKey) == this->listStore.end()) return 0; |
480 | | |
481 | 0 | auto &list = this->listStore[strKey]; |
482 | 0 | if (start_offset < 0) start_offset += list.size(); |
483 | 0 | if (end_offset < 0) end_offset += list.size(); |
484 | 0 | int k = 0; |
485 | 0 | vector<std::string> retList; |
486 | 0 | for (auto it = list.begin(); it != list.end(); ++k, ++it) { |
487 | 0 | if (k >= start_offset && k <= end_offset) retList.push_back(*it); |
488 | 0 | } |
489 | |
|
490 | 0 | *elements = (char **)malloc(retList.size() * sizeof(char *)); |
491 | 0 | for (int i = 0; i < (int)retList.size(); ++i) |
492 | 0 | (*elements)[i] = strdup(retList[i].c_str()); |
493 | |
|
494 | 0 | return retList.size(); |
495 | 0 | } |
496 | | |
497 | 0 | int Redis::lpop(const char *queue_name, char **buf) { |
498 | 0 | *buf = NULL; |
499 | 0 | stats.num_lpop_rpop++; |
500 | 0 | std::string strKey(queue_name); |
501 | 0 | if (this->listStore.find(strKey) == this->listStore.end()) { |
502 | 0 | return -1; |
503 | 0 | } |
504 | | |
505 | 0 | if (this->listStore[strKey].size() == 0) { |
506 | 0 | return -1; |
507 | 0 | } |
508 | | |
509 | 0 | *buf = (char *)strdup(this->listStore[strKey].front().c_str()); |
510 | 0 | if (!buf) { |
511 | 0 | return -1; |
512 | 0 | } |
513 | | |
514 | 0 | this->listStore[strKey].erase(this->listStore[strKey].begin()); |
515 | |
|
516 | 0 | return 0; |
517 | 0 | } |
518 | | |
519 | 0 | int Redis::rpop(const char *queue_name, char **buf) { |
520 | 0 | *buf = NULL; |
521 | 0 | stats.num_lpop_rpop++; |
522 | 0 | std::string strKey(queue_name); |
523 | 0 | if (this->listStore.find(strKey) == this->listStore.end()) { |
524 | 0 | return -1; |
525 | 0 | } |
526 | | |
527 | 0 | if (this->listStore[strKey].size() == 0) { |
528 | 0 | return -1; |
529 | 0 | } |
530 | | |
531 | 0 | *buf = (char *)strdup(this->listStore[strKey].back().c_str()); |
532 | 0 | if (!buf) { |
533 | 0 | return -1; |
534 | 0 | } |
535 | | |
536 | 0 | this->listStore[strKey].pop_back(); |
537 | |
|
538 | 0 | return 0; |
539 | 0 | } |
540 | | |
541 | 0 | int Redis::incr(const char *key, int amount) { |
542 | 0 | std::string strKey(key); |
543 | 0 | if (this->store.find(strKey) == this->store.end()) return 0; |
544 | | |
545 | 0 | const auto &val = this->store[strKey]; |
546 | 0 | try { |
547 | 0 | long l = std::stol(val); |
548 | 0 | l += amount; |
549 | 0 | std::stringstream ss; |
550 | 0 | ss << l; |
551 | 0 | this->store[strKey] = ss.str(); |
552 | 0 | return l; |
553 | 0 | } catch (std::exception const &e) { |
554 | 0 | return 0; |
555 | 0 | } |
556 | 0 | } |
557 | | |
558 | 0 | int Redis::flushDb() { |
559 | 0 | stats.num_other++; |
560 | 0 | this->store.clear(); |
561 | 0 | return 0; |
562 | 0 | } |
563 | | |
564 | 0 | void Redis::flushCache() {} |
565 | | |
566 | 0 | void Redis::lua(lua_State *vm) { |
567 | 0 | lua_newtable(vm); |
568 | |
|
569 | 0 | lua_push_uint64_table_entry(vm, "num_expire", stats.num_expire); |
570 | 0 | lua_push_uint64_table_entry(vm, "num_get", stats.num_get); |
571 | 0 | lua_push_uint64_table_entry(vm, "num_ttl", stats.num_ttl); |
572 | 0 | lua_push_uint64_table_entry(vm, "num_del", stats.num_del); |
573 | 0 | lua_push_uint64_table_entry(vm, "num_hget", stats.num_hget); |
574 | 0 | lua_push_uint64_table_entry(vm, "num_hset", stats.num_hset); |
575 | 0 | lua_push_uint64_table_entry(vm, "num_hdel", stats.num_hdel); |
576 | 0 | lua_push_uint64_table_entry(vm, "num_set", stats.num_set); |
577 | 0 | lua_push_uint64_table_entry(vm, "num_expire", stats.num_expire); |
578 | 0 | lua_push_uint64_table_entry(vm, "num_keys", stats.num_keys); |
579 | 0 | lua_push_uint64_table_entry(vm, "num_hkeys", stats.num_hkeys); |
580 | 0 | lua_push_uint64_table_entry(vm, "num_hgetall", stats.num_hgetall); |
581 | 0 | lua_push_uint64_table_entry(vm, "num_trim", stats.num_trim); |
582 | 0 | lua_push_uint64_table_entry(vm, "num_reconnections", |
583 | 0 | stats.num_reconnections); |
584 | 0 | lua_push_uint64_table_entry(vm, "num_lpush_rpush", stats.num_lpush_rpush); |
585 | 0 | lua_push_uint64_table_entry(vm, "num_lpop_rpop", stats.num_lpop_rpop); |
586 | 0 | lua_push_uint64_table_entry(vm, "num_llen", stats.num_llen); |
587 | 0 | lua_push_uint64_table_entry(vm, "num_strlen", stats.num_strlen); |
588 | 0 | lua_push_uint64_table_entry(vm, "num_other", stats.num_other); |
589 | | |
590 | | /* Address resolution */ |
591 | 0 | lua_push_uint64_table_entry(vm, "num_resolver_saved_lookups", |
592 | 0 | stats.num_saved_lookups); |
593 | 0 | lua_push_uint64_table_entry(vm, "num_resolver_get_address", |
594 | 0 | stats.num_get_address); |
595 | 0 | lua_push_uint64_table_entry(vm, "num_resolver_set_address", |
596 | 0 | stats.num_set_resolved_address); |
597 | 0 | } |
598 | | |
599 | 0 | char *Redis::dump(char *key) { |
600 | 0 | stats.num_other++; |
601 | 0 | char *ret = (char *)malloc(1); |
602 | 0 | ret[0] = 0; |
603 | 0 | return ret; |
604 | 0 | } |
605 | | |
606 | 0 | int Redis::restore(char *key, char *buf) { return 0; } |
607 | | |
608 | 0 | char* Redis::findAllWithAlloc(char* key) { return(NULL); } |
609 | | |
610 | 0 | char* Redis::findBestWithAlloc(char* key) { return(NULL); } |