From 29c97fe780f3827282f4b677db61950ee19299a6 Mon Sep 17 00:00:00 2001 From: Vincent Penquerc'h Date: Thu, 27 Oct 2011 10:35:53 +0100 Subject: [PATCH] gstvalue: quicker test for substraction emptiness 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 | 8 ++----- gst/gstvalue.c | 61 +++++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 49 insertions(+), 20 deletions(-) diff --git a/gst/gststructure.c b/gst/gststructure.c index a254797..f06049c 100644 --- a/gst/gststructure.c +++ b/gst/gststructure.c @@ -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; } diff --git a/gst/gstvalue.c b/gst/gstvalue.c index eed6e02..19d7e5f 100644 --- a/gst/gstvalue.c +++ b/gst/gstvalue.c @@ -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; } -- 2.7.4