diff options
author | Sébastien Helleu <flashcode@flashtux.org> | 2023-02-23 07:35:21 +0100 |
---|---|---|
committer | Sébastien Helleu <flashcode@flashtux.org> | 2023-03-16 20:42:19 +0100 |
commit | d1adec29f9af2ddbc3513a88314b298254417bb5 (patch) | |
tree | d2065bdcea24969a0d40038fe213cbc7cb9b5008 /src | |
parent | 5b5c9afa290bd444514c446ab6184c2ca55d9d72 (diff) | |
download | weechat-d1adec29f9af2ddbc3513a88314b298254417bb5.zip |
core: optimize search of key by reducing the number of splits into chunks
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/gui-key.c | 115 |
1 files changed, 67 insertions, 48 deletions
diff --git a/src/gui/gui-key.c b/src/gui/gui-key.c index eab368a26..6b121912b 100644 --- a/src/gui/gui-key.c +++ b/src/gui/gui-key.c @@ -1307,32 +1307,31 @@ gui_key_compare_chunks (const char **chunks, int chunks_count, } /* - * Searches for a key (maybe part of string) for context default, search or - * cursor (not for mouse). + * Searches key chunks for context default, search or cursor (not for mouse). + * It can be part of key chunks or exact match. * - * If exact match is found, *exact_match is set to 1, otherwise to 0. + * Parameter "chunks1" is the raw key split into chunks, and "chunks2" is the + * key with alias split into chunks (at least one of the chunks must be non + * NULL). * * Returns pointer to key found, NULL if not found. + * In case of exact match, *exact_match is set to 1, otherwise 0. */ struct t_gui_key * gui_key_search_part (struct t_gui_buffer *buffer, int context, - const char *key, const char *key_alias, + const char **chunks1, int chunks1_count, + const char **chunks2, int chunks2_count, int *exact_match) { struct t_gui_key *ptr_key; - char **chunks, **chunks_alias; - int rc, chunks_count, chunks_alias_count; + int rc; - if (!key || !exact_match) + if ((!chunks1 && !chunks2) || !exact_match) return NULL; *exact_match = 0; - chunks = string_split (key, ",", NULL, 0, 0, &chunks_count); - chunks_alias = (key_alias) ? - string_split (key_alias, ",", NULL, 0, 0, &chunks_alias_count) : NULL; - for (ptr_key = (buffer) ? buffer->keys : gui_keys[context]; ptr_key; ptr_key = ptr_key->next_key) { @@ -1340,20 +1339,23 @@ gui_key_search_part (struct t_gui_buffer *buffer, int context, && ((context != GUI_KEY_CONTEXT_CURSOR) || (ptr_key->key[0] != '@'))) { - rc = gui_key_compare_chunks ((const char **)chunks, - chunks_count, - (const char **)ptr_key->chunks, - ptr_key->chunks_count); - if (rc > 0) + if (chunks1) { - if (rc == 2) - *exact_match = 1; - break; + rc = gui_key_compare_chunks (chunks1, + chunks1_count, + (const char **)ptr_key->chunks, + ptr_key->chunks_count); + if (rc > 0) + { + if (rc == 2) + *exact_match = 1; + break; + } } - if (chunks_alias) + if (chunks2) { - rc = gui_key_compare_chunks ((const char **)chunks_alias, - chunks_alias_count, + rc = gui_key_compare_chunks (chunks2, + chunks2_count, (const char **)ptr_key->chunks, ptr_key->chunks_count); if (rc > 0) @@ -1366,11 +1368,6 @@ gui_key_search_part (struct t_gui_buffer *buffer, int context, } } - if (chunks) - string_free_split (chunks); - if (chunks_alias) - string_free_split (chunks_alias); - return ptr_key; } @@ -1869,11 +1866,10 @@ int gui_key_pressed (const char *key_str) { int i, insert_into_input, context, length, length_key, signal_sent; - int rc, rc_expand, exact_match; + int rc, rc_expand, exact_match, chunks1_count, chunks2_count; struct t_gui_key *ptr_key; char *pos, signal_name[128], **commands; - char *key_name, *key_name_alias; - const char *ptr_key_name2; + char *key_name, *key_name_alias, **chunks1, **chunks2; signal_sent = 0; @@ -1944,42 +1940,65 @@ gui_key_pressed (const char *key_str) ptr_key = NULL; exact_match = 0; - ptr_key_name2 = (string_strcmp (key_name, key_name_alias) != 0) ? - key_name_alias : NULL; + + chunks1 = string_split (key_name, ",", NULL, 0, 0, &chunks1_count); + chunks2 = (string_strcmp (key_name, key_name_alias) != 0) ? + string_split (key_name_alias, ",", NULL, 0, 0, &chunks2_count) : NULL; context = gui_key_get_current_context (); switch (context) { case GUI_KEY_CONTEXT_DEFAULT: /* look for key combo in key table for current buffer */ - ptr_key = gui_key_search_part (gui_current_window->buffer, - GUI_KEY_CONTEXT_DEFAULT, - key_name, ptr_key_name2, - &exact_match); + ptr_key = gui_key_search_part ( + gui_current_window->buffer, + GUI_KEY_CONTEXT_DEFAULT, + (const char **)chunks1, chunks1_count, + (const char **)chunks2, chunks2_count, + &exact_match); /* if key is not found for buffer, then look in general table */ if (!ptr_key) - ptr_key = gui_key_search_part (NULL, GUI_KEY_CONTEXT_DEFAULT, - key_name, ptr_key_name2, - &exact_match); + { + ptr_key = gui_key_search_part ( + NULL, + GUI_KEY_CONTEXT_DEFAULT, + (const char **)chunks1, chunks1_count, + (const char **)chunks2, chunks2_count, + &exact_match); + } break; case GUI_KEY_CONTEXT_SEARCH: - ptr_key = gui_key_search_part (NULL, GUI_KEY_CONTEXT_SEARCH, - key_name, ptr_key_name2, - &exact_match); + ptr_key = gui_key_search_part ( + NULL, + GUI_KEY_CONTEXT_SEARCH, + (const char **)chunks1, chunks1_count, + (const char **)chunks2, chunks2_count, + &exact_match); if (!ptr_key) { - ptr_key = gui_key_search_part (NULL, GUI_KEY_CONTEXT_DEFAULT, - key_name, ptr_key_name2, - &exact_match); + ptr_key = gui_key_search_part ( + NULL, + GUI_KEY_CONTEXT_DEFAULT, + (const char **)chunks1, chunks1_count, + (const char **)chunks2, chunks2_count, + &exact_match); } break; case GUI_KEY_CONTEXT_CURSOR: - ptr_key = gui_key_search_part (NULL, GUI_KEY_CONTEXT_CURSOR, - key_name, ptr_key_name2, - &exact_match); + ptr_key = gui_key_search_part ( + NULL, + GUI_KEY_CONTEXT_CURSOR, + (const char **)chunks1, chunks1_count, + (const char **)chunks2, chunks2_count, + &exact_match); break; } + if (chunks1) + string_free_split (chunks1); + if (chunks2) + string_free_split (chunks2); + if (ptr_key) { /* |