| // Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| package com.android.tools.r8.utils.collections; |
| |
| import com.android.tools.r8.graph.ProgramDerivedContext; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.IdentityHashMap; |
| import java.util.Iterator; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.function.Function; |
| |
| public class IdentityHashSetFromMap<K, V> implements Set<V> { |
| |
| private final Map<K, V> backing = new IdentityHashMap<>(); |
| private final Function<V, K> valueToKeyMapping; |
| |
| public IdentityHashSetFromMap(Function<V, K> valueToKeyMapping) { |
| this.valueToKeyMapping = valueToKeyMapping; |
| } |
| |
| public static Set<ProgramDerivedContext> newProgramDerivedContextSet() { |
| return new IdentityHashSetFromMap<>(context -> context.getContext().getReference()); |
| } |
| |
| @Override |
| public int size() { |
| return backing.size(); |
| } |
| |
| @Override |
| public boolean isEmpty() { |
| return backing.isEmpty(); |
| } |
| |
| @SuppressWarnings("unchecked") |
| @Override |
| public boolean contains(Object o) { |
| return backing.containsKey(valueToKeyMapping.apply((V) o)); |
| } |
| |
| @Override |
| public Iterator<V> iterator() { |
| return backing.values().iterator(); |
| } |
| |
| @Override |
| public Object[] toArray() { |
| return backing.values().toArray(); |
| } |
| |
| @Override |
| public <T> T[] toArray(T[] ts) { |
| return backing.values().toArray(ts); |
| } |
| |
| @Override |
| public boolean add(V v) { |
| return backing.put(valueToKeyMapping.apply(v), v) == null; |
| } |
| |
| @SuppressWarnings("unchecked") |
| @Override |
| public boolean remove(Object o) { |
| return backing.remove(valueToKeyMapping.apply((V) o)) != null; |
| } |
| |
| @Override |
| public boolean containsAll(Collection<?> collection) { |
| return backing.values().containsAll(collection); |
| } |
| |
| @Override |
| public boolean addAll(Collection<? extends V> collection) { |
| boolean changed = false; |
| for (V element : collection) { |
| changed |= add(element); |
| } |
| return changed; |
| } |
| |
| @SuppressWarnings("unchecked") |
| @Override |
| public boolean retainAll(Collection<?> collection) { |
| Collection<Object> found = new ArrayList<>(collection.size()); |
| for (Object element : collection) { |
| if (contains(element)) { |
| found.add(element); |
| } |
| } |
| if (found.size() < size()) { |
| clear(); |
| addAll((Collection<V>) found); |
| return true; |
| } |
| return false; |
| } |
| |
| @Override |
| public boolean removeAll(Collection<?> collection) { |
| boolean changed = false; |
| for (Object element : collection) { |
| changed |= remove(element); |
| } |
| return changed; |
| } |
| |
| @Override |
| public void clear() { |
| backing.clear(); |
| } |
| } |