mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-04-26 12:58:03 +00:00
MINOR: cli: improve fuzzy matching to work on all remaining words at once
Till now the fuzzy matching would only work on the same number of words, but this doesn't account for commands like "show servers conn" which involve 3 words and were not proposed when entering only "show conn". Let's improve the situation by building the two fingerprints separately for the correct keyword sequence and the entered one, then compare them. This can result in slightly larger variations due to the different string lengths but is easily compensated for. Thanks to this, we can now see "show servers conn" when entering "show conn", and the following choices are relevant to correct typos: - "show foo" show sess [id] : report the list of current sessions or dump this session show info : report information about the running process [desc|json|typed]* show env [var] : dump environment variables known to the process show fd [num] : dump list of file descriptors in use show pools : report information about the memory pools usage - "show stuff" show sess [id] : report the list of current sessions or dump this session show info : report information about the running process [desc|json|typed]* show stat : report counters for each proxy and server [desc|json|no-maint|typed|up]* show fd [num] : dump list of file descriptors in use show tasks : show running tasks - "show stafe" show sess [id] : report the list of current sessions or dump this session show stat : report counters for each proxy and server [desc|json|no-maint|typed|up]* show fd [num] : dump list of file descriptors in use show table [id]: report table usage stats or dump this table's contents show tasks : show running tasks - "show state" show stat : report counters for each proxy and server [desc|json|no-maint|typed|up]* show servers state [id]: dump volatile server information (for backend <id>) It's still visible that the shorter ones continue to easily match, such as "show sess" not having much in common with "show foo" but what matters is that the best candidates are definitely relevant. Probably that listing them in match order would further help.
This commit is contained in:
parent
714c4c14d1
commit
a9aa628703
26
src/cli.c
26
src/cli.c
@ -164,26 +164,32 @@ static char *cli_gen_usage_msg(struct appctx *appctx, char * const *args)
|
||||
uint8_t list_sig[1024];
|
||||
int dist = 0;
|
||||
int totlen = 0;
|
||||
int i;
|
||||
|
||||
/* this one matches, let's compute the distance between the two
|
||||
* on the remaining words
|
||||
* on the remaining words. For this we're computing the signature
|
||||
* of everything that remains and the cumulated length of the
|
||||
* strings.
|
||||
*/
|
||||
memset(word_sig, 0, sizeof(word_sig));
|
||||
memset(list_sig, 0, sizeof(list_sig));
|
||||
|
||||
while (idx < CLI_PREFIX_KW_NB && kw->str_kw[idx] && args[idx] && *args[idx]) {
|
||||
update_word_fingerprint(word_sig, args[idx]);
|
||||
update_word_fingerprint(list_sig, kw->str_kw[idx]);
|
||||
totlen += strlen(args[idx]) + strlen(kw->str_kw[idx]);
|
||||
idx++;
|
||||
for (i = idx; i < CLI_PREFIX_KW_NB && args[i] && *args[i]; i++) {
|
||||
update_word_fingerprint(word_sig, args[i]);
|
||||
totlen += strlen(args[i]);
|
||||
}
|
||||
|
||||
memset(list_sig, 0, sizeof(list_sig));
|
||||
for (i = idx; i < CLI_PREFIX_KW_NB && kw->str_kw[i]; i++) {
|
||||
update_word_fingerprint(list_sig, kw->str_kw[i]);
|
||||
totlen += strlen(kw->str_kw[i]);
|
||||
}
|
||||
|
||||
dist = word_fingerprint_distance(word_sig, list_sig);
|
||||
|
||||
/* insert this one at its place if relevant, in order to keep only
|
||||
* the best matches.
|
||||
*/
|
||||
swp.kw = kw; swp.dist = dist;
|
||||
if (dist < totlen && dist < matches[CLI_MAX_MATCHES-1].dist) {
|
||||
if (dist < 5*totlen/2 && dist < matches[CLI_MAX_MATCHES-1].dist) {
|
||||
matches[CLI_MAX_MATCHES-1] = swp;
|
||||
for (idx = CLI_MAX_MATCHES - 1; --idx >= 0;) {
|
||||
if (matches[idx+1].dist >= matches[idx].dist)
|
||||
@ -229,7 +235,7 @@ static char *cli_gen_usage_msg(struct appctx *appctx, char * const *args)
|
||||
* idx will be CLI_MAX_MATCHES, indicating "not found".
|
||||
*/
|
||||
for (idx = 0; matches[0].kw && idx < CLI_MAX_MATCHES; idx++)
|
||||
if (kw == matches[idx].kw && matches[idx].dist <= 2*matches[0].dist)
|
||||
if (kw == matches[idx].kw && matches[idx].dist <= 5*matches[0].dist/2)
|
||||
break;
|
||||
|
||||
if (idx < CLI_MAX_MATCHES)
|
||||
|
Loading…
Reference in New Issue
Block a user