diff options
author | Carlos Garnacho <carlosg@gnome.org> | 2019-11-13 19:37:00 +0100 |
---|---|---|
committer | Christoph Reiter <reiter.christoph@gmail.com> | 2019-11-14 16:23:39 +0000 |
commit | 441926c7d5da515c865a3bc4a3d1d996a6b64b67 (patch) | |
tree | 6d30bf6876462ed2375d9d3510c5cbc795c8556f | |
parent | 01701e40099a23cf2f8378361fc4bf85693e6da5 (diff) | |
download | gobject-introspection-441926c7d5da515c865a3bc4a3d1d996a6b64b67.tar.gz |
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.
-rw-r--r-- | girepository/girepository.c | 15 |
1 files changed, 14 insertions, 1 deletions
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; + } } /** |