Merge branch 'wip/baedert/gparam' into 'master'

More small GKeyFile performance improvements

See merge request GNOME/glib!1832
This commit is contained in:
Sebastian Dröge 2021-01-04 08:46:41 +00:00
commit 9a7ca661a3
5 changed files with 146 additions and 120 deletions

View File

@ -477,9 +477,7 @@ g_io_modules_scan_all_in_directory_with_scope (const char *dirname,
filename = g_build_filename (dirname, "giomodule.cache", NULL); filename = g_build_filename (dirname, "giomodule.cache", NULL);
cache = g_hash_table_new_full (g_str_hash, g_str_equal, cache = NULL;
g_free, (GDestroyNotify)g_strfreev);
cache_time = 0; cache_time = 0;
if (g_stat (filename, &statbuf) == 0 && if (g_stat (filename, &statbuf) == 0 &&
g_file_get_contents (filename, &data, NULL, NULL)) g_file_get_contents (filename, &data, NULL, NULL))
@ -523,6 +521,10 @@ g_io_modules_scan_all_in_directory_with_scope (const char *dirname,
while (g_ascii_isspace (*colon)) while (g_ascii_isspace (*colon))
colon++; colon++;
if (G_UNLIKELY (!cache))
cache = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, (GDestroyNotify)g_strfreev);
extension_points = g_strsplit (colon, ",", -1); extension_points = g_strsplit (colon, ",", -1);
g_hash_table_insert (cache, file, extension_points); g_hash_table_insert (cache, file, extension_points);
} }
@ -536,13 +538,15 @@ g_io_modules_scan_all_in_directory_with_scope (const char *dirname,
GIOExtensionPoint *extension_point; GIOExtensionPoint *extension_point;
GIOModule *module; GIOModule *module;
gchar *path; gchar *path;
char **extension_points; char **extension_points = NULL;
int i; int i;
path = g_build_filename (dirname, name, NULL); path = g_build_filename (dirname, name, NULL);
module = g_io_module_new (path); module = g_io_module_new (path);
extension_points = g_hash_table_lookup (cache, name); if (cache)
extension_points = g_hash_table_lookup (cache, name);
if (extension_points != NULL && if (extension_points != NULL &&
g_stat (path, &statbuf) == 0 && g_stat (path, &statbuf) == 0 &&
statbuf.st_ctime <= cache_time) statbuf.st_ctime <= cache_time)
@ -577,7 +581,8 @@ g_io_modules_scan_all_in_directory_with_scope (const char *dirname,
g_dir_close (dir); g_dir_close (dir);
g_hash_table_destroy (cache); if (cache)
g_hash_table_destroy (cache);
g_free (filename); g_free (filename);
} }

View File

@ -929,9 +929,10 @@ g_resource_enumerate_children (GResource *resource,
if (*path == 0) if (*path == 0)
{ {
g_set_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND, if (error)
_("The resource at “%s” does not exist"), g_set_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND,
path); _("The resource at “%s” does not exist"),
path);
return NULL; return NULL;
} }
@ -968,9 +969,10 @@ g_resource_enumerate_children (GResource *resource,
if (children == NULL) if (children == NULL)
{ {
g_set_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND, if (error)
_("The resource at “%s” does not exist"), g_set_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND,
path); _("The resource at “%s” does not exist"),
path);
return NULL; return NULL;
} }
@ -1237,9 +1239,10 @@ g_resources_enumerate_children (const gchar *path,
if (hash == NULL) if (hash == NULL)
{ {
g_set_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND, if (error)
_("The resource at “%s” does not exist"), g_set_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND,
path); _("The resource at “%s” does not exist"),
path);
return NULL; return NULL;
} }
else else

View File

@ -897,10 +897,12 @@ get_contents_posix (const gchar *filename,
if (fd < 0) if (fd < 0)
{ {
int saved_errno = errno; int saved_errno = errno;
set_file_error (error,
filename, if (error)
_("Failed to open file “%s”: %s"), set_file_error (error,
saved_errno); filename,
_("Failed to open file “%s”: %s"),
saved_errno);
return FALSE; return FALSE;
} }
@ -909,10 +911,11 @@ get_contents_posix (const gchar *filename,
if (fstat (fd, &stat_buf) < 0) if (fstat (fd, &stat_buf) < 0)
{ {
int saved_errno = errno; int saved_errno = errno;
set_file_error (error, if (error)
filename, set_file_error (error,
_("Failed to get attributes of file “%s”: fstat() failed: %s"), filename,
saved_errno); _("Failed to get attributes of file “%s”: fstat() failed: %s"),
saved_errno);
close (fd); close (fd);
return FALSE; return FALSE;
@ -939,10 +942,11 @@ get_contents_posix (const gchar *filename,
if (f == NULL) if (f == NULL)
{ {
int saved_errno = errno; int saved_errno = errno;
set_file_error (error, if (error)
filename, set_file_error (error,
_("Failed to open file “%s”: fdopen() failed: %s"), filename,
saved_errno); _("Failed to open file “%s”: fdopen() failed: %s"),
saved_errno);
return FALSE; return FALSE;
} }
@ -969,10 +973,11 @@ get_contents_win32 (const gchar *filename,
if (f == NULL) if (f == NULL)
{ {
int saved_errno = errno; int saved_errno = errno;
set_file_error (error, if (error)
filename, set_file_error (error,
_("Failed to open file “%s”: %s"), filename,
saved_errno); _("Failed to open file “%s”: %s"),
saved_errno);
return FALSE; return FALSE;
} }
@ -1165,9 +1170,10 @@ write_to_file (const gchar *contents,
if (saved_errno == EINTR) if (saved_errno == EINTR)
continue; continue;
set_file_error (err, if (err)
dest_file, _("Failed to write file “%s”: write() failed: %s"), set_file_error (err,
saved_errno); dest_file, _("Failed to write file “%s”: write() failed: %s"),
saved_errno);
close (fd); close (fd);
return FALSE; return FALSE;
@ -1185,9 +1191,10 @@ write_to_file (const gchar *contents,
if (do_fsync && g_fsync (fd) != 0) if (do_fsync && g_fsync (fd) != 0)
{ {
int saved_errno = errno; int saved_errno = errno;
set_file_error (err, if (err)
dest_file, _("Failed to write file “%s”: fsync() failed: %s"), set_file_error (err,
saved_errno); dest_file, _("Failed to write file “%s”: fsync() failed: %s"),
saved_errno);
close (fd); close (fd);
return FALSE; return FALSE;
@ -1353,9 +1360,10 @@ g_file_set_contents_full (const gchar *filename,
if (fd == -1) if (fd == -1)
{ {
int saved_errno = errno; int saved_errno = errno;
set_file_error (error, if (error)
tmp_filename, _("Failed to create file “%s”: %s"), set_file_error (error,
saved_errno); tmp_filename, _("Failed to create file “%s”: %s"),
saved_errno);
retval = FALSE; retval = FALSE;
goto consistent_out; goto consistent_out;
} }
@ -1396,10 +1404,11 @@ g_file_set_contents_full (const gchar *filename,
if (g_unlink (filename) == -1) if (g_unlink (filename) == -1)
{ {
int saved_errno = errno; int saved_errno = errno;
set_file_error (error, if (error)
filename, set_file_error (error,
_("Existing file “%s” could not be removed: g_unlink() failed: %s"), filename,
saved_errno); _("Existing file “%s” could not be removed: g_unlink() failed: %s"),
saved_errno);
g_unlink (tmp_filename); g_unlink (tmp_filename);
retval = FALSE; retval = FALSE;
goto consistent_out; goto consistent_out;
@ -1462,9 +1471,10 @@ consistent_out:
mode, error); mode, error);
#endif /* O_NOFOLLOW */ #endif /* O_NOFOLLOW */
set_file_error (error, if (error)
filename, _("Failed to open file “%s”: %s"), set_file_error (error,
saved_errno); filename, _("Failed to open file “%s”: %s"),
saved_errno);
return FALSE; return FALSE;
} }
@ -1764,10 +1774,11 @@ g_get_tmp_name (const gchar *tmpl,
if (retval == -1) if (retval == -1)
{ {
int saved_errno = errno; int saved_errno = errno;
set_file_error (error, if (error)
fulltemplate, set_file_error (error,
_("Failed to create file “%s”: %s"), fulltemplate,
saved_errno); _("Failed to create file “%s”: %s"),
saved_errno);
g_free (fulltemplate); g_free (fulltemplate);
return -1; return -1;
} }
@ -2301,10 +2312,11 @@ g_file_read_link (const gchar *filename,
if (read_size < 0) if (read_size < 0)
{ {
int saved_errno = errno; int saved_errno = errno;
set_file_error (error, if (error)
filename, set_file_error (error,
_("Failed to read the symbolic link “%s”: %s"), filename,
saved_errno); _("Failed to read the symbolic link “%s”: %s"),
saved_errno);
g_free (buffer); g_free (buffer);
return NULL; return NULL;
} }
@ -2329,10 +2341,11 @@ g_file_read_link (const gchar *filename,
if (read_size < 0) if (read_size < 0)
{ {
int saved_errno = errno; int saved_errno = errno;
set_file_error (error, if (error)
filename, set_file_error (error,
_("Failed to read the symbolic link “%s”: %s"), filename,
saved_errno); _("Failed to read the symbolic link “%s”: %s"),
saved_errno);
return NULL; return NULL;
} }
else if (read_size == 0) else if (read_size == 0)

View File

@ -631,9 +631,9 @@ g_key_file_init (GKeyFile *key_file)
{ {
key_file->current_group = g_slice_new0 (GKeyFileGroup); key_file->current_group = g_slice_new0 (GKeyFileGroup);
key_file->groups = g_list_prepend (NULL, key_file->current_group); key_file->groups = g_list_prepend (NULL, key_file->current_group);
key_file->group_hash = g_hash_table_new (g_str_hash, g_str_equal); key_file->group_hash = NULL;
key_file->start_group = NULL; key_file->start_group = NULL;
key_file->parse_buffer = g_string_sized_new (128); key_file->parse_buffer = NULL;
key_file->list_separator = ';'; key_file->list_separator = ';';
key_file->flags = 0; key_file->flags = 0;
} }
@ -1473,6 +1473,9 @@ g_key_file_parse_data (GKeyFile *key_file,
parse_error = NULL; parse_error = NULL;
if (!key_file->parse_buffer)
key_file->parse_buffer = g_string_sized_new (128);
i = 0; i = 0;
while (i < length) while (i < length)
{ {
@ -1529,6 +1532,9 @@ g_key_file_flush_parse_buffer (GKeyFile *key_file,
g_return_if_fail (key_file != NULL); g_return_if_fail (key_file != NULL);
if (!key_file->parse_buffer)
return;
file_error = NULL; file_error = NULL;
if (key_file->parse_buffer->len > 0) if (key_file->parse_buffer->len > 0)
@ -3831,6 +3837,9 @@ g_key_file_add_group (GKeyFile *key_file,
if (key_file->start_group == NULL) if (key_file->start_group == NULL)
key_file->start_group = group; key_file->start_group = group;
if (!key_file->group_hash)
key_file->group_hash = g_hash_table_new (g_str_hash, g_str_equal);
g_hash_table_insert (key_file->group_hash, (gpointer)group->name, group); g_hash_table_insert (key_file->group_hash, (gpointer)group->name, group);
} }
@ -3883,7 +3892,10 @@ g_key_file_remove_group_node (GKeyFile *key_file,
group = (GKeyFileGroup *) group_node->data; group = (GKeyFileGroup *) group_node->data;
if (group->name) if (group->name)
g_hash_table_remove (key_file->group_hash, group->name); {
g_assert (key_file->group_hash);
g_hash_table_remove (key_file->group_hash, group->name);
}
/* If the current group gets deleted make the current group the last /* If the current group gets deleted make the current group the last
* added group. * added group.
@ -4089,6 +4101,9 @@ static GKeyFileGroup *
g_key_file_lookup_group (GKeyFile *key_file, g_key_file_lookup_group (GKeyFile *key_file,
const gchar *group_name) const gchar *group_name)
{ {
if (!key_file->group_hash)
return NULL;
return (GKeyFileGroup *)g_hash_table_lookup (key_file->group_hash, group_name); return (GKeyFileGroup *)g_hash_table_lookup (key_file->group_hash, group_name);
} }

View File

@ -1203,52 +1203,30 @@ pspec_compare_id (gconstpointer a,
return strcmp (pspec1->name, pspec2->name); return strcmp (pspec1->name, pspec2->name);
} }
static inline GSList* static inline gboolean
pspec_list_remove_overridden_and_redirected (GSList *plist, should_list_pspec (GParamSpec *pspec,
GHashTable *ht, GType owner_type,
GType owner_type, GHashTable *ht)
guint *n_p)
{ {
GSList *rlist = NULL; GParamSpec *found;
while (plist) /* Remove paramspecs that are redirected, and also paramspecs
* that have are overridden by non-redirected properties.
* The idea is to get the single paramspec for each name that
* best corresponds to what the application sees.
*/
if (g_param_spec_get_redirect_target (pspec))
return FALSE;
found = param_spec_ht_lookup (ht, pspec->name, owner_type, TRUE);
if (found != pspec)
{ {
GSList *tmp = plist->next; GParamSpec *redirect = g_param_spec_get_redirect_target (found);
GParamSpec *pspec = plist->data; if (redirect != pspec)
GParamSpec *found; return FALSE;
gboolean remove = FALSE;
/* Remove paramspecs that are redirected, and also paramspecs
* that have are overridden by non-redirected properties.
* The idea is to get the single paramspec for each name that
* best corresponds to what the application sees.
*/
if (g_param_spec_get_redirect_target (pspec))
remove = TRUE;
else
{
found = param_spec_ht_lookup (ht, pspec->name, owner_type, TRUE);
if (found != pspec)
{
GParamSpec *redirect = g_param_spec_get_redirect_target (found);
if (redirect != pspec)
remove = TRUE;
}
}
if (remove)
{
g_slist_free_1 (plist);
}
else
{
plist->next = rlist;
rlist = plist;
*n_p += 1;
}
plist = tmp;
} }
return rlist;
return TRUE;
} }
static void static void
@ -1260,18 +1238,23 @@ pool_depth_list (gpointer key,
gpointer *data = user_data; gpointer *data = user_data;
GSList **slists = data[0]; GSList **slists = data[0];
GType owner_type = (GType) data[1]; GType owner_type = (GType) data[1];
GHashTable *ht = data[2];
int *count = data[3];
if (g_type_is_a (owner_type, pspec->owner_type)) if (g_type_is_a (owner_type, pspec->owner_type) &&
should_list_pspec (pspec, owner_type, ht))
{ {
if (G_TYPE_IS_INTERFACE (pspec->owner_type)) if (G_TYPE_IS_INTERFACE (pspec->owner_type))
{ {
slists[0] = g_slist_prepend (slists[0], pspec); slists[0] = g_slist_prepend (slists[0], pspec);
*count = *count + 1;
} }
else else
{ {
guint d = g_type_depth (pspec->owner_type); guint d = g_type_depth (pspec->owner_type);
slists[d - 1] = g_slist_prepend (slists[d - 1], pspec); slists[d - 1] = g_slist_prepend (slists[d - 1], pspec);
*count = *count + 1;
} }
} }
} }
@ -1294,9 +1277,15 @@ pool_depth_list_for_interface (gpointer key,
gpointer *data = user_data; gpointer *data = user_data;
GSList **slists = data[0]; GSList **slists = data[0];
GType owner_type = (GType) data[1]; GType owner_type = (GType) data[1];
GHashTable *ht = data[2];
int *count = data[3];
if (pspec->owner_type == owner_type) if (pspec->owner_type == owner_type &&
slists[0] = g_slist_prepend (slists[0], pspec); should_list_pspec (pspec, owner_type, ht))
{
slists[0] = g_slist_prepend (slists[0], pspec);
*count = *count + 1;
}
} }
/** /**
@ -1319,29 +1308,29 @@ g_param_spec_pool_list (GParamSpecPool *pool,
{ {
GParamSpec **pspecs, **p; GParamSpec **pspecs, **p;
GSList **slists, *node; GSList **slists, *node;
gpointer data[2]; gpointer data[4];
guint d, i; guint d, i;
int n_pspecs = 0;
g_return_val_if_fail (pool != NULL, NULL); g_return_val_if_fail (pool != NULL, NULL);
g_return_val_if_fail (owner_type > 0, NULL); g_return_val_if_fail (owner_type > 0, NULL);
g_return_val_if_fail (n_pspecs_p != NULL, NULL); g_return_val_if_fail (n_pspecs_p != NULL, NULL);
g_mutex_lock (&pool->mutex); g_mutex_lock (&pool->mutex);
*n_pspecs_p = 0;
d = g_type_depth (owner_type); d = g_type_depth (owner_type);
slists = g_new0 (GSList*, d); slists = g_new0 (GSList*, d);
data[0] = slists; data[0] = slists;
data[1] = (gpointer) owner_type; data[1] = (gpointer) owner_type;
data[2] = pool->hash_table;
data[3] = &n_pspecs;
g_hash_table_foreach (pool->hash_table, g_hash_table_foreach (pool->hash_table,
G_TYPE_IS_INTERFACE (owner_type) ? G_TYPE_IS_INTERFACE (owner_type) ?
pool_depth_list_for_interface : pool_depth_list_for_interface :
pool_depth_list, pool_depth_list,
&data); &data);
for (i = 0; i < d; i++) pspecs = g_new (GParamSpec*, n_pspecs + 1);
slists[i] = pspec_list_remove_overridden_and_redirected (slists[i], pool->hash_table, owner_type, n_pspecs_p);
pspecs = g_new (GParamSpec*, *n_pspecs_p + 1);
p = pspecs; p = pspecs;
for (i = 0; i < d; i++) for (i = 0; i < d; i++)
{ {
@ -1354,10 +1343,11 @@ g_param_spec_pool_list (GParamSpecPool *pool,
g_free (slists); g_free (slists);
g_mutex_unlock (&pool->mutex); g_mutex_unlock (&pool->mutex);
*n_pspecs_p = n_pspecs;
return pspecs; return pspecs;
} }
/* --- auxiliary functions --- */ /* --- auxiliary functions --- */
typedef struct typedef struct
{ {