]> granicus.if.org Git - vim/commitdiff
patch 9.0.1100: a hashtab with many removed items is not cleaned up v9.0.1100
authorBram Moolenaar <Bram@vim.org>
Mon, 26 Dec 2022 13:51:26 +0000 (13:51 +0000)
committerBram Moolenaar <Bram@vim.org>
Mon, 26 Dec 2022 13:51:26 +0000 (13:51 +0000)
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.

src/hashtab.c
src/version.c

index 8c25c818b2f610f82bc5a338242fde7ff9843387..ddf1877693bac37b141d75e36d5309ce748a8dd4 100644 (file)
@@ -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;
     }
 
index eb362a3de1b22be1db14c3b4e454c1dde1d494fd..e8ea9f54f42996528cd1fdc5237b3d6e4fd6d76f 100644 (file)
@@ -695,6 +695,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1100,
 /**/
     1099,
 /**/