996 lines
35 KiB
Java
996 lines
35 KiB
Java
|
package com.google.common.collect;
|
||
|
|
||
|
import com.google.common.base.Objects;
|
||
|
import com.google.common.base.Preconditions;
|
||
|
import com.google.common.collect.ImmutableCollection;
|
||
|
import java.io.IOException;
|
||
|
import java.io.ObjectInputStream;
|
||
|
import java.io.ObjectOutputStream;
|
||
|
import java.io.Serializable;
|
||
|
import java.util.AbstractMap;
|
||
|
import java.util.AbstractSet;
|
||
|
import java.util.Arrays;
|
||
|
import java.util.ConcurrentModificationException;
|
||
|
import java.util.Iterator;
|
||
|
import java.util.Map;
|
||
|
import java.util.NoSuchElementException;
|
||
|
import java.util.Set;
|
||
|
|
||
|
/* loaded from: classes2.dex */
|
||
|
public final class HashBiMap<K, V> extends AbstractMap<K, V> implements BiMap<K, V>, Serializable {
|
||
|
private static final int ABSENT = -1;
|
||
|
private static final int ENDPOINT = -2;
|
||
|
private transient Set<Map.Entry<K, V>> entrySet;
|
||
|
private transient int firstInInsertionOrder;
|
||
|
private transient int[] hashTableKToV;
|
||
|
private transient int[] hashTableVToK;
|
||
|
private transient BiMap<V, K> inverse;
|
||
|
private transient Set<K> keySet;
|
||
|
transient K[] keys;
|
||
|
private transient int lastInInsertionOrder;
|
||
|
transient int modCount;
|
||
|
private transient int[] nextInBucketKToV;
|
||
|
private transient int[] nextInBucketVToK;
|
||
|
private transient int[] nextInInsertionOrder;
|
||
|
private transient int[] prevInInsertionOrder;
|
||
|
transient int size;
|
||
|
private transient Set<V> valueSet;
|
||
|
transient V[] values;
|
||
|
|
||
|
public static <K, V> HashBiMap<K, V> create() {
|
||
|
return create(16);
|
||
|
}
|
||
|
|
||
|
public static <K, V> HashBiMap<K, V> create(int i) {
|
||
|
return new HashBiMap<>(i);
|
||
|
}
|
||
|
|
||
|
public static <K, V> HashBiMap<K, V> create(Map<? extends K, ? extends V> map) {
|
||
|
HashBiMap<K, V> create = create(map.size());
|
||
|
create.putAll(map);
|
||
|
return create;
|
||
|
}
|
||
|
|
||
|
private HashBiMap(int i) {
|
||
|
init(i);
|
||
|
}
|
||
|
|
||
|
final void init(int i) {
|
||
|
CollectPreconditions.checkNonnegative(i, "expectedSize");
|
||
|
int closedTableSize = Hashing.closedTableSize(i, 1.0d);
|
||
|
this.size = 0;
|
||
|
this.keys = (K[]) new Object[i];
|
||
|
this.values = (V[]) new Object[i];
|
||
|
this.hashTableKToV = createFilledWithAbsent(closedTableSize);
|
||
|
this.hashTableVToK = createFilledWithAbsent(closedTableSize);
|
||
|
this.nextInBucketKToV = createFilledWithAbsent(i);
|
||
|
this.nextInBucketVToK = createFilledWithAbsent(i);
|
||
|
this.firstInInsertionOrder = -2;
|
||
|
this.lastInInsertionOrder = -2;
|
||
|
this.prevInInsertionOrder = createFilledWithAbsent(i);
|
||
|
this.nextInInsertionOrder = createFilledWithAbsent(i);
|
||
|
}
|
||
|
|
||
|
private static int[] createFilledWithAbsent(int i) {
|
||
|
int[] iArr = new int[i];
|
||
|
Arrays.fill(iArr, -1);
|
||
|
return iArr;
|
||
|
}
|
||
|
|
||
|
private static int[] expandAndFillWithAbsent(int[] iArr, int i) {
|
||
|
int length = iArr.length;
|
||
|
int[] copyOf = Arrays.copyOf(iArr, i);
|
||
|
Arrays.fill(copyOf, length, i, -1);
|
||
|
return copyOf;
|
||
|
}
|
||
|
|
||
|
private void ensureCapacity(int i) {
|
||
|
int[] iArr = this.nextInBucketKToV;
|
||
|
if (iArr.length < i) {
|
||
|
int expandedCapacity = ImmutableCollection.Builder.expandedCapacity(iArr.length, i);
|
||
|
this.keys = (K[]) Arrays.copyOf(this.keys, expandedCapacity);
|
||
|
this.values = (V[]) Arrays.copyOf(this.values, expandedCapacity);
|
||
|
this.nextInBucketKToV = expandAndFillWithAbsent(this.nextInBucketKToV, expandedCapacity);
|
||
|
this.nextInBucketVToK = expandAndFillWithAbsent(this.nextInBucketVToK, expandedCapacity);
|
||
|
this.prevInInsertionOrder = expandAndFillWithAbsent(this.prevInInsertionOrder, expandedCapacity);
|
||
|
this.nextInInsertionOrder = expandAndFillWithAbsent(this.nextInInsertionOrder, expandedCapacity);
|
||
|
}
|
||
|
if (this.hashTableKToV.length < i) {
|
||
|
int closedTableSize = Hashing.closedTableSize(i, 1.0d);
|
||
|
this.hashTableKToV = createFilledWithAbsent(closedTableSize);
|
||
|
this.hashTableVToK = createFilledWithAbsent(closedTableSize);
|
||
|
for (int i2 = 0; i2 < this.size; i2++) {
|
||
|
int bucket = bucket(Hashing.smearedHash(this.keys[i2]));
|
||
|
int[] iArr2 = this.nextInBucketKToV;
|
||
|
int[] iArr3 = this.hashTableKToV;
|
||
|
iArr2[i2] = iArr3[bucket];
|
||
|
iArr3[bucket] = i2;
|
||
|
int bucket2 = bucket(Hashing.smearedHash(this.values[i2]));
|
||
|
int[] iArr4 = this.nextInBucketVToK;
|
||
|
int[] iArr5 = this.hashTableVToK;
|
||
|
iArr4[i2] = iArr5[bucket2];
|
||
|
iArr5[bucket2] = i2;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private int bucket(int i) {
|
||
|
return i & (this.hashTableKToV.length - 1);
|
||
|
}
|
||
|
|
||
|
final int findEntryByKey(Object obj) {
|
||
|
return findEntryByKey(obj, Hashing.smearedHash(obj));
|
||
|
}
|
||
|
|
||
|
final int findEntryByKey(Object obj, int i) {
|
||
|
return findEntry(obj, i, this.hashTableKToV, this.nextInBucketKToV, this.keys);
|
||
|
}
|
||
|
|
||
|
final int findEntryByValue(Object obj) {
|
||
|
return findEntryByValue(obj, Hashing.smearedHash(obj));
|
||
|
}
|
||
|
|
||
|
final int findEntryByValue(Object obj, int i) {
|
||
|
return findEntry(obj, i, this.hashTableVToK, this.nextInBucketVToK, this.values);
|
||
|
}
|
||
|
|
||
|
final int findEntry(Object obj, int i, int[] iArr, int[] iArr2, Object[] objArr) {
|
||
|
int i2 = iArr[bucket(i)];
|
||
|
while (i2 != -1) {
|
||
|
if (Objects.equal(objArr[i2], obj)) {
|
||
|
return i2;
|
||
|
}
|
||
|
i2 = iArr2[i2];
|
||
|
}
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
@Override // java.util.AbstractMap, java.util.Map
|
||
|
public final boolean containsKey(Object obj) {
|
||
|
return findEntryByKey(obj) != -1;
|
||
|
}
|
||
|
|
||
|
@Override // java.util.AbstractMap, java.util.Map
|
||
|
public final boolean containsValue(Object obj) {
|
||
|
return findEntryByValue(obj) != -1;
|
||
|
}
|
||
|
|
||
|
@Override // java.util.AbstractMap, java.util.Map
|
||
|
public final V get(Object obj) {
|
||
|
int findEntryByKey = findEntryByKey(obj);
|
||
|
if (findEntryByKey == -1) {
|
||
|
return null;
|
||
|
}
|
||
|
return this.values[findEntryByKey];
|
||
|
}
|
||
|
|
||
|
final K getInverse(Object obj) {
|
||
|
int findEntryByValue = findEntryByValue(obj);
|
||
|
if (findEntryByValue == -1) {
|
||
|
return null;
|
||
|
}
|
||
|
return this.keys[findEntryByValue];
|
||
|
}
|
||
|
|
||
|
@Override // java.util.AbstractMap, java.util.Map, com.google.common.collect.BiMap
|
||
|
public final V put(K k, V v) {
|
||
|
return put(k, v, false);
|
||
|
}
|
||
|
|
||
|
final V put(K k, V v, boolean z) {
|
||
|
int smearedHash = Hashing.smearedHash(k);
|
||
|
int findEntryByKey = findEntryByKey(k, smearedHash);
|
||
|
if (findEntryByKey != -1) {
|
||
|
V v2 = this.values[findEntryByKey];
|
||
|
if (Objects.equal(v2, v)) {
|
||
|
return v;
|
||
|
}
|
||
|
replaceValueInEntry(findEntryByKey, v, z);
|
||
|
return v2;
|
||
|
}
|
||
|
int smearedHash2 = Hashing.smearedHash(v);
|
||
|
int findEntryByValue = findEntryByValue(v, smearedHash2);
|
||
|
if (!z) {
|
||
|
Preconditions.checkArgument(findEntryByValue == -1, "Value already present: %s", v);
|
||
|
} else if (findEntryByValue != -1) {
|
||
|
removeEntryValueHashKnown(findEntryByValue, smearedHash2);
|
||
|
}
|
||
|
ensureCapacity(this.size + 1);
|
||
|
K[] kArr = this.keys;
|
||
|
int i = this.size;
|
||
|
kArr[i] = k;
|
||
|
this.values[i] = v;
|
||
|
insertIntoTableKToV(i, smearedHash);
|
||
|
insertIntoTableVToK(this.size, smearedHash2);
|
||
|
setSucceeds(this.lastInInsertionOrder, this.size);
|
||
|
setSucceeds(this.size, -2);
|
||
|
this.size++;
|
||
|
this.modCount++;
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
@Override // com.google.common.collect.BiMap
|
||
|
public final V forcePut(K k, V v) {
|
||
|
return put(k, v, true);
|
||
|
}
|
||
|
|
||
|
final K putInverse(V v, K k, boolean z) {
|
||
|
int smearedHash = Hashing.smearedHash(v);
|
||
|
int findEntryByValue = findEntryByValue(v, smearedHash);
|
||
|
if (findEntryByValue != -1) {
|
||
|
K k2 = this.keys[findEntryByValue];
|
||
|
if (Objects.equal(k2, k)) {
|
||
|
return k;
|
||
|
}
|
||
|
replaceKeyInEntry(findEntryByValue, k, z);
|
||
|
return k2;
|
||
|
}
|
||
|
int i = this.lastInInsertionOrder;
|
||
|
int smearedHash2 = Hashing.smearedHash(k);
|
||
|
int findEntryByKey = findEntryByKey(k, smearedHash2);
|
||
|
if (!z) {
|
||
|
Preconditions.checkArgument(findEntryByKey == -1, "Key already present: %s", k);
|
||
|
} else if (findEntryByKey != -1) {
|
||
|
i = this.prevInInsertionOrder[findEntryByKey];
|
||
|
removeEntryKeyHashKnown(findEntryByKey, smearedHash2);
|
||
|
}
|
||
|
ensureCapacity(this.size + 1);
|
||
|
K[] kArr = this.keys;
|
||
|
int i2 = this.size;
|
||
|
kArr[i2] = k;
|
||
|
this.values[i2] = v;
|
||
|
insertIntoTableKToV(i2, smearedHash2);
|
||
|
insertIntoTableVToK(this.size, smearedHash);
|
||
|
int i3 = i == -2 ? this.firstInInsertionOrder : this.nextInInsertionOrder[i];
|
||
|
setSucceeds(i, this.size);
|
||
|
setSucceeds(this.size, i3);
|
||
|
this.size++;
|
||
|
this.modCount++;
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
private void setSucceeds(int i, int i2) {
|
||
|
if (i == -2) {
|
||
|
this.firstInInsertionOrder = i2;
|
||
|
} else {
|
||
|
this.nextInInsertionOrder[i] = i2;
|
||
|
}
|
||
|
if (i2 == -2) {
|
||
|
this.lastInInsertionOrder = i;
|
||
|
} else {
|
||
|
this.prevInInsertionOrder[i2] = i;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void insertIntoTableKToV(int i, int i2) {
|
||
|
Preconditions.checkArgument(i != -1);
|
||
|
int bucket = bucket(i2);
|
||
|
int[] iArr = this.nextInBucketKToV;
|
||
|
int[] iArr2 = this.hashTableKToV;
|
||
|
iArr[i] = iArr2[bucket];
|
||
|
iArr2[bucket] = i;
|
||
|
}
|
||
|
|
||
|
private void insertIntoTableVToK(int i, int i2) {
|
||
|
Preconditions.checkArgument(i != -1);
|
||
|
int bucket = bucket(i2);
|
||
|
int[] iArr = this.nextInBucketVToK;
|
||
|
int[] iArr2 = this.hashTableVToK;
|
||
|
iArr[i] = iArr2[bucket];
|
||
|
iArr2[bucket] = i;
|
||
|
}
|
||
|
|
||
|
private void deleteFromTableKToV(int i, int i2) {
|
||
|
Preconditions.checkArgument(i != -1);
|
||
|
int bucket = bucket(i2);
|
||
|
int[] iArr = this.hashTableKToV;
|
||
|
int i3 = iArr[bucket];
|
||
|
if (i3 == i) {
|
||
|
int[] iArr2 = this.nextInBucketKToV;
|
||
|
iArr[bucket] = iArr2[i];
|
||
|
iArr2[i] = -1;
|
||
|
return;
|
||
|
}
|
||
|
int i4 = this.nextInBucketKToV[i3];
|
||
|
while (true) {
|
||
|
int i5 = i3;
|
||
|
i3 = i4;
|
||
|
if (i3 == -1) {
|
||
|
String valueOf = String.valueOf(this.keys[i]);
|
||
|
StringBuilder sb = new StringBuilder(String.valueOf(valueOf).length() + 32);
|
||
|
sb.append("Expected to find entry with key ");
|
||
|
sb.append(valueOf);
|
||
|
throw new AssertionError(sb.toString());
|
||
|
}
|
||
|
if (i3 != i) {
|
||
|
i4 = this.nextInBucketKToV[i3];
|
||
|
} else {
|
||
|
int[] iArr3 = this.nextInBucketKToV;
|
||
|
iArr3[i5] = iArr3[i];
|
||
|
iArr3[i] = -1;
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void deleteFromTableVToK(int i, int i2) {
|
||
|
Preconditions.checkArgument(i != -1);
|
||
|
int bucket = bucket(i2);
|
||
|
int[] iArr = this.hashTableVToK;
|
||
|
int i3 = iArr[bucket];
|
||
|
if (i3 == i) {
|
||
|
int[] iArr2 = this.nextInBucketVToK;
|
||
|
iArr[bucket] = iArr2[i];
|
||
|
iArr2[i] = -1;
|
||
|
return;
|
||
|
}
|
||
|
int i4 = this.nextInBucketVToK[i3];
|
||
|
while (true) {
|
||
|
int i5 = i3;
|
||
|
i3 = i4;
|
||
|
if (i3 == -1) {
|
||
|
String valueOf = String.valueOf(this.values[i]);
|
||
|
StringBuilder sb = new StringBuilder(String.valueOf(valueOf).length() + 34);
|
||
|
sb.append("Expected to find entry with value ");
|
||
|
sb.append(valueOf);
|
||
|
throw new AssertionError(sb.toString());
|
||
|
}
|
||
|
if (i3 != i) {
|
||
|
i4 = this.nextInBucketVToK[i3];
|
||
|
} else {
|
||
|
int[] iArr3 = this.nextInBucketVToK;
|
||
|
iArr3[i5] = iArr3[i];
|
||
|
iArr3[i] = -1;
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* JADX INFO: Access modifiers changed from: private */
|
||
|
public void replaceValueInEntry(int i, V v, boolean z) {
|
||
|
Preconditions.checkArgument(i != -1);
|
||
|
int smearedHash = Hashing.smearedHash(v);
|
||
|
int findEntryByValue = findEntryByValue(v, smearedHash);
|
||
|
if (findEntryByValue != -1) {
|
||
|
if (z) {
|
||
|
removeEntryValueHashKnown(findEntryByValue, smearedHash);
|
||
|
if (i == this.size) {
|
||
|
i = findEntryByValue;
|
||
|
}
|
||
|
} else {
|
||
|
String valueOf = String.valueOf(v);
|
||
|
StringBuilder sb = new StringBuilder(String.valueOf(valueOf).length() + 30);
|
||
|
sb.append("Value already present in map: ");
|
||
|
sb.append(valueOf);
|
||
|
throw new IllegalArgumentException(sb.toString());
|
||
|
}
|
||
|
}
|
||
|
deleteFromTableVToK(i, Hashing.smearedHash(this.values[i]));
|
||
|
this.values[i] = v;
|
||
|
insertIntoTableVToK(i, smearedHash);
|
||
|
}
|
||
|
|
||
|
/* JADX INFO: Access modifiers changed from: private */
|
||
|
public void replaceKeyInEntry(int i, K k, boolean z) {
|
||
|
int i2;
|
||
|
Preconditions.checkArgument(i != -1);
|
||
|
int smearedHash = Hashing.smearedHash(k);
|
||
|
int findEntryByKey = findEntryByKey(k, smearedHash);
|
||
|
int i3 = this.lastInInsertionOrder;
|
||
|
if (findEntryByKey == -1) {
|
||
|
i2 = -2;
|
||
|
} else if (z) {
|
||
|
i3 = this.prevInInsertionOrder[findEntryByKey];
|
||
|
i2 = this.nextInInsertionOrder[findEntryByKey];
|
||
|
removeEntryKeyHashKnown(findEntryByKey, smearedHash);
|
||
|
if (i == this.size) {
|
||
|
i = findEntryByKey;
|
||
|
}
|
||
|
} else {
|
||
|
String valueOf = String.valueOf(k);
|
||
|
StringBuilder sb = new StringBuilder(String.valueOf(valueOf).length() + 28);
|
||
|
sb.append("Key already present in map: ");
|
||
|
sb.append(valueOf);
|
||
|
throw new IllegalArgumentException(sb.toString());
|
||
|
}
|
||
|
if (i3 == i) {
|
||
|
i3 = this.prevInInsertionOrder[i];
|
||
|
} else if (i3 == this.size) {
|
||
|
i3 = findEntryByKey;
|
||
|
}
|
||
|
if (i2 == i) {
|
||
|
findEntryByKey = this.nextInInsertionOrder[i];
|
||
|
} else if (i2 != this.size) {
|
||
|
findEntryByKey = i2;
|
||
|
}
|
||
|
setSucceeds(this.prevInInsertionOrder[i], this.nextInInsertionOrder[i]);
|
||
|
deleteFromTableKToV(i, Hashing.smearedHash(this.keys[i]));
|
||
|
this.keys[i] = k;
|
||
|
insertIntoTableKToV(i, Hashing.smearedHash(k));
|
||
|
setSucceeds(i3, i);
|
||
|
setSucceeds(i, findEntryByKey);
|
||
|
}
|
||
|
|
||
|
@Override // java.util.AbstractMap, java.util.Map
|
||
|
public final V remove(Object obj) {
|
||
|
int smearedHash = Hashing.smearedHash(obj);
|
||
|
int findEntryByKey = findEntryByKey(obj, smearedHash);
|
||
|
if (findEntryByKey == -1) {
|
||
|
return null;
|
||
|
}
|
||
|
V v = this.values[findEntryByKey];
|
||
|
removeEntryKeyHashKnown(findEntryByKey, smearedHash);
|
||
|
return v;
|
||
|
}
|
||
|
|
||
|
final K removeInverse(Object obj) {
|
||
|
int smearedHash = Hashing.smearedHash(obj);
|
||
|
int findEntryByValue = findEntryByValue(obj, smearedHash);
|
||
|
if (findEntryByValue == -1) {
|
||
|
return null;
|
||
|
}
|
||
|
K k = this.keys[findEntryByValue];
|
||
|
removeEntryValueHashKnown(findEntryByValue, smearedHash);
|
||
|
return k;
|
||
|
}
|
||
|
|
||
|
final void removeEntry(int i) {
|
||
|
removeEntryKeyHashKnown(i, Hashing.smearedHash(this.keys[i]));
|
||
|
}
|
||
|
|
||
|
private void removeEntry(int i, int i2, int i3) {
|
||
|
Preconditions.checkArgument(i != -1);
|
||
|
deleteFromTableKToV(i, i2);
|
||
|
deleteFromTableVToK(i, i3);
|
||
|
setSucceeds(this.prevInInsertionOrder[i], this.nextInInsertionOrder[i]);
|
||
|
moveEntryToIndex(this.size - 1, i);
|
||
|
K[] kArr = this.keys;
|
||
|
int i4 = this.size - 1;
|
||
|
kArr[i4] = null;
|
||
|
this.values[i4] = null;
|
||
|
this.size = i4;
|
||
|
this.modCount++;
|
||
|
}
|
||
|
|
||
|
final void removeEntryKeyHashKnown(int i, int i2) {
|
||
|
removeEntry(i, i2, Hashing.smearedHash(this.values[i]));
|
||
|
}
|
||
|
|
||
|
final void removeEntryValueHashKnown(int i, int i2) {
|
||
|
removeEntry(i, Hashing.smearedHash(this.keys[i]), i2);
|
||
|
}
|
||
|
|
||
|
private void moveEntryToIndex(int i, int i2) {
|
||
|
if (i == i2) {
|
||
|
return;
|
||
|
}
|
||
|
int i3 = this.prevInInsertionOrder[i];
|
||
|
int i4 = this.nextInInsertionOrder[i];
|
||
|
setSucceeds(i3, i2);
|
||
|
setSucceeds(i2, i4);
|
||
|
K[] kArr = this.keys;
|
||
|
K k = kArr[i];
|
||
|
V[] vArr = this.values;
|
||
|
V v = vArr[i];
|
||
|
kArr[i2] = k;
|
||
|
vArr[i2] = v;
|
||
|
int bucket = bucket(Hashing.smearedHash(k));
|
||
|
int[] iArr = this.hashTableKToV;
|
||
|
int i5 = iArr[bucket];
|
||
|
if (i5 == i) {
|
||
|
iArr[bucket] = i2;
|
||
|
} else {
|
||
|
int i6 = this.nextInBucketKToV[i5];
|
||
|
while (i6 != i) {
|
||
|
i5 = i6;
|
||
|
i6 = this.nextInBucketKToV[i6];
|
||
|
}
|
||
|
this.nextInBucketKToV[i5] = i2;
|
||
|
}
|
||
|
int[] iArr2 = this.nextInBucketKToV;
|
||
|
iArr2[i2] = iArr2[i];
|
||
|
iArr2[i] = -1;
|
||
|
int bucket2 = bucket(Hashing.smearedHash(v));
|
||
|
int[] iArr3 = this.hashTableVToK;
|
||
|
int i7 = iArr3[bucket2];
|
||
|
if (i7 == i) {
|
||
|
iArr3[bucket2] = i2;
|
||
|
} else {
|
||
|
int i8 = this.nextInBucketVToK[i7];
|
||
|
while (i8 != i) {
|
||
|
i7 = i8;
|
||
|
i8 = this.nextInBucketVToK[i8];
|
||
|
}
|
||
|
this.nextInBucketVToK[i7] = i2;
|
||
|
}
|
||
|
int[] iArr4 = this.nextInBucketVToK;
|
||
|
iArr4[i2] = iArr4[i];
|
||
|
iArr4[i] = -1;
|
||
|
}
|
||
|
|
||
|
@Override // java.util.AbstractMap, java.util.Map
|
||
|
public final void clear() {
|
||
|
Arrays.fill(this.keys, 0, this.size, (Object) null);
|
||
|
Arrays.fill(this.values, 0, this.size, (Object) null);
|
||
|
Arrays.fill(this.hashTableKToV, -1);
|
||
|
Arrays.fill(this.hashTableVToK, -1);
|
||
|
Arrays.fill(this.nextInBucketKToV, 0, this.size, -1);
|
||
|
Arrays.fill(this.nextInBucketVToK, 0, this.size, -1);
|
||
|
Arrays.fill(this.prevInInsertionOrder, 0, this.size, -1);
|
||
|
Arrays.fill(this.nextInInsertionOrder, 0, this.size, -1);
|
||
|
this.size = 0;
|
||
|
this.firstInInsertionOrder = -2;
|
||
|
this.lastInInsertionOrder = -2;
|
||
|
this.modCount++;
|
||
|
}
|
||
|
|
||
|
/* JADX INFO: Access modifiers changed from: package-private */
|
||
|
/* loaded from: classes2.dex */
|
||
|
public static abstract class View<K, V, T> extends AbstractSet<T> {
|
||
|
final HashBiMap<K, V> biMap;
|
||
|
|
||
|
abstract T forEntry(int i);
|
||
|
|
||
|
View(HashBiMap<K, V> hashBiMap) {
|
||
|
this.biMap = hashBiMap;
|
||
|
}
|
||
|
|
||
|
@Override // java.util.AbstractCollection, java.util.Collection, java.lang.Iterable, java.util.Set
|
||
|
public Iterator<T> iterator() {
|
||
|
return new Iterator<T>(this) { // from class: com.google.common.collect.HashBiMap.View.1
|
||
|
private int expectedModCount;
|
||
|
private int index;
|
||
|
private int indexToRemove = -1;
|
||
|
private int remaining;
|
||
|
final View this$0;
|
||
|
|
||
|
{
|
||
|
this.this$0 = this;
|
||
|
this.index = ((HashBiMap) this.biMap).firstInInsertionOrder;
|
||
|
this.expectedModCount = this.biMap.modCount;
|
||
|
this.remaining = this.biMap.size;
|
||
|
}
|
||
|
|
||
|
private void checkForComodification() {
|
||
|
if (this.this$0.biMap.modCount != this.expectedModCount) {
|
||
|
throw new ConcurrentModificationException();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Override // java.util.Iterator
|
||
|
public boolean hasNext() {
|
||
|
checkForComodification();
|
||
|
return this.index != -2 && this.remaining > 0;
|
||
|
}
|
||
|
|
||
|
@Override // java.util.Iterator
|
||
|
public T next() {
|
||
|
if (!hasNext()) {
|
||
|
throw new NoSuchElementException();
|
||
|
}
|
||
|
T t = (T) this.this$0.forEntry(this.index);
|
||
|
this.indexToRemove = this.index;
|
||
|
this.index = ((HashBiMap) this.this$0.biMap).nextInInsertionOrder[this.index];
|
||
|
this.remaining--;
|
||
|
return t;
|
||
|
}
|
||
|
|
||
|
@Override // java.util.Iterator
|
||
|
public void remove() {
|
||
|
checkForComodification();
|
||
|
CollectPreconditions.checkRemove(this.indexToRemove != -1);
|
||
|
this.this$0.biMap.removeEntry(this.indexToRemove);
|
||
|
if (this.index == this.this$0.biMap.size) {
|
||
|
this.index = this.indexToRemove;
|
||
|
}
|
||
|
this.indexToRemove = -1;
|
||
|
this.expectedModCount = this.this$0.biMap.modCount;
|
||
|
}
|
||
|
};
|
||
|
}
|
||
|
|
||
|
@Override // java.util.AbstractCollection, java.util.Collection, java.util.Set
|
||
|
public int size() {
|
||
|
return this.biMap.size;
|
||
|
}
|
||
|
|
||
|
@Override // java.util.AbstractCollection, java.util.Collection, java.util.Set
|
||
|
public void clear() {
|
||
|
this.biMap.clear();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Override // java.util.AbstractMap, java.util.Map
|
||
|
public final Set<K> keySet() {
|
||
|
Set<K> set = this.keySet;
|
||
|
if (set != null) {
|
||
|
return set;
|
||
|
}
|
||
|
KeySet keySet = new KeySet(this);
|
||
|
this.keySet = keySet;
|
||
|
return keySet;
|
||
|
}
|
||
|
|
||
|
/* loaded from: classes2.dex */
|
||
|
final class KeySet extends View<K, V, K> {
|
||
|
final HashBiMap this$0;
|
||
|
|
||
|
/* JADX WARN: 'super' call moved to the top of the method (can break code semantics) */
|
||
|
KeySet(HashBiMap hashBiMap) {
|
||
|
super(hashBiMap);
|
||
|
this.this$0 = hashBiMap;
|
||
|
}
|
||
|
|
||
|
@Override // com.google.common.collect.HashBiMap.View
|
||
|
final K forEntry(int i) {
|
||
|
return this.this$0.keys[i];
|
||
|
}
|
||
|
|
||
|
@Override // java.util.AbstractCollection, java.util.Collection, java.util.Set
|
||
|
public final boolean contains(Object obj) {
|
||
|
return this.this$0.containsKey(obj);
|
||
|
}
|
||
|
|
||
|
@Override // java.util.AbstractCollection, java.util.Collection, java.util.Set
|
||
|
public final boolean remove(Object obj) {
|
||
|
int smearedHash = Hashing.smearedHash(obj);
|
||
|
int findEntryByKey = this.this$0.findEntryByKey(obj, smearedHash);
|
||
|
if (findEntryByKey == -1) {
|
||
|
return false;
|
||
|
}
|
||
|
this.this$0.removeEntryKeyHashKnown(findEntryByKey, smearedHash);
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Override // java.util.AbstractMap, java.util.Map
|
||
|
public final Set<V> values() {
|
||
|
Set<V> set = this.valueSet;
|
||
|
if (set != null) {
|
||
|
return set;
|
||
|
}
|
||
|
ValueSet valueSet = new ValueSet(this);
|
||
|
this.valueSet = valueSet;
|
||
|
return valueSet;
|
||
|
}
|
||
|
|
||
|
/* JADX INFO: Access modifiers changed from: package-private */
|
||
|
/* loaded from: classes2.dex */
|
||
|
public final class ValueSet extends View<K, V, V> {
|
||
|
final HashBiMap this$0;
|
||
|
|
||
|
/* JADX WARN: 'super' call moved to the top of the method (can break code semantics) */
|
||
|
ValueSet(HashBiMap hashBiMap) {
|
||
|
super(hashBiMap);
|
||
|
this.this$0 = hashBiMap;
|
||
|
}
|
||
|
|
||
|
@Override // com.google.common.collect.HashBiMap.View
|
||
|
final V forEntry(int i) {
|
||
|
return this.this$0.values[i];
|
||
|
}
|
||
|
|
||
|
@Override // java.util.AbstractCollection, java.util.Collection, java.util.Set
|
||
|
public final boolean contains(Object obj) {
|
||
|
return this.this$0.containsValue(obj);
|
||
|
}
|
||
|
|
||
|
@Override // java.util.AbstractCollection, java.util.Collection, java.util.Set
|
||
|
public final boolean remove(Object obj) {
|
||
|
int smearedHash = Hashing.smearedHash(obj);
|
||
|
int findEntryByValue = this.this$0.findEntryByValue(obj, smearedHash);
|
||
|
if (findEntryByValue == -1) {
|
||
|
return false;
|
||
|
}
|
||
|
this.this$0.removeEntryValueHashKnown(findEntryByValue, smearedHash);
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Override // java.util.AbstractMap, java.util.Map
|
||
|
public final Set<Map.Entry<K, V>> entrySet() {
|
||
|
Set<Map.Entry<K, V>> set = this.entrySet;
|
||
|
if (set != null) {
|
||
|
return set;
|
||
|
}
|
||
|
EntrySet entrySet = new EntrySet(this);
|
||
|
this.entrySet = entrySet;
|
||
|
return entrySet;
|
||
|
}
|
||
|
|
||
|
/* loaded from: classes2.dex */
|
||
|
final class EntrySet extends View<K, V, Map.Entry<K, V>> {
|
||
|
final HashBiMap this$0;
|
||
|
|
||
|
/* JADX WARN: 'super' call moved to the top of the method (can break code semantics) */
|
||
|
EntrySet(HashBiMap hashBiMap) {
|
||
|
super(hashBiMap);
|
||
|
this.this$0 = hashBiMap;
|
||
|
}
|
||
|
|
||
|
@Override // java.util.AbstractCollection, java.util.Collection, java.util.Set
|
||
|
public final boolean contains(Object obj) {
|
||
|
if (!(obj instanceof Map.Entry)) {
|
||
|
return false;
|
||
|
}
|
||
|
Map.Entry entry = (Map.Entry) obj;
|
||
|
Object key = entry.getKey();
|
||
|
Object value = entry.getValue();
|
||
|
int findEntryByKey = this.this$0.findEntryByKey(key);
|
||
|
return findEntryByKey != -1 && Objects.equal(value, this.this$0.values[findEntryByKey]);
|
||
|
}
|
||
|
|
||
|
@Override // java.util.AbstractCollection, java.util.Collection, java.util.Set
|
||
|
public final boolean remove(Object obj) {
|
||
|
if (!(obj instanceof Map.Entry)) {
|
||
|
return false;
|
||
|
}
|
||
|
Map.Entry entry = (Map.Entry) obj;
|
||
|
Object key = entry.getKey();
|
||
|
Object value = entry.getValue();
|
||
|
int smearedHash = Hashing.smearedHash(key);
|
||
|
int findEntryByKey = this.this$0.findEntryByKey(key, smearedHash);
|
||
|
if (findEntryByKey == -1 || !Objects.equal(value, this.this$0.values[findEntryByKey])) {
|
||
|
return false;
|
||
|
}
|
||
|
this.this$0.removeEntryKeyHashKnown(findEntryByKey, smearedHash);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
/* JADX INFO: Access modifiers changed from: package-private */
|
||
|
@Override // com.google.common.collect.HashBiMap.View
|
||
|
public final Map.Entry<K, V> forEntry(int i) {
|
||
|
return new EntryForKey(this.this$0, i);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* JADX INFO: Access modifiers changed from: package-private */
|
||
|
/* loaded from: classes2.dex */
|
||
|
public final class EntryForKey extends AbstractMapEntry<K, V> {
|
||
|
int index;
|
||
|
final K key;
|
||
|
final HashBiMap this$0;
|
||
|
|
||
|
EntryForKey(HashBiMap hashBiMap, int i) {
|
||
|
this.this$0 = hashBiMap;
|
||
|
this.key = hashBiMap.keys[i];
|
||
|
this.index = i;
|
||
|
}
|
||
|
|
||
|
final void updateIndex() {
|
||
|
int i = this.index;
|
||
|
if (i == -1 || i > this.this$0.size || !Objects.equal(this.this$0.keys[this.index], this.key)) {
|
||
|
this.index = this.this$0.findEntryByKey(this.key);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Override // com.google.common.collect.AbstractMapEntry, java.util.Map.Entry
|
||
|
public final V getValue() {
|
||
|
updateIndex();
|
||
|
if (this.index == -1) {
|
||
|
return null;
|
||
|
}
|
||
|
return this.this$0.values[this.index];
|
||
|
}
|
||
|
|
||
|
@Override // com.google.common.collect.AbstractMapEntry, java.util.Map.Entry
|
||
|
public final V setValue(V v) {
|
||
|
updateIndex();
|
||
|
if (this.index == -1) {
|
||
|
return this.this$0.put(this.key, v);
|
||
|
}
|
||
|
V v2 = this.this$0.values[this.index];
|
||
|
if (Objects.equal(v2, v)) {
|
||
|
return v;
|
||
|
}
|
||
|
this.this$0.replaceValueInEntry(this.index, v, false);
|
||
|
return v2;
|
||
|
}
|
||
|
|
||
|
@Override // com.google.common.collect.AbstractMapEntry, java.util.Map.Entry
|
||
|
public final K getKey() {
|
||
|
return this.key;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Override // com.google.common.collect.BiMap
|
||
|
public final BiMap<V, K> inverse() {
|
||
|
BiMap<V, K> biMap = this.inverse;
|
||
|
if (biMap != null) {
|
||
|
return biMap;
|
||
|
}
|
||
|
Inverse inverse = new Inverse(this);
|
||
|
this.inverse = inverse;
|
||
|
return inverse;
|
||
|
}
|
||
|
|
||
|
/* loaded from: classes2.dex */
|
||
|
static class Inverse<K, V> extends AbstractMap<V, K> implements BiMap<V, K>, Serializable {
|
||
|
private final HashBiMap<K, V> forward;
|
||
|
private transient Set<Map.Entry<V, K>> inverseEntrySet;
|
||
|
|
||
|
Inverse(HashBiMap<K, V> hashBiMap) {
|
||
|
this.forward = hashBiMap;
|
||
|
}
|
||
|
|
||
|
@Override // java.util.AbstractMap, java.util.Map
|
||
|
public int size() {
|
||
|
return this.forward.size;
|
||
|
}
|
||
|
|
||
|
@Override // java.util.AbstractMap, java.util.Map
|
||
|
public boolean containsKey(Object obj) {
|
||
|
return this.forward.containsValue(obj);
|
||
|
}
|
||
|
|
||
|
@Override // java.util.AbstractMap, java.util.Map
|
||
|
public K get(Object obj) {
|
||
|
return this.forward.getInverse(obj);
|
||
|
}
|
||
|
|
||
|
@Override // java.util.AbstractMap, java.util.Map
|
||
|
public boolean containsValue(Object obj) {
|
||
|
return this.forward.containsKey(obj);
|
||
|
}
|
||
|
|
||
|
@Override // java.util.AbstractMap, java.util.Map, com.google.common.collect.BiMap
|
||
|
public K put(V v, K k) {
|
||
|
return this.forward.putInverse(v, k, false);
|
||
|
}
|
||
|
|
||
|
@Override // com.google.common.collect.BiMap
|
||
|
public K forcePut(V v, K k) {
|
||
|
return this.forward.putInverse(v, k, true);
|
||
|
}
|
||
|
|
||
|
@Override // java.util.AbstractMap, java.util.Map
|
||
|
public K remove(Object obj) {
|
||
|
return this.forward.removeInverse(obj);
|
||
|
}
|
||
|
|
||
|
@Override // java.util.AbstractMap, java.util.Map
|
||
|
public void clear() {
|
||
|
this.forward.clear();
|
||
|
}
|
||
|
|
||
|
@Override // java.util.AbstractMap, java.util.Map
|
||
|
public Set<V> keySet() {
|
||
|
return this.forward.values();
|
||
|
}
|
||
|
|
||
|
@Override // java.util.AbstractMap, java.util.Map
|
||
|
public Set<K> values() {
|
||
|
return this.forward.keySet();
|
||
|
}
|
||
|
|
||
|
@Override // java.util.AbstractMap, java.util.Map
|
||
|
public Set<Map.Entry<V, K>> entrySet() {
|
||
|
Set<Map.Entry<V, K>> set = this.inverseEntrySet;
|
||
|
if (set != null) {
|
||
|
return set;
|
||
|
}
|
||
|
InverseEntrySet inverseEntrySet = new InverseEntrySet(this.forward);
|
||
|
this.inverseEntrySet = inverseEntrySet;
|
||
|
return inverseEntrySet;
|
||
|
}
|
||
|
|
||
|
private void readObject(ObjectInputStream objectInputStream) throws ClassNotFoundException, IOException {
|
||
|
objectInputStream.defaultReadObject();
|
||
|
((HashBiMap) this.forward).inverse = this;
|
||
|
}
|
||
|
|
||
|
@Override // com.google.common.collect.BiMap
|
||
|
public BiMap<K, V> inverse() {
|
||
|
return this.forward;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* loaded from: classes2.dex */
|
||
|
static class InverseEntrySet<K, V> extends View<K, V, Map.Entry<V, K>> {
|
||
|
InverseEntrySet(HashBiMap<K, V> hashBiMap) {
|
||
|
super(hashBiMap);
|
||
|
}
|
||
|
|
||
|
@Override // java.util.AbstractCollection, java.util.Collection, java.util.Set
|
||
|
public boolean contains(Object obj) {
|
||
|
if (!(obj instanceof Map.Entry)) {
|
||
|
return false;
|
||
|
}
|
||
|
Map.Entry entry = (Map.Entry) obj;
|
||
|
Object key = entry.getKey();
|
||
|
Object value = entry.getValue();
|
||
|
int findEntryByValue = this.biMap.findEntryByValue(key);
|
||
|
return findEntryByValue != -1 && Objects.equal(this.biMap.keys[findEntryByValue], value);
|
||
|
}
|
||
|
|
||
|
@Override // java.util.AbstractCollection, java.util.Collection, java.util.Set
|
||
|
public boolean remove(Object obj) {
|
||
|
if (!(obj instanceof Map.Entry)) {
|
||
|
return false;
|
||
|
}
|
||
|
Map.Entry entry = (Map.Entry) obj;
|
||
|
Object key = entry.getKey();
|
||
|
Object value = entry.getValue();
|
||
|
int smearedHash = Hashing.smearedHash(key);
|
||
|
int findEntryByValue = this.biMap.findEntryByValue(key, smearedHash);
|
||
|
if (findEntryByValue == -1 || !Objects.equal(this.biMap.keys[findEntryByValue], value)) {
|
||
|
return false;
|
||
|
}
|
||
|
this.biMap.removeEntryValueHashKnown(findEntryByValue, smearedHash);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
/* JADX INFO: Access modifiers changed from: package-private */
|
||
|
@Override // com.google.common.collect.HashBiMap.View
|
||
|
public Map.Entry<V, K> forEntry(int i) {
|
||
|
return new EntryForValue(this.biMap, i);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* JADX INFO: Access modifiers changed from: package-private */
|
||
|
/* loaded from: classes2.dex */
|
||
|
public static final class EntryForValue<K, V> extends AbstractMapEntry<V, K> {
|
||
|
final HashBiMap<K, V> biMap;
|
||
|
int index;
|
||
|
final V value;
|
||
|
|
||
|
EntryForValue(HashBiMap<K, V> hashBiMap, int i) {
|
||
|
this.biMap = hashBiMap;
|
||
|
this.value = hashBiMap.values[i];
|
||
|
this.index = i;
|
||
|
}
|
||
|
|
||
|
private void updateIndex() {
|
||
|
int i = this.index;
|
||
|
if (i == -1 || i > this.biMap.size || !Objects.equal(this.value, this.biMap.values[this.index])) {
|
||
|
this.index = this.biMap.findEntryByValue(this.value);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Override // com.google.common.collect.AbstractMapEntry, java.util.Map.Entry
|
||
|
public final K getValue() {
|
||
|
updateIndex();
|
||
|
if (this.index == -1) {
|
||
|
return null;
|
||
|
}
|
||
|
return this.biMap.keys[this.index];
|
||
|
}
|
||
|
|
||
|
@Override // com.google.common.collect.AbstractMapEntry, java.util.Map.Entry
|
||
|
public final K setValue(K k) {
|
||
|
updateIndex();
|
||
|
if (this.index == -1) {
|
||
|
return this.biMap.putInverse(this.value, k, false);
|
||
|
}
|
||
|
K k2 = this.biMap.keys[this.index];
|
||
|
if (Objects.equal(k2, k)) {
|
||
|
return k;
|
||
|
}
|
||
|
this.biMap.replaceKeyInEntry(this.index, k, false);
|
||
|
return k2;
|
||
|
}
|
||
|
|
||
|
@Override // com.google.common.collect.AbstractMapEntry, java.util.Map.Entry
|
||
|
public final V getKey() {
|
||
|
return this.value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void writeObject(ObjectOutputStream objectOutputStream) throws IOException {
|
||
|
objectOutputStream.defaultWriteObject();
|
||
|
Serialization.writeMap(this, objectOutputStream);
|
||
|
}
|
||
|
|
||
|
private void readObject(ObjectInputStream objectInputStream) throws IOException, ClassNotFoundException {
|
||
|
objectInputStream.defaultReadObject();
|
||
|
int readCount = Serialization.readCount(objectInputStream);
|
||
|
init(16);
|
||
|
Serialization.populateMap(this, objectInputStream, readCount);
|
||
|
}
|
||
|
|
||
|
@Override // java.util.AbstractMap, java.util.Map
|
||
|
public final int size() {
|
||
|
return this.size;
|
||
|
}
|
||
|
}
|