mirror of https://github.com/sipwise/kamailio.git
KEYS is considerably faster then SCAN, even with just one iteration, and
since we're always reading the full set of keys in one go anyway,
there's no benefit of using multiple SCAN invocations.
Change-Id: I0771db1b90273bf3bf73cb6b53e7d9ef8c43fcc6
(cherry picked from commit 053e45bdfa)
changes/14/32414/1
parent
0fcb821185
commit
fa52db1f18
@ -0,0 +1,91 @@
|
||||
--- a/src/modules/db_redis/redis_dbase.c
|
||||
+++ b/src/modules/db_redis/redis_dbase.c
|
||||
@@ -695,15 +695,21 @@
|
||||
|
||||
size_t i = 0;
|
||||
redis_key_t *query_v = NULL;
|
||||
- char cursor_str[32] = "";
|
||||
redisReply *reply = NULL;
|
||||
- unsigned long cursor = 0;
|
||||
+ redisReply *keys_list = NULL;
|
||||
size_t j;
|
||||
int l;
|
||||
+
|
||||
+
|
||||
+#undef USE_SCAN
|
||||
+
|
||||
+#ifdef USE_SCAN
|
||||
+
|
||||
+ char cursor_str[32] = "";
|
||||
+ unsigned long cursor = 0;
|
||||
unsigned int match_count = match_count_start_val;
|
||||
char match_count_str[16];
|
||||
|
||||
-
|
||||
do {
|
||||
snprintf(cursor_str, sizeof(cursor_str), "%lu", cursor);
|
||||
|
||||
@@ -763,16 +769,37 @@
|
||||
}
|
||||
LM_DBG("cursor is %lu\n", cursor);
|
||||
|
||||
- if (reply->element[1]->type != REDIS_REPLY_ARRAY) {
|
||||
+ keys_list = reply->element[1];
|
||||
+
|
||||
+#else // use KEYS
|
||||
+
|
||||
+ if (db_redis_key_add_string(&query_v, "KEYS", 4) != 0) {
|
||||
+ LM_ERR("Failed to add scan command to scan query\n");
|
||||
+ goto err;
|
||||
+ }
|
||||
+ if (db_redis_key_add_string(&query_v, match_pattern->s, match_pattern->len) != 0) {
|
||||
+ LM_ERR("Failed to add match pattern to scan query\n");
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ reply = db_redis_command_argv(con, query_v);
|
||||
+ db_redis_key_free(&query_v);
|
||||
+ db_redis_check_reply(con, reply, err);
|
||||
+
|
||||
+ keys_list = reply;
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
+ if (keys_list->type != REDIS_REPLY_ARRAY) {
|
||||
LM_ERR("Invalid content type for scan on table '%.*s', expected array\n",
|
||||
match_pattern->len, match_pattern->s);
|
||||
goto err;
|
||||
}
|
||||
|
||||
- *query_keys_count += reply->element[1]->elements;
|
||||
+ *query_keys_count += keys_list->elements;
|
||||
|
||||
- for (j = 0; j < reply->element[1]->elements; ++i, ++j) {
|
||||
- redisReply *key = reply->element[1]->element[j];
|
||||
+ for (j = 0; j < keys_list->elements; ++i, ++j) {
|
||||
+ redisReply *key = keys_list->element[j];
|
||||
if (!key) {
|
||||
LM_ERR("Invalid null key at cursor result index %lu while scanning table '%.*s'\n",
|
||||
j, match_pattern->len, match_pattern->s);
|
||||
@@ -789,14 +816,19 @@
|
||||
}
|
||||
}
|
||||
|
||||
+#ifdef USE_SCAN
|
||||
// exponential increase and falloff, hovering around 1000 results
|
||||
- if (reply->element[1]->elements > 1300 && match_count > 500)
|
||||
+ if (keys_list->elements > 1300 && match_count > 500)
|
||||
match_count /= 2;
|
||||
- else if (reply->element[1]->elements < 700 && match_count < 500000)
|
||||
+ else if (keys_list->elements < 700 && match_count < 500000)
|
||||
match_count *= 2;
|
||||
+#endif
|
||||
|
||||
db_redis_free_reply(&reply);
|
||||
+
|
||||
+#ifdef USE_SCAN
|
||||
} while (cursor > 0);
|
||||
+#endif
|
||||
|
||||
// for full table scans, we have to manually match all given keys
|
||||
// but only do this once for repeated invocations
|
||||
Loading…
Reference in new issue