From 59012a18e190532f673e72899b3e005e9792d8f8 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 27 Dec 2022 18:49:24 +0800 Subject: [PATCH 1/3] vim-patch:9.0.1096: reallocating hashtab when the size didn't change Problem: Reallocating hashtab when the size didn't change. Solution: Bail out when the hashtab is already the desired size. https://github.com/vim/vim/commit/71d53e7c579b8af44083142ea3894b455947ad81 Co-authored-by: Bram Moolenaar --- src/nvim/hashtab.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/nvim/hashtab.c b/src/nvim/hashtab.c index fdbfdd7d77..448e78ab07 100644 --- a/src/nvim/hashtab.c +++ b/src/nvim/hashtab.c @@ -334,6 +334,11 @@ static void hash_may_resize(hashtab_T *ht, size_t minitems) assert(newsize != 0); } + // bail out if the hashtab is already at the desired size + if (newsize == ht->ht_mask + 1) { + return; + } + bool newarray_is_small = newsize == HT_INIT_SIZE; bool keep_smallarray = newarray_is_small && ht->ht_array == ht->ht_smallarray; From 9bab4b72ae4c996751a83badc1c2a183c7cbf5d2 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 27 Dec 2022 18:54:52 +0800 Subject: [PATCH 2/3] vim-patch:9.0.1097: tests are failing Problem: Tests are failing. Solution: Do clean up a hashtab when at the initial size. https://github.com/vim/vim/commit/b3d614369fceb891819badc941f80f08f57831f9 Co-authored-by: Bram Moolenaar --- src/nvim/hashtab.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/nvim/hashtab.c b/src/nvim/hashtab.c index 448e78ab07..55198d8e05 100644 --- a/src/nvim/hashtab.c +++ b/src/nvim/hashtab.c @@ -334,12 +334,13 @@ static void hash_may_resize(hashtab_T *ht, size_t minitems) assert(newsize != 0); } - // bail out if the hashtab is already at the desired size - if (newsize == ht->ht_mask + 1) { + bool newarray_is_small = newsize == HT_INIT_SIZE; + + if (!newarray_is_small && newsize == ht->ht_mask + 1) { + // the hashtab is already at the desired size, bail out return; } - bool newarray_is_small = newsize == HT_INIT_SIZE; bool keep_smallarray = newarray_is_small && ht->ht_array == ht->ht_smallarray; From 45d9735aae9aea91420c849aace76ab72e9d3f2a Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 27 Dec 2022 18:58:24 +0800 Subject: [PATCH 3/3] vim-patch:9.0.1100: a hashtab with many removed items is not cleaned up Problem: A hashtab with many removed items is not cleaned up. Solution: Re-hash a hashtab even when the size didn't change if too many items were removed. https://github.com/vim/vim/commit/d0883faac6a74f777c9a6be9d035c59ee1c969c5 N/A patches for version.c: vim-patch:9.0.1099: trying to resize a hashtab may cause a problem Problem: Trying to resize a hashtab may cause a problem. Solution: Do not try to resize a hashtab before adding an item. https://github.com/vim/vim/commit/81b7ecc5cb78cad901a9a85e46ecba109cc6ee7d Co-authored-by: Bram Moolenaar --- src/nvim/hashtab.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/nvim/hashtab.c b/src/nvim/hashtab.c index 55198d8e05..042cb43ce4 100644 --- a/src/nvim/hashtab.c +++ b/src/nvim/hashtab.c @@ -292,6 +292,7 @@ static void hash_may_resize(hashtab_T *ht, size_t minitems) #endif // ifdef HT_DEBUG size_t minsize; + const size_t oldsize = ht->ht_mask + 1; if (minitems == 0) { // Return quickly for small tables with at least two NULL items. // items are required for the lookup to decide a key isn't there. @@ -304,7 +305,6 @@ static void hash_may_resize(hashtab_T *ht, size_t minitems) // removed items, so that they get cleaned up). // Shrink the array when it's less than 1/5 full. When growing it is // at least 1/4 full (avoids repeated grow-shrink operations) - size_t oldsize = ht->ht_mask + 1; if ((ht->ht_filled * 3 < oldsize * 2) && (ht->ht_used > oldsize / 5)) { return; } @@ -336,8 +336,9 @@ static void hash_may_resize(hashtab_T *ht, size_t minitems) bool newarray_is_small = newsize == HT_INIT_SIZE; - if (!newarray_is_small && newsize == ht->ht_mask + 1) { - // the hashtab is already at the desired size, bail out + if (!newarray_is_small && newsize == oldsize && ht->ht_filled * 3 < oldsize * 2) { + // The hashtab is already at the desired size, and there are not too + // many removed items, bail out. return; }