Speed up ContactResolver by removing looping

The previous contactresolver was O(E*A) where E was the number of commhistory events and A was the number of addresses in the contacts db. (Technically something like O(E*A*n) where n is the average number of addresses per contact, but n is usually a small number)

I rewrote its core loop so that it canonicalizes the addresses, which allows hashtable lookups instead of list scans. From the commit message:

- Canonicalize requested addresses so that they can be looked up in hashes (using a canonicalization that matches what addressMatchesList used to do)

- Fill in all the resolved contacts when the events list is sent out, instead of looping over all the events whenever something changes.

- Side effect: having lots of duplicate addresses in the events list no longer slows down contactUpdated processing

The benefit is visible in voicecall-ui startup, which in tests on iamer's phone showed improvement from 40s of cpu time to 12s of cpu time. He has about 8000 commhistory events and about 500 contacts.
Actually, maybe we could make UidPair a struct and add a cached hash value member, which is returned from a qHash<UidPair>() overload?