def aggregator(data):
    """
    FLATTEN CC LISTS OVER TIME BY BUG
    MULTISET COUNTS THE NUMBER OF EMAIL AT BUG CREATION
    NEGATIVE MEANS THERE WAS AN ADD WITHOUT A REMOVE (AND NOT IN CURRENT LIST)
    """
    for d in data:
        new_emails = Q.map2set(split_email(d.new_value), alias)
        old_emails = Q.map2set(split_email(d.old_value), alias)

        for e in new_emails | old_emails:
            details = aliases.get(e, Struct())
            aliases[e] = details

        agg = bugs.get(d.bug_id, Multiset(allow_negative=True))
        agg = agg - new_emails
        agg = agg + old_emails
        bugs[d.bug_id] = agg
def aggregator(data):
    """
    FLATTEN CC LISTS OVER TIME BY BUG
    MULTISET COUNTS THE NUMBER OF EMAIL AT BUG CREATION
    NEGATIVE MEANS THERE WAS AN ADD WITHOUT A REMOVE (AND NOT IN CURRENT LIST)
    """
    for d in data:
        new_emails = Q.map2set(split_email(d.new_value), alias)
        old_emails = Q.map2set(split_email(d.old_value), alias)

        for e in new_emails | old_emails:
            details = aliases.get(e, Struct())
            aliases[e] = details

        agg = bugs.get(d.bug_id, Multiset(allow_negative=True))
        agg = agg - new_emails
        agg = agg + old_emails
        bugs[d.bug_id] = agg