gstvalue: quicker test for substraction emptiness
authorVincent Penquerc'h <vincent.penquerch@collabora.co.uk>
Thu, 27 Oct 2011 09:35:53 +0000 (10:35 +0100)
committerVincent Penquerc'h <vincent.penquerch@collabora.co.uk>
Mon, 7 Nov 2011 15:16:52 +0000 (15:16 +0000)
When we do not care about the actual resulting set,
but only whether it is empty of not, we can skip a fair bit
of GValue juggling.

Add a function that does so, since we cannot just pass NULL
to the existing API as it may be part of the API contract.

https://bugzilla.gnome.org/show_bug.cgi?id=662777

gst/gststructure.c
gst/gstvalue.c

index a254797..f06049c 100644 (file)
@@ -3108,7 +3108,6 @@ gst_caps_structure_is_subset_field (GQuark field_id, const GValue * value,
     gpointer user_data)
 {
   GstStructure *superset = user_data;
-  GValue subtraction = { 0, };
   const GValue *other;
 
   if (!(other = gst_structure_id_get_value (superset, field_id)))
@@ -3139,13 +3138,10 @@ gst_caps_structure_is_subset_field (GQuark field_id, const GValue * value,
    *  subtractions needs to give en empty set.
    *  Both substractions are switched below, as it's faster that way.
    */
-  if (!gst_value_subtract (&subtraction, value, other)) {
-    if (gst_value_subtract (&subtraction, other, value)) {
-      g_value_unset (&subtraction);
+  if (!gst_value_subtract (NULL, value, other)) {
+    if (gst_value_subtract (NULL, other, value)) {
       return TRUE;
     }
-  } else {
-    g_value_unset (&subtraction);
   }
   return FALSE;
 }
index eed6e02..19d7e5f 100644 (file)
@@ -2860,7 +2860,8 @@ gst_value_subtract_int_int_range (GValue * dest, const GValue * minuend,
    * range */
   if (val < min || val > max) {
     /* and the result is the int */
-    gst_value_init_and_copy (dest, minuend);
+    if (dest)
+      gst_value_init_and_copy (dest, minuend);
     return TRUE;
   }
   return FALSE;
@@ -2889,6 +2890,9 @@ gst_value_create_new_range (GValue * dest, gint min1, gint max1, gint min2,
     return FALSE;
   }
 
+  if (!dest)
+    return TRUE;
+
   if (min1 < max1) {
     g_value_init (pv1, GST_TYPE_INT_RANGE);
     gst_value_set_int_range (pv1, min1, max1);
@@ -2924,7 +2928,8 @@ gst_value_subtract_int_range_int (GValue * dest, const GValue * minuend,
 
   /* value is outside of the range, return range unchanged */
   if (val < min || val > max) {
-    gst_value_init_and_copy (dest, minuend);
+    if (dest)
+      gst_value_init_and_copy (dest, minuend);
     return TRUE;
   } else {
     /* max must be MAXINT too as val <= max */
@@ -2937,7 +2942,8 @@ gst_value_subtract_int_range_int (GValue * dest, const GValue * minuend,
       min++;
       val++;
     }
-    gst_value_create_new_range (dest, min, val - 1, val + 1, max);
+    if (dest)
+      gst_value_create_new_range (dest, min, val - 1, val + 1, max);
   }
   return TRUE;
 }
@@ -2975,7 +2981,8 @@ gst_value_subtract_int64_int64_range (GValue * dest, const GValue * minuend,
    * range */
   if (val < min || val > max) {
     /* and the result is the int64 */
-    gst_value_init_and_copy (dest, minuend);
+    if (dest)
+      gst_value_init_and_copy (dest, minuend);
     return TRUE;
   }
   return FALSE;
@@ -3004,6 +3011,9 @@ gst_value_create_new_int64_range (GValue * dest, gint64 min1, gint64 max1,
     return FALSE;
   }
 
+  if (!dest)
+    return TRUE;
+
   if (min1 < max1) {
     g_value_init (pv1, GST_TYPE_INT64_RANGE);
     gst_value_set_int64_range (pv1, min1, max1);
@@ -3039,7 +3049,8 @@ gst_value_subtract_int64_range_int64 (GValue * dest, const GValue * minuend,
 
   /* value is outside of the range, return range unchanged */
   if (val < min || val > max) {
-    gst_value_init_and_copy (dest, minuend);
+    if (dest)
+      gst_value_init_and_copy (dest, minuend);
     return TRUE;
   } else {
     /* max must be MAXINT64 too as val <= max */
@@ -3052,7 +3063,8 @@ gst_value_subtract_int64_range_int64 (GValue * dest, const GValue * minuend,
       min++;
       val++;
     }
-    gst_value_create_new_int64_range (dest, min, val - 1, val + 1, max);
+    if (dest)
+      gst_value_create_new_int64_range (dest, min, val - 1, val + 1, max);
   }
   return TRUE;
 }
@@ -3089,7 +3101,8 @@ gst_value_subtract_double_double_range (GValue * dest, const GValue * minuend,
   gdouble val = g_value_get_double (minuend);
 
   if (val < min || val > max) {
-    gst_value_init_and_copy (dest, minuend);
+    if (dest)
+      gst_value_init_and_copy (dest, minuend);
     return TRUE;
   }
   return FALSE;
@@ -3101,7 +3114,8 @@ gst_value_subtract_double_range_double (GValue * dest, const GValue * minuend,
 {
   /* since we don't have open ranges, we cannot create a hole in
    * a double range. We return the original range */
-  gst_value_init_and_copy (dest, minuend);
+  if (dest)
+    gst_value_init_and_copy (dest, minuend);
   return TRUE;
 }
 
@@ -3132,6 +3146,9 @@ gst_value_subtract_double_range_double_range (GValue * dest,
     return FALSE;
   }
 
+  if (!dest)
+    return TRUE;
+
   if (min1 < max1) {
     g_value_init (pv1, GST_TYPE_DOUBLE_RANGE);
     gst_value_set_double_range (pv1, min1, max1);
@@ -3164,6 +3181,15 @@ gst_value_subtract_from_list (GValue * dest, const GValue * minuend,
   for (i = 0; i < size; i++) {
     const GValue *cur = VALUE_LIST_GET_VALUE (minuend, i);
 
+    /* quicker version when we can discard the result */
+    if (!dest) {
+      if (gst_value_subtract (NULL, cur, subtrahend)) {
+        ret = TRUE;
+        break;
+      }
+      continue;
+    }
+
     if (gst_value_subtract (&subtraction, cur, subtrahend)) {
       if (!ret) {
         gst_value_init_and_copy (dest, &subtraction);
@@ -3209,7 +3235,8 @@ gst_value_subtract_list (GValue * dest, const GValue * minuend,
       return FALSE;
     }
   }
-  gst_value_init_and_copy (dest, result);
+  if (dest)
+    gst_value_init_and_copy (dest, result);
   g_value_unset (result);
   return TRUE;
 }
@@ -3230,7 +3257,8 @@ gst_value_subtract_fraction_fraction_range (GValue * dest,
         gst_value_compare_with_func (minuend, max, compare) ==
         GST_VALUE_GREATER_THAN) {
       /* and the result is the value */
-      gst_value_init_and_copy (dest, minuend);
+      if (dest)
+        gst_value_init_and_copy (dest, minuend);
       return TRUE;
     }
   }
@@ -3243,7 +3271,8 @@ gst_value_subtract_fraction_range_fraction (GValue * dest,
 {
   /* since we don't have open ranges, we cannot create a hole in
    * a range. We return the original range */
-  gst_value_init_and_copy (dest, minuend);
+  if (dest)
+    gst_value_init_and_copy (dest, minuend);
   return TRUE;
 }
 
@@ -3294,6 +3323,9 @@ gst_value_subtract_fraction_range_fraction_range (GValue * dest,
     return FALSE;
   }
 
+  if (!dest)
+    return TRUE;
+
   if (cmp1 == GST_VALUE_LESS_THAN) {
     g_value_init (pv1, GST_TYPE_FRACTION_RANGE);
     gst_value_set_fraction_range (pv1, min1, max1);
@@ -3703,7 +3735,8 @@ gst_value_register_intersect_func (GType type1, GType type2,
 /**
  * gst_value_subtract:
  * @dest: (out caller-allocates): the destination value for the result if the
- *     subtraction is not empty
+ *     subtraction is not empty. May be NULL, in which case the resulting set
+ *     will not be computed, which can give a fair speedup.
  * @minuend: the value to subtract from
  * @subtrahend: the value to subtract
  *
@@ -3720,7 +3753,6 @@ gst_value_subtract (GValue * dest, const GValue * minuend,
   guint i, len;
   GType ltype, mtype, stype;
 
-  g_return_val_if_fail (dest != NULL, FALSE);
   g_return_val_if_fail (G_IS_VALUE (minuend), FALSE);
   g_return_val_if_fail (G_IS_VALUE (subtrahend), FALSE);
 
@@ -3744,7 +3776,8 @@ gst_value_subtract (GValue * dest, const GValue * minuend,
   }
 
   if (gst_value_compare (minuend, subtrahend) != GST_VALUE_EQUAL) {
-    gst_value_init_and_copy (dest, minuend);
+    if (dest)
+      gst_value_init_and_copy (dest, minuend);
     return TRUE;
   }