summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2019-06-29 04:59:49 +0000
committerEmmanuele Bassi <ebassi@gnome.org>2019-07-01 00:10:11 +0100
commit511e2b435e308cfb162f598ff67e5be319026eac (patch)
treead77014058de187c096dbe8b552c6f2680338945
parent3f36340921c5cbaeacf1818e8d4b2934ab87e567 (diff)
downloadgtk+-511e2b435e308cfb162f598ff67e5be319026eac.tar.gz
constraints: Use better data structures
Use a GSequence for GtkVariableSet, to avoid quadratic behavior.
-rw-r--r--gtk/gtkconstraintexpression.c61
1 files changed, 28 insertions, 33 deletions
diff --git a/gtk/gtkconstraintexpression.c b/gtk/gtkconstraintexpression.c
index eff63679ec..382d9514b9 100644
--- a/gtk/gtkconstraintexpression.c
+++ b/gtk/gtkconstraintexpression.c
@@ -371,11 +371,8 @@ gtk_constraint_variable_is_dummy (const GtkConstraintVariable *variable)
* A set of variables.
*/
struct _GtkConstraintVariableSet {
- /* HashSet<Variable>, owns a reference */
- GHashTable *set;
-
- /* List<Variable>, used for iterating */
- GList *ordered_set;
+ /* List<Variable>, owns a reference */
+ GSequence *set;
/* Age of the set, to guard against mutations while iterating */
gint64 age;
@@ -392,8 +389,7 @@ gtk_constraint_variable_set_free (GtkConstraintVariableSet *set)
{
g_return_if_fail (set != NULL);
- g_list_free (set->ordered_set);
- g_hash_table_unref (set->set);
+ g_sequence_free (set->set);
g_free (set);
}
@@ -410,10 +406,7 @@ gtk_constraint_variable_set_new (void)
{
GtkConstraintVariableSet *res = g_new (GtkConstraintVariableSet, 1);
- res->set = g_hash_table_new_full (NULL, NULL,
- (GDestroyNotify) gtk_constraint_variable_unref,
- NULL);
- res->ordered_set = NULL;
+ res->set = g_sequence_new ((GDestroyNotify) gtk_constraint_variable_unref);
res->age = 0;
@@ -422,7 +415,8 @@ gtk_constraint_variable_set_new (void)
static int
sort_by_variable_id (gconstpointer a,
- gconstpointer b)
+ gconstpointer b,
+ gpointer data)
{
const GtkConstraintVariable *va = a, *vb = b;
@@ -450,16 +444,17 @@ gboolean
gtk_constraint_variable_set_add (GtkConstraintVariableSet *set,
GtkConstraintVariable *variable)
{
- if (g_hash_table_contains (set->set, variable))
- return FALSE;
+ GSequenceIter *iter;
- g_hash_table_add (set->set, gtk_constraint_variable_ref (variable));
+ iter = g_sequence_search (set->set, variable, sort_by_variable_id, NULL);
+ if (!g_sequence_iter_is_end (iter))
+ {
+ GtkConstraintVariable *v = g_sequence_get (iter);
+ if (v->_id == variable->_id)
+ return FALSE;
+ }
- /* This is a tricky bit; the variables in the set must be ordered
- * not by insertion, but by the incremental id of each variable,
- * as that's the expected iteration order
- */
- set->ordered_set = g_list_insert_sorted (set->ordered_set, variable, sort_by_variable_id);
+ g_sequence_insert_before (iter, gtk_constraint_variable_ref (variable));
set->age += 1;
@@ -482,10 +477,12 @@ gboolean
gtk_constraint_variable_set_remove (GtkConstraintVariableSet *set,
GtkConstraintVariable *variable)
{
- if (g_hash_table_contains (set->set, variable))
+ GSequenceIter *iter;
+
+ iter = g_sequence_lookup (set->set, variable, sort_by_variable_id, NULL);
+ if (iter != NULL)
{
- set->ordered_set = g_list_remove (set->ordered_set, variable);
- g_hash_table_remove (set->set, variable);
+ g_sequence_remove (iter);
set->age += 1;
return TRUE;
@@ -505,7 +502,7 @@ gtk_constraint_variable_set_remove (GtkConstraintVariableSet *set,
int
gtk_constraint_variable_set_size (GtkConstraintVariableSet *set)
{
- return g_hash_table_size (set->set);
+ return g_sequence_get_length (set->set);
}
/*< private >
@@ -516,7 +513,7 @@ gtk_constraint_variable_set_size (GtkConstraintVariableSet *set)
/* Keep in sync with GtkConstraintVariableSetIter */
typedef struct {
GtkConstraintVariableSet *set;
- GList *current;
+ GSequenceIter *iter;
gint64 age;
} RealVariableSetIter;
@@ -539,7 +536,7 @@ gtk_constraint_variable_set_iter_init (GtkConstraintVariableSetIter *iter,
g_return_if_fail (set != NULL);
riter->set = set;
- riter->current = NULL;
+ riter->iter = g_sequence_get_begin_iter (set->set);
riter->age = set->age;
}
@@ -563,15 +560,13 @@ gtk_constraint_variable_set_iter_next (GtkConstraintVariableSetIter *iter,
g_assert (riter->age == riter->set->age);
- if (riter->current == NULL)
- riter->current = riter->set->ordered_set;
- else
- riter->current = riter->current->next;
+ if (g_sequence_iter_is_end (riter->iter))
+ return FALSE;
- if (riter->current != NULL)
- *variable_p = riter->current->data;
+ *variable_p = g_sequence_get (riter->iter);
+ riter->iter = g_sequence_iter_next (riter->iter);
- return riter->current != NULL;
+ return TRUE;
}
/*< private >