[gtk/wip/matthiasc/stringlist-array: 2/2] stringlist: Try to reuse objects



commit 31404c5d2fc93bc9c69904f297ccc8e3234b0cb4
Author: Matthias Clasen <mclasen redhat com>
Date:   Tue Jun 30 23:52:10 2020 -0400

    stringlist: Try to reuse objects
    
    Try a few nearby positions to see if they have
    unused objects, and if so, steal one. This avoids
    object growth when filtering, but does not help
    for scrolling.

 gtk/gtkstringlist.c | 42 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 41 insertions(+), 1 deletion(-)
---
diff --git a/gtk/gtkstringlist.c b/gtk/gtkstringlist.c
index 45ee337992..62a5afef50 100644
--- a/gtk/gtkstringlist.c
+++ b/gtk/gtkstringlist.c
@@ -205,6 +205,38 @@ MAKE_STRING (const char *str)
   return GINT_TO_POINTER (GPOINTER_TO_INT (str) | 0x1);
 }
 
+static guint n_string_objects;
+
+static inline GtkStringObject *
+steal_nearby_orphan (GtkStringList *self,
+                     guint          position)
+{
+  gpointer item;
+  guint i;
+
+  for (i = 0; i < 3; i++)
+    {
+      if (position == 0)
+        break;
+
+      position--;
+
+      item = g_ptr_array_index (self->items, position);
+
+      if (!IS_STRING (item) &&
+          G_OBJECT (item)->ref_count == 1)
+        {
+          GtkStringObject *obj = GTK_STRING_OBJECT (item);
+          gpointer str = MAKE_STRING (obj->string);
+          obj->string = NULL;
+          g_ptr_array_index (self->items, position) = str;
+          return obj;
+        }
+    }
+
+  return NULL;
+}
+
 static gpointer
 gtk_string_list_get_item (GListModel *list,
                           guint       position)
@@ -219,7 +251,15 @@ gtk_string_list_get_item (GListModel *list,
 
   if (IS_STRING (item))
     {
-      GtkStringObject *obj = g_object_new (GTK_TYPE_STRING_OBJECT, NULL);
+      GtkStringObject *obj;
+
+      obj = steal_nearby_orphan (self, position);
+      if (!obj)
+        {
+          obj = g_object_new (GTK_TYPE_STRING_OBJECT, NULL);
+          n_string_objects++;
+        }
+      //g_print ("%u string objects\n", n_string_objects);
       obj->string = (char *)TO_STRING (item);
       g_assert (!IS_STRING (obj));
       g_ptr_array_index (self->items, position) = obj;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]