Closed Bug 1457728 Opened 6 years ago Closed 6 years ago

Support tri-state Comparator functions in nsTArray

Categories

(Core :: MFBT, enhancement)

enhancement
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla63
Tracking Status
firefox63 --- fixed

People

(Reporter: kmag, Assigned: kmag)

References

Details

Attachments

(1 file)

The comparator that nsTArray uses for sorting and binary search requires two separate comparisons for every element which isn't equal. While that probably doesn't matter much for pointer or int comparisons, it could add up to a lot of extra overhead for larger comparisons. In bug 1456035, for instance, I had to avoid it so that I wouldn't need an extra memcmp() call when binary searching.

We can solve this without much code chrun by auto-generating LessThan/Equals or tri-state Compare methods from the given comparator, depending on which is already present.

Although, now that I see bug 1443272, I'm thinking maybe it should use operator() rather than Compare().
Comment on attachment 8971832 [details]
Bug 1457728: Support tri-state comparators in nsTArray.

https://reviewboard.mozilla.org/r/240576/#review249668

Overall looks good, sorry this took a while to get to. A few questions / comments, so clearing review for now.

::: xpcom/ds/nsTArray.h:773
(Diff revision 1)
>    }
>  };
>  
>  namespace detail {
>  
> -template<class Item, class Comparator>
> +template <typename T, typename U, typename V = int>

Can you add comments about what's going on with these template methods?

::: xpcom/ds/nsTArray.h:776
(Diff revision 1)
>  namespace detail {
>  
> -template<class Item, class Comparator>
> -struct ItemComparatorEq
> +template <typename T, typename U, typename V = int>
> +struct IsCompareMethod : mozilla::FalseType {};
> +
> +template <typename T, typename U>

Do we really need `T`? It seems like that should always be an `int`.

::: xpcom/ds/nsTArray.h:780
(Diff revision 1)
> +
> +template <typename T, typename U>
> +struct IsCompareMethod<T, U, decltype(mozilla::DeclVal<T>()(mozilla::DeclVal<U>(), mozilla::DeclVal<U>()))>
> +  : mozilla::TrueType {};
> +
> +template <typename T, typename U, bool IsCompare = IsCompareMethod<T, U>::value>

Add a comment here that this is the version that uses a comparison function.

::: xpcom/ds/nsTArray.h:808
(Diff revision 1)
>    }
> +
> +  const T& mComparator;
>  };
>  
> -template<class Item, class Comparator>
> +template <typename T, typename U>

And a comment here that this is the specialization for using a comparator object.

::: xpcom/ds/nsTArray.h:1272
(Diff revision 1)
>      using mozilla::BinarySearchIf;
> -    typedef ::detail::ItemComparatorEq<Item, Comparator> Cmp;
> +    ::detail::CompareWrapper<Comparator, Item> comp(aComp);
>  
>      size_t index;
> -    bool found = BinarySearchIf(*this, 0, Length(), Cmp(aItem, aComp), &index);
> +    bool found = BinarySearchIf(*this, 0, Length(),
> +                                [&] (const elem_type& aElement) { return -comp.Compare(aElement, aItem); },

Can you document why you're negating here?

::: xpcom/tests/gtest/TestTArray2.cpp:1084
(Diff revision 1)
> +  {
> +    return aLeft < aRight;
> +  }
> +};
> +
> +TEST(TArray, test_comparator_objects) {

Thanks for adding tests!
Attachment #8971832 - Flags: review?(erahm)
Comment on attachment 8971832 [details]
Bug 1457728: Support tri-state comparators in nsTArray.

https://reviewboard.mozilla.org/r/240576/#review249668

> Do we really need `T`? It seems like that should always be an `int`.

Not sure what you mean. T is the type of the comparator function/class.

> Can you document why you're negating here?

Yeah.

I don't particularly like this, to be honest. I had to do this because some existing callers pass a different polymorphic type for aItem than the element type, and expect aElement to always be the first argument to LessThan().

I thought about just fixing those callers, but I took the easy option instead.
Comment on attachment 8971832 [details]
Bug 1457728: Support tri-state comparators in nsTArray.

https://reviewboard.mozilla.org/r/240576/#review262342

Thanks, looks good.
Attachment #8971832 - Flags: review?(erahm) → review+
Flags: needinfo?(kmaglione+bmo)
https://hg.mozilla.org/mozilla-central/rev/9aaee5070157
Status: NEW → RESOLVED
Closed: 6 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla63
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: