[gobject-introspection/wip/carlosg/cache-misses: 2/2] girepository: Also store GType cache misses



commit 441926c7d5da515c865a3bc4a3d1d996a6b64b67
Author: Carlos Garnacho <carlosg gnome org>
Date:   Wed Nov 13 19:37:00 2019 +0100

    girepository: Also store GType cache misses
    
    There are notably 4 classes of GTypes where a girepository lookup
    might fail:
    - GTypes from private interfaces in public objects (eg. MetaCullable in
      mutter)
    - GTypes for private base objects with public interfaces (eg. GLocalFile
      in GLib)
    - GTypes registered from the language, and presumably not coming from the
      GIR
    - GTypes of objects/interfaces that we didn't load a typelib for
    
    It is moot to look for those over and over again, and a full lookup can
    be taxing if looking up for a method/property on objects with those
    characteristics.
    
    It seems we can cache the misses too, so next lookups are just as quick
    as an introspected GType. The cache is invalidated after loading new
    typelibs, in case some of the previously missed GTypes is now properly
    introspected.

 girepository/girepository.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)
---
diff --git a/girepository/girepository.c b/girepository/girepository.c
index fd668c5a..b7948d61 100644
--- a/girepository/girepository.c
+++ b/girepository/girepository.c
@@ -81,6 +81,7 @@ struct _GIRepositoryPrivate
   GHashTable *info_by_gtype; /* GType -> GIBaseInfo */
   GHashTable *info_by_error_domain; /* GQuark -> GIBaseInfo */
   GHashTable *interfaces_for_gtype; /* GType -> GTypeInterfaceCache */
+  GHashTable *unknown_gtypes; /* hashset of GType */
 };
 
 G_DEFINE_TYPE_WITH_CODE (GIRepository, g_irepository, G_TYPE_OBJECT, G_ADD_PRIVATE (GIRepository));
@@ -144,6 +145,7 @@ g_irepository_init (GIRepository *repository)
     = g_hash_table_new_full (g_direct_hash, g_direct_equal,
                              (GDestroyNotify) NULL,
                              (GDestroyNotify) gtype_interface_cache_free);
+  repository->priv->unknown_gtypes = g_hash_table_new (NULL, NULL);
 }
 
 static void
@@ -156,6 +158,7 @@ g_irepository_finalize (GObject *object)
   g_hash_table_destroy (repository->priv->info_by_gtype);
   g_hash_table_destroy (repository->priv->info_by_error_domain);
   g_hash_table_destroy (repository->priv->interfaces_for_gtype);
+  g_hash_table_destroy (repository->priv->unknown_gtypes);
 
   (* G_OBJECT_CLASS (g_irepository_parent_class)->finalize) (G_OBJECT (repository));
 }
@@ -439,6 +442,9 @@ register_internal (GIRepository *repository,
       g_hash_table_insert (repository->priv->typelibs, key, (void *)typelib);
     }
 
+  /* These types might be resolved now, clear the cache */
+  g_hash_table_remove_all (repository->priv->unknown_gtypes);
+
   return namespace;
 }
 
@@ -814,6 +820,9 @@ g_irepository_find_by_gtype (GIRepository *repository,
   if (cached != NULL)
     return g_base_info_ref (cached);
 
+  if (g_hash_table_contains (repository->priv->unknown_gtypes, (gpointer)gtype))
+    return NULL;
+
   data.gtype_name = g_type_name (gtype);
   data.result_typelib = NULL;
 
@@ -849,7 +858,11 @@ g_irepository_find_by_gtype (GIRepository *repository,
                           g_base_info_ref (cached));
       return cached;
     }
-  return NULL;
+  else
+    {
+      g_hash_table_add (repository->priv->unknown_gtypes, (gpointer) gtype);
+      return NULL;
+    }
 }
 
 /**


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