[gtk/action-muxer-speedup: 18/19] actionmuxer: Use an array for accels



commit ed92026632246d03e41e381ddaa3c3f4501725d0
Author: Matthias Clasen <mclasen redhat com>
Date:   Sun Jul 19 15:11:35 2020 -0400

    actionmuxer: Use an array for accels
    
    We have a lot of accels across all the muxers, but the vast
    majority has just one or two, so an array is going to be
    smaller and faster for this.

 gtk/gtkactionmuxer.c | 106 +++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 85 insertions(+), 21 deletions(-)
---
diff --git a/gtk/gtkactionmuxer.c b/gtk/gtkactionmuxer.c
index 7663e0d1a7..3c013507cb 100644
--- a/gtk/gtkactionmuxer.c
+++ b/gtk/gtkactionmuxer.c
@@ -31,6 +31,78 @@
 
 #include <string.h>
 
+typedef struct
+{
+  char *action_and_target;
+  char *accel;
+} GtkAccel;
+
+static void
+gtk_accel_clear (GtkAccel *accel)
+{
+  g_free (accel->action_and_target);
+  g_free (accel->accel);
+}
+
+#define GDK_ARRAY_NAME gtk_accels
+#define GDK_ARRAY_TYPE_NAME GtkAccels
+#define GDK_ARRAY_ELEMENT_TYPE GtkAccel
+#define GDK_ARRAY_FREE_FUNC gtk_accel_clear
+#define GDK_ARRAY_BY_VALUE 1
+#define GDK_ARRAY_PREALLOC 2
+#include "gdk/gdkarrayimpl.c"
+
+static guint
+gtk_accels_find (GtkAccels  *accels,
+                 const char *action_and_target)
+{
+  guint i;
+
+  for (i = 0; i < gtk_accels_get_size (accels); i++)
+    {
+      GtkAccel *accel = gtk_accels_index (accels, i);
+      if (strcmp (accel->action_and_target, action_and_target) == 0)
+        return i;
+    }
+
+  return G_MAXUINT;
+}
+
+static void
+gtk_accels_replace (GtkAccels  *accels,
+                    const char *action_and_target,
+                    const char *primary_accel)
+{
+  guint position;
+
+  position = gtk_accels_find (accels, action_and_target);
+  if (position < gtk_accels_get_size (accels))
+    {
+      GtkAccel *accel = gtk_accels_index (accels, position);
+      g_free (accel->accel);
+      accel->accel = g_strdup (primary_accel);
+    }
+  else
+    {
+      GtkAccel accel;
+
+      accel.action_and_target = g_strdup (action_and_target);
+      accel.accel = g_strdup (primary_accel);
+      gtk_accels_append (accels, &accel);
+    }
+}
+
+static void
+gtk_accels_remove (GtkAccels  *accels,
+                   const char *action_and_target)
+{
+  guint position;
+
+  position = gtk_accels_find (accels, action_and_target);
+  if (position < gtk_accels_get_size (accels))
+    gtk_accels_splice (accels, position, 1, NULL, 0);
+}
+
 /*< private >
  * SECTION:gtkactionmuxer
  * @short_description: Aggregate and monitor several action groups
@@ -67,13 +139,12 @@ typedef GObjectClass GtkActionMuxerClass;
 struct _GtkActionMuxer
 {
   GObject parent_instance;
+  GtkActionMuxer *parent;
+  GtkWidget *widget;
 
   GHashTable *observed_actions;
   GHashTable *groups;
-  GHashTable *primary_accels;
-  GtkActionMuxer *parent;
-
-  GtkWidget *widget;
+  GtkAccels primary_accels;
 
   GtkBitmask *widget_actions_disabled;
 };
@@ -944,8 +1015,8 @@ gtk_action_muxer_finalize (GObject *object)
     }
   if (muxer->groups)
     g_hash_table_unref (muxer->groups);
-  if (muxer->primary_accels)
-    g_hash_table_unref (muxer->primary_accels);
+
+  gtk_accels_clear (&muxer->primary_accels);
 
   _gtk_bitmask_free (muxer->widget_actions_disabled);
 
@@ -1276,16 +1347,13 @@ gtk_action_muxer_set_parent (GtkActionMuxer *muxer,
 
 void
 gtk_action_muxer_set_primary_accel (GtkActionMuxer *muxer,
-                                    const gchar    *action_and_target,
-                                    const gchar    *primary_accel)
+                                    const char     *action_and_target,
+                                    const char     *primary_accel)
 {
-  if (!muxer->primary_accels)
-    muxer->primary_accels = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
-
   if (primary_accel)
-    g_hash_table_insert (muxer->primary_accels, g_strdup (action_and_target), g_strdup (primary_accel));
+    gtk_accels_replace (&muxer->primary_accels, action_and_target, primary_accel);
   else
-    g_hash_table_remove (muxer->primary_accels, action_and_target);
+    gtk_accels_remove (&muxer->primary_accels, action_and_target);
 
   gtk_action_muxer_primary_accel_changed (muxer, NULL, action_and_target);
 }
@@ -1294,15 +1362,11 @@ const gchar *
 gtk_action_muxer_get_primary_accel (GtkActionMuxer *muxer,
                                     const gchar    *action_and_target)
 {
-  if (muxer->primary_accels)
-    {
-      const gchar *primary_accel;
+   guint position;
 
-      primary_accel = g_hash_table_lookup (muxer->primary_accels, action_and_target);
-
-      if (primary_accel)
-        return primary_accel;
-    }
+   position = gtk_accels_find (&muxer->primary_accels, action_and_target);
+   if (position < G_MAXUINT)
+     return gtk_accels_index (&muxer->primary_accels, position)->accel;
 
   if (!muxer->parent)
     return NULL;


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