blob: c778df3405a291405e2b1712b58d7fe401cfb535 [file] [log] [blame]
// Copyright (c) 2020, 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.DexEncodedField;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.ProgramField;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Sets;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Predicate;
import java.util.stream.Stream;
public class ProgramFieldSet implements Iterable<ProgramField> {
private static final ProgramFieldSet EMPTY = new ProgramFieldSet(ImmutableMap.of());
private Map<DexField, ProgramField> backing;
private ProgramFieldSet(Map<DexField, ProgramField> backing) {
this.backing = backing;
}
public static ProgramFieldSet create() {
return new ProgramFieldSet(new IdentityHashMap<>());
}
public static ProgramFieldSet createConcurrent() {
return new ProgramFieldSet(new ConcurrentHashMap<>());
}
public static ProgramFieldSet empty() {
return EMPTY;
}
public boolean add(ProgramField field) {
ProgramField existing = backing.put(field.getReference(), field);
assert existing == null || existing.isStructurallyEqualTo(field);
return existing == null;
}
public void addAll(Iterable<ProgramField> fields) {
fields.forEach(this::add);
}
public void addAll(ProgramFieldSet fields) {
backing.putAll(fields.backing);
}
public boolean createAndAdd(DexProgramClass clazz, DexEncodedField definition) {
return add(new ProgramField(clazz, definition));
}
public boolean contains(DexEncodedField field) {
return backing.containsKey(field.getReference());
}
public boolean contains(ProgramField field) {
return backing.containsKey(field.getReference());
}
public void clear() {
backing.clear();
}
public boolean isEmpty() {
return backing.isEmpty();
}
@Override
public Iterator<ProgramField> iterator() {
return backing.values().iterator();
}
public boolean remove(DexField field) {
ProgramField existing = backing.remove(field);
return existing != null;
}
public boolean remove(DexEncodedField field) {
return remove(field.getReference());
}
public boolean remove(ProgramField field) {
return remove(field.getReference());
}
public boolean removeIf(Predicate<? super ProgramField> predicate) {
return backing.values().removeIf(predicate);
}
public int size() {
return backing.size();
}
public Stream<ProgramField> stream() {
return backing.values().stream();
}
public Set<DexEncodedField> toDefinitionSet() {
assert backing instanceof IdentityHashMap;
Set<DexEncodedField> definitions = Sets.newIdentityHashSet();
forEach(field -> definitions.add(field.getDefinition()));
return definitions;
}
}