This is an archive of the discontinued LLVM Phabricator instance.

[ADT] Add initializer_list constructor, equality tests for DenseMap/DenseSet.
ClosedPublic

Authored by lhames on Oct 13 2018, 3:29 PM.

Details

Summary

Adds an initializer_list constructor to DenseMap and fixes a bug in the
initializer_list constructor for DenseSet (it previously crashed on
initializer_lists whose lengths were not a power of two).

Also adds equality and inequality operators for DenseMap and DenseSet.

These changes make it easier to migrate existing code that uses std::map and
std::set (which support initializer_list construction and equality comparison)
to DenseMap and DenseSet.

Diff Detail

Repository
rL LLVM

Event Timeline

lhames created this revision.Oct 13 2018, 3:29 PM

Might be good to separate this into three or four (five? maybe, given the change to the DenseSet initial capacity?) separate changes - but mostly the only interesting question for me is about the equality

include/llvm/ADT/DenseMap.h
656–659 ↗(On Diff #169581)

Is this guaranteed to work, given the lack of ordering guarantees? I think the order can depend on insertion order - so equivalent containers might have different iteration orders, perhaps?

lhames added inline comments.Oct 14 2018, 9:05 AM
include/llvm/ADT/DenseMap.h
656–659 ↗(On Diff #169581)

Good point. No -- this won't work.

This was mostly a convenience for unit tests, so dropping it (at the cost of some slightly more verbose unit tests) seems like the best solution.

lhames added inline comments.Oct 14 2018, 9:27 AM
include/llvm/ADT/DenseMap.h
656–659 ↗(On Diff #169581)

Alternatively they could be implemented by iterating over one structure and testing that the corresponding element is present in the other. In either case I think I'll want some extra comments for them, so I will break the equality tests out into a separate patch.

Broke out https://reviews.llvm.org/D53260 for the DenseSet bug fix.

dblaikie added inline comments.Oct 14 2018, 12:35 PM
include/llvm/ADT/DenseMap.h
656–659 ↗(On Diff #169581)

Yeah, sounds pretty reasonable to me.

Yeah, looks like the standard containers have similar complexity (amortized linear (since the lookups are amortized constant), worst case N^2 (if all the elements hash collide))

"Proportional to N calls to operator== on value_type, calls to the predicate returned by key_eq, and calls to the hasher returned by hash_function, in the average case, proportional to N2 in the worst case where N is the size of the container." - https://en.cppreference.com/w/cpp/container/unordered_set/operator_cmp

lhames updated this revision to Diff 169630.Oct 14 2018, 2:02 PM

Updated to remove the dependence on stable iteration order for operator== (on both DenseMap and DenseSet). Also adds some comments on performance.

I decided to leave the initializer_list constructor for DenseMap in this patch, as it simplifies unit testing: The equality operators are the easiest way to test that DenseMap construction behaved as expected and vice-versa.

dblaikie accepted this revision.Oct 15 2018, 7:59 AM

Looks good - thanks!

This revision is now accepted and ready to land.Oct 15 2018, 7:59 AM
lhames closed this revision.Oct 15 2018, 8:29 AM

Committed in r344522.