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.
Generalizing the above, maybe we could make something like:

    template<typename T>
    HashMemo {
        uint seed;
        uint hash;
        T value;
        HashMemo(const T &v) : seed(-1), hash(0), value(v) {}
    }

    template<typename T>
    uint qHash<HashMemo<T> >(const HashMemo<T> &mem, uint seed) {
        if (mem.seed != seed || mem.hash == 0) {
            mem.seed = seed;
            mem.hash = qHash(mem.value, mem.seed);
        }
        return mem.hash;
    }

and then use QHash<HashMemo<UidPair>, ... >