summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Garnacho <carlosg@gnome.org>2019-11-13 19:37:00 +0100
committerChristoph Reiter <reiter.christoph@gmail.com>2019-11-14 16:23:39 +0000
commit441926c7d5da515c865a3bc4a3d1d996a6b64b67 (patch)
tree6d30bf6876462ed2375d9d3510c5cbc795c8556f
parent01701e40099a23cf2f8378361fc4bf85693e6da5 (diff)
downloadgobject-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.c15
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;
+ }
}
/**