Subject: bug#28590: [PATCH 7/7] weak-table: Resize less frequently.

From: Ludovic Courtès <[email-masked]>
Date: Tue, 3 Oct 2017 13:43:52 +0200

* libguile/weak-table.c (do_count_entries, update_entry_count): New
functions.
(resize_table): Use it; check 'n_items' and return if there's nothing to
do.
---
 libguile/weak-table.c | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/libguile/weak-table.c b/libguile/weak-table.c
index 24fff4e73..1a99a130f 100644
--- a/libguile/weak-table.c
+++ b/libguile/weak-table.c
@@ -504,6 +504,32 @@ is_acceptable_size_index (scm_t_weak_table *table, int size_index)
   return 0;
 }
 
+static void *
+do_count_entries (void *data)
+{
+  size_t i, count = 0;
+  scm_t_weak_table *table = data;
+
+  for (i = 0; i < table->size; i++)
+    {
+      if (table->entries[i].hash != 0
+	  && table->entries[i].key != 0
+	  && table->entries[i].value != 0)
+	count++;
+    }
+
+  table->n_items = count;
+
+  return table;
+}
+
+/* Traverse all of TABLE and updates its 'n_items' field.  */
+static void
+update_entry_count (scm_t_weak_table *table)
+{
+  GC_call_with_alloc_lock (do_count_entries, table);
+}
+
 static void
 resize_table (scm_t_weak_table *table)
 {
@@ -511,6 +537,14 @@ resize_table (scm_t_weak_table *table)
   int new_size_index;
   unsigned long old_size, new_size, old_k;
 
+  /* Make sure we have an accurate view of TABLE's load factor before
+     attempting to resize it.  */
+  update_entry_count (table);
+
+  if (table->n_items > table->lower
+      && table->n_items < table->upper)
+    return;
+
   do 
     {
       new_size_index = compute_size_index (table);
-- 
2.14.2