From 67152656a8f6f49d2e04b99a91734d4c59a8b569 Mon Sep 17 00:00:00 2001 From: Khaled Alam Date: Tue, 23 May 2023 09:32:58 +0300 Subject: [PATCH 1/4] Add the actual keys' values hint instead of only hint word key for GET command. --- src/redis-cli.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 84 insertions(+), 5 deletions(-) diff --git a/src/redis-cli.c b/src/redis-cli.c index 3f5827fbe..046a20fc2 100644 --- a/src/redis-cli.c +++ b/src/redis-cli.c @@ -281,8 +281,15 @@ static struct config { /* User preferences. */ static struct pref { - int hints; + // Hints + char hints; + char hints_keys_values; + unsigned int hints_keys_values_count; } pref; +#define HINTS_ON '1' +#define HINTS_OFF '0' +#define HINTS_KEYS_VALUES_COUNT 5 +#define HINTS_KEYS_VALUES_COUNT_MAX 20 static volatile sig_atomic_t force_cancel_loop = 0; static void usage(int err); @@ -974,6 +981,9 @@ static void cliOutputGenericHelp(void) { "To set redis-cli preferences:\n" " \":set hints\" enable online hints\n" " \":set nohints\" disable online hints\n" + " \":set hints-keys-values\" enable online hints of actual keys' values\n" + " \":set nohints-keys-values\" enable online hints of actual keys' values\n" + " \":set hints-keys-value-counts X\" set online hints of actual keys' values to X items (default: 5, max: 20)\n" "Set your preferences in ~/.redisclirc\n", version ); @@ -1491,11 +1501,58 @@ static helpEntry* findHelpEntry(int argc, char **argv) { return entry; } +/* Add the actual keys' values hint instead of only hint word "key" for GET command. + * + * This method depends on: + * 1) The hint value to be "key" + * 2) SCAN command(since: v2.8.0) with pattern[PREFIX*] + * + * The default hints_keys_values_count is 5 keys. + */ +static void addActualKeysValuesHint(const sds* secondArgv, hisds* hint) { + + if (*secondArgv && *hint && strcmp((*hint), "key") == 0) { + + (*hint) = sdsnew("key: [ "); + + // Form pattern: e.g. "GET X" pattern will be "X*" + sds matchPattern = sdsnew((*secondArgv)); + matchPattern = sdscat(matchPattern, "*"); + + redisReply *reply = NULL; + unsigned int cur = 0, cnt = 0; + do { + reply = redisCommand(context,"SCAN %d MATCH %s COUNT 1",cur, matchPattern); + cur = atoi(reply->element[0]->str); + reply = reply->element[1]; + + for (unsigned int j = 0; j < reply->elements; j++) { + (*hint) = sdscat((*hint), reply->element[j]->str); + (*hint) = sdscat((*hint), ", "); + if (++cnt >= pref.hints_keys_values_count) { + cur = 0; + break; + } + } + } while(cur != 0 && cnt < pref.hints_keys_values_count); + + (*hint) = sdscat((*hint), "]"); + + sdsfree(matchPattern); + freeReplyObject(reply); + } +} + /* Returns the command-line hint string for a given partial input. */ static sds getHintForInput(const char *charinput) { sds hint = NULL; + int inputargc, inputlen = strlen(charinput); sds *inputargv = sdssplitargs(charinput, &inputargc); + + int secondArgc; + sds *secondArgv = sdssplitargs(charinput+3, &secondArgc); + int endspace = inputlen && isspace(charinput[inputlen-1]); /* Don't match the last word until the user has typed a space after it. */ @@ -1505,13 +1562,20 @@ static sds getHintForInput(const char *charinput) { if (entry) { hint = makeHint(inputargv, matchargc, entry->argc, entry->docs); } + + if (pref.hints_keys_values == HINTS_ON && !endspace && *secondArgv) { + addActualKeysValuesHint(secondArgv, &hint); + } + sdsfreesplitres(inputargv, inputargc); + sdsfreesplitres(secondArgv, secondArgc); + return hint; } /* Linenoise hints callback. */ static char *hintsCallback(const char *buf, int *color, int *bold) { - if (!pref.hints) return NULL; + if (pref.hints != HINTS_ON) return NULL; sds hint = getHintForInput(buf); if (hint == NULL) { @@ -3219,8 +3283,21 @@ static sds *cliSplitArgs(char *line, int *argc) { * set user preferences. */ void cliSetPreferences(char **argv, int argc, int interactive) { if (!strcasecmp(argv[0],":set") && argc >= 2) { - if (!strcasecmp(argv[1],"hints")) pref.hints = 1; - else if (!strcasecmp(argv[1],"nohints")) pref.hints = 0; + if (!strcasecmp(argv[1],"hints")) pref.hints = HINTS_ON; + else if (!strcasecmp(argv[1],"nohints")) pref.hints = HINTS_OFF; + else if (!strcasecmp(argv[1],"hints-keys-values")) pref.hints_keys_values = HINTS_ON; + else if (!strcasecmp(argv[1],"hints-keys-values-count")){ + if (argc >= 3) { + int hints_keys_values_count_value = atoi(argv[2]); + if (hints_keys_values_count_value < 1 || hints_keys_values_count_value > HINTS_KEYS_VALUES_COUNT_MAX) { + hints_keys_values_count_value = HINTS_KEYS_VALUES_COUNT; + } + pref.hints_keys_values_count = hints_keys_values_count_value; + } else { + pref.hints_keys_values_count = HINTS_KEYS_VALUES_COUNT; + } + } + else if (!strcasecmp(argv[1],"nohints-keys-values")) pref.hints_keys_values = HINTS_OFF; else { printf("%sunknown redis-cli preference '%s'\n", interactive ? "" : ".redisclirc: ", @@ -9820,7 +9897,9 @@ int main(int argc, char **argv) { config.cluster_manager_command.threshold = CLUSTER_MANAGER_REBALANCE_THRESHOLD; config.cluster_manager_command.backup_dir = NULL; - pref.hints = 1; + pref.hints = HINTS_ON; + pref.hints_keys_values = HINTS_ON; + pref.hints_keys_values_count = HINTS_KEYS_VALUES_COUNT; spectrum_palette = spectrum_palette_color; spectrum_palette_size = spectrum_palette_color_size; From 55fdac1a6301f00cbe0843f00179f749381f45a7 Mon Sep 17 00:00:00 2001 From: Khaled Alam Date: Tue, 23 May 2023 09:56:56 +0300 Subject: [PATCH 2/4] Increase SCAN COUNT. --- src/redis-cli.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/redis-cli.c b/src/redis-cli.c index 046a20fc2..792146c75 100644 --- a/src/redis-cli.c +++ b/src/redis-cli.c @@ -1522,7 +1522,7 @@ static void addActualKeysValuesHint(const sds* secondArgv, hisds* hint) { redisReply *reply = NULL; unsigned int cur = 0, cnt = 0; do { - reply = redisCommand(context,"SCAN %d MATCH %s COUNT 1",cur, matchPattern); + reply = redisCommand(context,"SCAN %d MATCH %s COUNT 10000",cur, matchPattern); cur = atoi(reply->element[0]->str); reply = reply->element[1]; From bd3aa577ca1b750c71190bf8e77906f829a75aed Mon Sep 17 00:00:00 2001 From: Khaled Alam Date: Wed, 24 May 2023 06:13:41 +0300 Subject: [PATCH 3/4] Make hints-keys-values OFF by default. --- src/redis-cli.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/redis-cli.c b/src/redis-cli.c index 792146c75..65b7eebf0 100644 --- a/src/redis-cli.c +++ b/src/redis-cli.c @@ -981,7 +981,7 @@ static void cliOutputGenericHelp(void) { "To set redis-cli preferences:\n" " \":set hints\" enable online hints\n" " \":set nohints\" disable online hints\n" - " \":set hints-keys-values\" enable online hints of actual keys' values\n" + " \":set hints-keys-values\" enable online hints of actual keys' values (by default it's OFF)\n" " \":set nohints-keys-values\" enable online hints of actual keys' values\n" " \":set hints-keys-value-counts X\" set online hints of actual keys' values to X items (default: 5, max: 20)\n" "Set your preferences in ~/.redisclirc\n", @@ -1506,7 +1506,8 @@ static helpEntry* findHelpEntry(int argc, char **argv) { * This method depends on: * 1) The hint value to be "key" * 2) SCAN command(since: v2.8.0) with pattern[PREFIX*] - * + * + * The default hints_keys_values is '0' (OFF). * The default hints_keys_values_count is 5 keys. */ static void addActualKeysValuesHint(const sds* secondArgv, hisds* hint) { @@ -1563,7 +1564,8 @@ static sds getHintForInput(const char *charinput) { hint = makeHint(inputargv, matchargc, entry->argc, entry->docs); } - if (pref.hints_keys_values == HINTS_ON && !endspace && *secondArgv) { + if (pref.hints_keys_values == HINTS_ON && !endspace && *secondArgv + && *inputargv && strcasecmp((*inputargv), "get") == 0) { addActualKeysValuesHint(secondArgv, &hint); } @@ -3288,13 +3290,10 @@ void cliSetPreferences(char **argv, int argc, int interactive) { else if (!strcasecmp(argv[1],"hints-keys-values")) pref.hints_keys_values = HINTS_ON; else if (!strcasecmp(argv[1],"hints-keys-values-count")){ if (argc >= 3) { - int hints_keys_values_count_value = atoi(argv[2]); - if (hints_keys_values_count_value < 1 || hints_keys_values_count_value > HINTS_KEYS_VALUES_COUNT_MAX) { - hints_keys_values_count_value = HINTS_KEYS_VALUES_COUNT; + unsigned int hints_keys_values_count_value = (unsigned int)atoi(argv[2]); + if (hints_keys_values_count_value >= 1 && hints_keys_values_count_value <= HINTS_KEYS_VALUES_COUNT_MAX) { + pref.hints_keys_values_count = hints_keys_values_count_value; } - pref.hints_keys_values_count = hints_keys_values_count_value; - } else { - pref.hints_keys_values_count = HINTS_KEYS_VALUES_COUNT; } } else if (!strcasecmp(argv[1],"nohints-keys-values")) pref.hints_keys_values = HINTS_OFF; @@ -9898,7 +9897,7 @@ int main(int argc, char **argv) { CLUSTER_MANAGER_REBALANCE_THRESHOLD; config.cluster_manager_command.backup_dir = NULL; pref.hints = HINTS_ON; - pref.hints_keys_values = HINTS_ON; + pref.hints_keys_values = HINTS_OFF; pref.hints_keys_values_count = HINTS_KEYS_VALUES_COUNT; spectrum_palette = spectrum_palette_color; From ef4a9c4848ed42dcb5a9621b835ac6866643e338 Mon Sep 17 00:00:00 2001 From: Khaled Alam Date: Wed, 24 May 2023 07:02:29 +0300 Subject: [PATCH 4/4] Fix typo in comment. --- src/redis-cli.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/redis-cli.c b/src/redis-cli.c index 65b7eebf0..d8d14ec9c 100644 --- a/src/redis-cli.c +++ b/src/redis-cli.c @@ -1507,7 +1507,7 @@ static helpEntry* findHelpEntry(int argc, char **argv) { * 1) The hint value to be "key" * 2) SCAN command(since: v2.8.0) with pattern[PREFIX*] * - * The default hints_keys_values is '0' (OFF). + * By default hints_keys_values is OFF. * The default hints_keys_values_count is 5 keys. */ static void addActualKeysValuesHint(const sds* secondArgv, hisds* hint) {