diff options
-rw-r--r-- | src/nvim/eval/userfunc.c | 16 | ||||
-rw-r--r-- | src/nvim/hashtab.c | 3 | ||||
-rw-r--r-- | src/nvim/hashtab.h | 17 |
3 files changed, 21 insertions, 15 deletions
diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c index a37613dca9..69b074ab99 100644 --- a/src/nvim/eval/userfunc.c +++ b/src/nvim/eval/userfunc.c @@ -1297,7 +1297,7 @@ void free_all_functions(void) ufunc_T *fp; uint64_t skipped = 0; uint64_t todo = 1; - uint64_t used; + int changed; // Clean up the current_funccal chain and the funccal stack. while (current_funccal != NULL) { @@ -1321,9 +1321,9 @@ void free_all_functions(void) if (func_name_refcount((char_u *)fp->uf_name)) { skipped++; } else { - used = func_hashtab.ht_used; + changed = func_hashtab.ht_changed; func_clear(fp, true); - if (used != func_hashtab.ht_used) { + if (changed != func_hashtab.ht_changed) { skipped = 0; break; } @@ -1993,8 +1993,8 @@ char *save_function_name(char **name, bool skip, int flags, funcdict_T *fudi) /// Otherwise functions matching "regmatch". static void list_functions(regmatch_T *regmatch) { - const size_t used = func_hashtab.ht_used; - size_t todo = used; + const int changed = func_hashtab.ht_changed; + size_t todo = func_hashtab.ht_used; const hashitem_T *const ht_array = func_hashtab.ht_array; for (const hashitem_T *hi = ht_array; todo > 0 && !got_int; hi++) { @@ -2008,7 +2008,7 @@ static void list_functions(regmatch_T *regmatch) : (!isdigit(*fp->uf_name) && vim_regexec(regmatch, (char *)fp->uf_name, 0)))) { list_func_head(fp, false, false); - if (used != func_hashtab.ht_used || ht_array != func_hashtab.ht_array) { + if (changed != func_hashtab.ht_changed) { emsg(_("E454: function list was modified")); return; } @@ -2730,15 +2730,17 @@ bool function_exists(const char *const name, bool no_deref) char *get_user_func_name(expand_T *xp, int idx) { static size_t done; + static int changed; static hashitem_T *hi; ufunc_T *fp; if (idx == 0) { done = 0; hi = func_hashtab.ht_array; + changed = func_hashtab.ht_changed; } assert(hi); - if (done < func_hashtab.ht_used) { + if (changed == func_hashtab.ht_changed && done < func_hashtab.ht_used) { if (done++ > 0) { hi++; } diff --git a/src/nvim/hashtab.c b/src/nvim/hashtab.c index 31dc6f5bd4..fdbfdd7d77 100644 --- a/src/nvim/hashtab.c +++ b/src/nvim/hashtab.c @@ -223,6 +223,7 @@ int hash_add(hashtab_T *ht, char *key) void hash_add_item(hashtab_T *ht, hashitem_T *hi, char_u *key, hash_T hash) { ht->ht_used++; + ht->ht_changed++; if (hi->hi_key == NULL) { ht->ht_filled++; } @@ -242,6 +243,7 @@ void hash_add_item(hashtab_T *ht, hashitem_T *hi, char_u *key, hash_T hash) void hash_remove(hashtab_T *ht, hashitem_T *hi) { ht->ht_used--; + ht->ht_changed++; hi->hi_key = HI_KEY_REMOVED; hash_may_resize(ht, 0); } @@ -384,6 +386,7 @@ static void hash_may_resize(hashtab_T *ht, size_t minitems) ht->ht_array = newarray; ht->ht_mask = newmask; ht->ht_filled = ht->ht_used; + ht->ht_changed++; } #define HASH_CYCLE_BODY(hash, p) \ diff --git a/src/nvim/hashtab.h b/src/nvim/hashtab.h index 28a3b69d44..0a50fb2ef8 100644 --- a/src/nvim/hashtab.h +++ b/src/nvim/hashtab.h @@ -61,14 +61,15 @@ typedef struct hashitem_S { /// /// The hashtable grows to accommodate more entries when needed. typedef struct hashtable_S { - hash_T ht_mask; /// mask used for hash value - /// (nr of items in array is "ht_mask" + 1) - size_t ht_used; /// number of items used - size_t ht_filled; /// number of items used or removed - int ht_locked; /// counter for hash_lock() - hashitem_T *ht_array; /// points to the array, allocated when it's - /// not "ht_smallarray" - hashitem_T ht_smallarray[HT_INIT_SIZE]; /// initial array + hash_T ht_mask; ///< mask used for hash value + ///< (nr of items in array is "ht_mask" + 1) + size_t ht_used; ///< number of items used + size_t ht_filled; ///< number of items used or removed + int ht_changed; ///< incremented when adding or removing an item + int ht_locked; ///< counter for hash_lock() + hashitem_T *ht_array; ///< points to the array, allocated when it's + ///< not "ht_smallarray" + hashitem_T ht_smallarray[HT_INIT_SIZE]; ///< initial array } hashtab_T; /// Iterate over a hashtab |