diff src/hashtab.c @ 31535:8b9771b827c1 v9.0.1100

patch 9.0.1100: a hashtab with many removed items is not cleaned up Commit: https://github.com/vim/vim/commit/d0883faac6a74f777c9a6be9d035c59ee1c969c5 Author: Bram Moolenaar <Bram@vim.org> Date: Mon Dec 26 13:51:26 2022 +0000 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.
author Bram Moolenaar <Bram@vim.org>
date Mon, 26 Dec 2022 15:00:04 +0100
parents a5959e14771a
children 04d9dff67d99
line wrap: on
line diff
--- a/src/hashtab.c
+++ b/src/hashtab.c
@@ -350,7 +350,7 @@ hash_may_resize(
     hashitem_T	*olditem, *newitem;
     unsigned	newi;
     int		todo;
-    long_u	oldsize, newsize;
+    long_u	newsize;
     long_u	minsize;
     long_u	newmask;
     hash_T	perturb;
@@ -366,6 +366,7 @@ hash_may_resize(
 	emsg("hash_may_resize(): table completely filled");
 #endif
 
+    long_u oldsize = ht->ht_mask + 1;
     if (minitems == 0)
     {
 	// Return quickly for small tables with at least two NULL items.  NULL
@@ -380,7 +381,6 @@ hash_may_resize(
 	 * 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)
 	 */
-	oldsize = ht->ht_mask + 1;
 	if (ht->ht_filled * 3 < oldsize * 2 && ht->ht_used > oldsize / 5)
 	    return OK;
 
@@ -422,9 +422,10 @@ hash_may_resize(
 	CLEAR_FIELD(ht->ht_smallarray);
     }
 
-    else if (newsize == ht->ht_mask + 1)
+    else if (newsize == oldsize && ht->ht_filled * 3 < oldsize * 2)
     {
-	// the hashtab is already at the desired size, bail out
+	// The hashtab is already at the desired size, and there are not too
+	// many removed items, bail out.
 	return OK;
     }