summaryrefslogtreecommitdiff
path: root/gtk/gtkallocatedbitmask.c
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2015-09-07 01:55:16 -0400
committerMatthias Clasen <mclasen@redhat.com>2015-09-07 02:02:07 -0400
commit7da1f8a1ce145f48b6299fd8be86a64389ff0b0d (patch)
treebbf87b0dd9662a11d885ef0e48061abf6b88fff7 /gtk/gtkallocatedbitmask.c
parent4dc47c37145509d63482f11a39ec0bab559421c1 (diff)
downloadgtk+-7da1f8a1ce145f48b6299fd8be86a64389ff0b0d.tar.gz
Speed up gtk_allocated_bit_mask_invert_range
It was showing up on profiles and has a comment asking for speed.
Diffstat (limited to 'gtk/gtkallocatedbitmask.c')
-rw-r--r--gtk/gtkallocatedbitmask.c27
1 files changed, 22 insertions, 5 deletions
diff --git a/gtk/gtkallocatedbitmask.c b/gtk/gtkallocatedbitmask.c
index 2ebe0e14e2..0f4a8d9e6d 100644
--- a/gtk/gtkallocatedbitmask.c
+++ b/gtk/gtkallocatedbitmask.c
@@ -25,6 +25,7 @@
#define VALUE_SIZE_BITS (sizeof (VALUE_TYPE) * 8)
#define VALUE_BIT(idx) (((VALUE_TYPE) 1) << (idx))
+#define ALL_BITS G_MAXSIZE
struct _GtkBitmask {
gsize len;
@@ -224,7 +225,7 @@ _gtk_allocated_bitmask_subtract (GtkBitmask *mask,
return gtk_allocated_bitmask_shrink (mask);
}
-static void
+static inline void
gtk_allocated_bitmask_indexes (guint index_,
guint *array_index,
guint *bit_index)
@@ -286,17 +287,33 @@ _gtk_allocated_bitmask_invert_range (GtkBitmask *mask,
guint end)
{
guint i;
+ guint start_word, start_bit;
+ guint end_word, end_bit;
g_return_val_if_fail (mask != NULL, NULL);
g_return_val_if_fail (start < end, NULL);
mask = gtk_bitmask_ensure_allocated (mask);
- /* I CAN HAS SPEEDUP? */
- for (i = start; i < end; i++)
- mask = _gtk_allocated_bitmask_set (mask, i, !_gtk_allocated_bitmask_get (mask, i));
+ gtk_allocated_bitmask_indexes (start, &start_word, &start_bit);
+ gtk_allocated_bitmask_indexes (end - 1, &end_word, &end_bit);
- return mask;
+ if (end_word >= mask->len)
+ mask = gtk_allocated_bitmask_resize (mask, end_word + 1);
+
+ if (start_word == end_word)
+ {
+ mask->data[start_word] ^= (ALL_BITS >> (end_bit - start_bit)) << start_bit;
+ }
+ else
+ {
+ mask->data[start_word] ^= ALL_BITS << start_bit;
+ for (i = start_word + 1; i < end_word; i++)
+ mask->data[i] ^= ALL_BITS;
+ mask->data[end_word] ^= ALL_BITS >> (VALUE_SIZE_BITS - end_bit);
+ }
+
+ return gtk_allocated_bitmask_shrink (mask);
}
gboolean