After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 639634 - [GTree] provide more lifecycle control when inserting existing keys
[GTree] provide more lifecycle control when inserting existing keys
Status: RESOLVED OBSOLETE
Product: glib
Classification: Platform
Component: general
2.27.x
Other All
: Normal enhancement
: ---
Assigned To: gtkdev
gtkdev
Depends on:
Blocks:
 
 
Reported: 2011-01-15 23:57 UTC by Jody Goldberg
Modified: 2018-05-24 12:57 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
GTree api extension (6.06 KB, patch)
2011-01-15 23:57 UTC, Jody Goldberg
none Details | Review
an alternative patch (15.99 KB, patch)
2011-02-16 05:05 UTC, Matthias Clasen
none Details | Review

Description Jody Goldberg 2011-01-15 23:57:44 UTC
Created attachment 178415 [details] [review]
GTree api extension

Current GTree insert/replace api provides control over whether an existing key dominates.   Unfortunately it always uses the new value.   Nor does it provide detail on whether the insertion was for a new or existing key.  A valid work around is to do a lookup prior to insertion but that is a wasted operation.   The proposed patch provides a new publicly exposed api to the existing insert/replace wrappers with a extra capabilities.
Comment 1 Matthias Clasen 2011-01-18 03:17:28 UTC
I must admit that I don't see any point in an insertion operation that does not replace the value. And returning pointers to destroyed values doesn't seem like a good idea to me, either.
Comment 2 Jody Goldberg 2011-01-18 18:33:13 UTC
accumulating unique items is a common operation and it is more useful to phrase it as

insert_extended (... dont_override)

rather than doing a dual lookup in the non-existent case

if (NULL == lookup ()
   insert ()

The case of returning pointers to destroyed values is indeed a poor api choice and I would not expect it to be used when destroy functions are supplied.  However, it seemed preferable to have a single api addition rather than multiple methods.   It is useful to do an insertion that returns the old values if there are no destruction functions.
Comment 3 Matthias Clasen 2011-02-16 05:05:59 UTC
Created attachment 180961 [details] [review]
an alternative patch

Here is my variation on this topic. For good measure, I've thrown in the corresponding hash table api as well.

/**
 * g_tree_probe:
 * @tree: a #GTree
 * @key: the key to insert or find
 * @found_key: (allow-none): return location for the key in the tree,
 *     or %NULL
 * @found_value: (allow-none): return location for the value in the tree,
 *     or %NULL
 *
 * Looks up @key in @tree.
 *
 * If @key is present in @tree, @found_key and @found_value are
 * set to point to the locations of the found key-value pair
 * matching @key.
 *
 * If @key is not yet present in @tree, it is inserted with a value
 * of %NULL and @found_key and @found_value are set to point to the
 * locations for the newly inserted key-value pair.
 *
 * The returned @found_key and @found_value can be used to modify the
 * in-tree key-value pair, but care must be taken to preserve the
 * ordering of the key wrt. to other items that are present in the
 * tree.
 *
 * Returns: %TRUE if and existing item matching @key was found in @tree
 *
 * Since: 2.30
 */
gboolean g_tree_probe (GTree     *tree,
                       gpointer   key,
                       gpointer **found_key,
                       gpointer **found_value)


Those out parameters are perhaps a bit ugly. An alternative would be to define
a sruct 
GPair {
  gpointer key;
  gpointer value;
}

and change the signature to

GPair *g_tree_probe (GTree *tree, gpointer key);
GPair *g_hash_table_probe (GHashTable *hash, gpointer key);

That looks a bit more elegant, at the cost of an extra struct type. To check if the pair was already in the tree, you can then check if pair->key == key.

Would this kind of API work for you ?
Comment 4 Matthias Clasen 2011-02-16 13:36:28 UTC
I guess a more principled api additions would be tree iters, along the lines of

void     g_tree_iter_init      (GTreeIter *iter,
                                GTree     *tree);
gboolean g_tree_iter_previous  (GTreeIter *iter,
                                gpointer  *key,
                                gpointer  *value);
gboolean g_tree_iter_next      (GTreeIter *iter,
                                gpointer  *key,
                                gpointer  *value);
void     g_tree_iter_remove    (GTreeIter *iter);
void     g_tree_iter_steal     (GTreeIter *iter);
gint     g_tree_iter_find      (GTreeIter *iter,
                                gpointer   key,
                                gpointer  *found_key,
                                gpointer  *found_value);
void     g_tree_iter_insert    (GTreeIter *iter,
                                gpointer   key,
                                gpointer   value);
Comment 5 GNOME Infrastructure Team 2018-05-24 12:57:26 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to GNOME's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/glib/issues/388.