diff options
author | Daniel Playfair Cal <daniel.playfair.cal@gmail.com> | 2017-12-11 17:11:14 +1100 |
---|---|---|
committer | Daniel Playfair Cal <daniel.playfair.cal@gmail.com> | 2019-12-29 20:06:20 +1100 |
commit | 5974d2d08b2d4dffffd348d240aba8afb9dfeb35 (patch) | |
tree | 868c255ef024abe4527b647a9baddd74ad39d1e4 /common | |
parent | 7ad890fb7a2ec90a777a756a1fa20a615ec7245e (diff) | |
download | dconf-5974d2d08b2d4dffffd348d240aba8afb9dfeb35.tar.gz |
Service: filter changesets when performing writes such that changed events are only emitted if new values differ from existing values
Diffstat (limited to 'common')
-rw-r--r-- | common/dconf-changeset.c | 70 | ||||
-rw-r--r-- | common/dconf-changeset.h | 3 |
2 files changed, 58 insertions, 15 deletions
diff --git a/common/dconf-changeset.c b/common/dconf-changeset.c index c80c88c..705fec9 100644 --- a/common/dconf-changeset.c +++ b/common/dconf-changeset.c @@ -772,6 +772,57 @@ dconf_changeset_change (DConfChangeset *changeset, } /** + * dconf_changeset_filter_changes: + * @base: a database mode changeset + * @changes: a changeset + * + * Produces a changeset that contains all the changes in @changes that + * are not already present in @base + * + * If there are no such changes, %NULL is returned + * + * Applying the result to @base will yield the same result as applying + * @changes to @base + * + * Returns: (transfer full) (nullable): the minimal changes, or %NULL + * + * Since: 0.35.1 + */ +DConfChangeset * +dconf_changeset_filter_changes (DConfChangeset *base, + DConfChangeset *changes) +{ + DConfChangeset *result = NULL; + GHashTableIter iter; + gpointer key, val; + + g_return_val_if_fail (base->is_database, NULL); + + /* We create the list of changes by iterating the 'changes' changeset + * and noting any keys that are not in the 'base' changeset or do not + * have the same value in the 'base' changeset + * + * Note: because 'base' is a database changeset we don't have to + * worry about it containing NULL values (dir resets). + */ + g_hash_table_iter_init (&iter, changes->table); + while (g_hash_table_iter_next (&iter, &key, &val)) + { + GVariant *base_val = g_hash_table_lookup (base->table, key); + + if (base_val == NULL || !g_variant_equal (val, base_val)) + { + if (!result) + result = dconf_changeset_new (); + + dconf_changeset_set (result, key, val); + } + } + + return result; +} + +/** * dconf_changeset_diff: * @from: a database mode changeset * @to: a database mode changeset @@ -793,7 +844,7 @@ DConfChangeset * dconf_changeset_diff (DConfChangeset *from, DConfChangeset *to) { - DConfChangeset *changeset = NULL; + DConfChangeset *changeset; GHashTableIter iter; gpointer key, val; @@ -806,8 +857,8 @@ dconf_changeset_diff (DConfChangeset *from, * * We create our list of changes in two steps: * - * - iterate the 'to' changeset and note any keys that do not have - * the same value in the 'from' changeset + * - call dconf_changeset_filter_changes to find values from 'to' + * which are not present in 'from' or hold different values to 'to' * * - iterate the 'from' changeset and note any keys not present in * the 'to' changeset, recording resets for them @@ -817,19 +868,8 @@ dconf_changeset_diff (DConfChangeset *from, * Note: because 'from' and 'to' are database changesets we don't have * to worry about seeing NULL values or dirs. */ - g_hash_table_iter_init (&iter, to->table); - while (g_hash_table_iter_next (&iter, &key, &val)) - { - GVariant *from_val = g_hash_table_lookup (from->table, key); - if (from_val == NULL || !g_variant_equal (val, from_val)) - { - if (!changeset) - changeset = dconf_changeset_new (); - - dconf_changeset_set (changeset, key, val); - } - } + changeset = dconf_changeset_filter_changes (from, to); g_hash_table_iter_init (&iter, from->table); while (g_hash_table_iter_next (&iter, &key, &val)) diff --git a/common/dconf-changeset.h b/common/dconf-changeset.h index b0ce450..6fe60f2 100644 --- a/common/dconf-changeset.h +++ b/common/dconf-changeset.h @@ -65,6 +65,9 @@ DConfChangeset * dconf_changeset_deserialise (GVarian void dconf_changeset_change (DConfChangeset *changeset, DConfChangeset *changes); +DConfChangeset * dconf_changeset_filter_changes (DConfChangeset *from, + DConfChangeset *changes); + DConfChangeset * dconf_changeset_diff (DConfChangeset *from, DConfChangeset *to); |