what-the-bank/sources/com/google/common/util/concurrent/Striped.java

388 lines
13 KiB
Java
Raw Permalink Normal View History

2024-07-27 18:17:47 +07:00
package com.google.common.util.concurrent;
import com.google.common.base.MoreObjects;
import com.google.common.base.Preconditions;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.collect.MapMaker;
import com.google.common.math.IntMath;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.math.RoundingMode;
import java.util.Arrays;
import java.util.Collections;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.AtomicReferenceArray;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/* loaded from: classes2.dex */
public abstract class Striped<L> {
private static final int ALL_SET = -1;
private static final int LARGE_LAZY_CUTOFF = 1024;
private static final Supplier<ReadWriteLock> READ_WRITE_LOCK_SUPPLIER = new Supplier<ReadWriteLock>() { // from class: com.google.common.util.concurrent.Striped.5
@Override // com.google.common.base.Supplier
public ReadWriteLock get() {
return new ReentrantReadWriteLock();
}
};
private static final Supplier<ReadWriteLock> WEAK_SAFE_READ_WRITE_LOCK_SUPPLIER = new Supplier<ReadWriteLock>() { // from class: com.google.common.util.concurrent.Striped.6
@Override // com.google.common.base.Supplier
public ReadWriteLock get() {
return new WeakSafeReadWriteLock();
}
};
/* JADX INFO: Access modifiers changed from: private */
public static int smear(int i) {
int i2 = i ^ ((i >>> 20) ^ (i >>> 12));
return (i2 ^ (i2 >>> 7)) ^ (i2 >>> 4);
}
public abstract L get(Object obj);
public abstract L getAt(int i);
abstract int indexFor(Object obj);
public abstract int size();
private Striped() {
}
public Iterable<L> bulkGet(Iterable<?> iterable) {
Object[] array = Iterables.toArray(iterable, Object.class);
if (array.length == 0) {
return ImmutableList.of();
}
int[] iArr = new int[array.length];
for (int i = 0; i < array.length; i++) {
iArr[i] = indexFor(array[i]);
}
Arrays.sort(iArr);
int i2 = iArr[0];
array[0] = getAt(i2);
for (int i3 = 1; i3 < array.length; i3++) {
int i4 = iArr[i3];
if (i4 == i2) {
array[i3] = array[i3 - 1];
} else {
array[i3] = getAt(i4);
i2 = i4;
}
}
return Collections.unmodifiableList(Arrays.asList(array));
}
static <L> Striped<L> custom(int i, Supplier<L> supplier) {
return new CompactStriped(i, supplier);
}
public static Striped<Lock> lock(int i) {
return custom(i, new Supplier<Lock>() { // from class: com.google.common.util.concurrent.Striped.1
@Override // com.google.common.base.Supplier
public Lock get() {
return new PaddedLock();
}
});
}
public static Striped<Lock> lazyWeakLock(int i) {
return lazy(i, new Supplier<Lock>() { // from class: com.google.common.util.concurrent.Striped.2
@Override // com.google.common.base.Supplier
public Lock get() {
return new ReentrantLock(false);
}
});
}
private static <L> Striped<L> lazy(int i, Supplier<L> supplier) {
if (i < 1024) {
return new SmallLazyStriped(i, supplier);
}
return new LargeLazyStriped(i, supplier);
}
public static Striped<Semaphore> semaphore(int i, int i2) {
return custom(i, new Supplier<Semaphore>(i2) { // from class: com.google.common.util.concurrent.Striped.3
final int val$permits;
{
this.val$permits = i2;
}
@Override // com.google.common.base.Supplier
public Semaphore get() {
return new PaddedSemaphore(this.val$permits);
}
});
}
public static Striped<Semaphore> lazyWeakSemaphore(int i, int i2) {
return lazy(i, new Supplier<Semaphore>(i2) { // from class: com.google.common.util.concurrent.Striped.4
final int val$permits;
{
this.val$permits = i2;
}
@Override // com.google.common.base.Supplier
public Semaphore get() {
return new Semaphore(this.val$permits, false);
}
});
}
public static Striped<ReadWriteLock> readWriteLock(int i) {
return custom(i, READ_WRITE_LOCK_SUPPLIER);
}
public static Striped<ReadWriteLock> lazyWeakReadWriteLock(int i) {
return lazy(i, WEAK_SAFE_READ_WRITE_LOCK_SUPPLIER);
}
/* JADX INFO: Access modifiers changed from: package-private */
/* loaded from: classes2.dex */
public static final class WeakSafeReadWriteLock implements ReadWriteLock {
private final ReadWriteLock delegate = new ReentrantReadWriteLock();
WeakSafeReadWriteLock() {
}
@Override // java.util.concurrent.locks.ReadWriteLock
public final Lock readLock() {
return new WeakSafeLock(this.delegate.readLock(), this);
}
@Override // java.util.concurrent.locks.ReadWriteLock
public final Lock writeLock() {
return new WeakSafeLock(this.delegate.writeLock(), this);
}
}
/* loaded from: classes2.dex */
static final class WeakSafeLock extends ForwardingLock {
private final Lock delegate;
private final WeakSafeReadWriteLock strongReference;
WeakSafeLock(Lock lock, WeakSafeReadWriteLock weakSafeReadWriteLock) {
this.delegate = lock;
this.strongReference = weakSafeReadWriteLock;
}
@Override // com.google.common.util.concurrent.ForwardingLock, java.util.concurrent.locks.Lock
public final Condition newCondition() {
return new WeakSafeCondition(this.delegate.newCondition(), this.strongReference);
}
@Override // com.google.common.util.concurrent.ForwardingLock
final Lock delegate() {
return this.delegate;
}
}
/* loaded from: classes2.dex */
static final class WeakSafeCondition extends ForwardingCondition {
private final Condition delegate;
private final WeakSafeReadWriteLock strongReference;
WeakSafeCondition(Condition condition, WeakSafeReadWriteLock weakSafeReadWriteLock) {
this.delegate = condition;
this.strongReference = weakSafeReadWriteLock;
}
@Override // com.google.common.util.concurrent.ForwardingCondition
final Condition delegate() {
return this.delegate;
}
}
/* loaded from: classes2.dex */
static abstract class PowerOfTwoStriped<L> extends Striped<L> {
final int mask;
PowerOfTwoStriped(int i) {
super();
Preconditions.checkArgument(i > 0, "Stripes must be positive");
this.mask = i > 1073741824 ? -1 : Striped.ceilToPowerOfTwo(i) - 1;
}
@Override // com.google.common.util.concurrent.Striped
final int indexFor(Object obj) {
return Striped.smear(obj.hashCode()) & this.mask;
}
@Override // com.google.common.util.concurrent.Striped
public final L get(Object obj) {
return getAt(indexFor(obj));
}
}
/* JADX INFO: Access modifiers changed from: package-private */
/* loaded from: classes2.dex */
public static class CompactStriped<L> extends PowerOfTwoStriped<L> {
private final Object[] array;
private CompactStriped(int i, Supplier<L> supplier) {
super(i);
int i2 = 0;
Preconditions.checkArgument(i <= 1073741824, "Stripes must be <= 2^30)");
this.array = new Object[this.mask + 1];
while (true) {
Object[] objArr = this.array;
if (i2 >= objArr.length) {
return;
}
objArr[i2] = supplier.get();
i2++;
}
}
@Override // com.google.common.util.concurrent.Striped
public L getAt(int i) {
return (L) this.array[i];
}
@Override // com.google.common.util.concurrent.Striped
public int size() {
return this.array.length;
}
}
/* JADX INFO: Access modifiers changed from: package-private */
/* loaded from: classes2.dex */
public static class SmallLazyStriped<L> extends PowerOfTwoStriped<L> {
final AtomicReferenceArray<ArrayReference<? extends L>> locks;
final ReferenceQueue<L> queue;
final int size;
final Supplier<L> supplier;
SmallLazyStriped(int i, Supplier<L> supplier) {
super(i);
this.queue = new ReferenceQueue<>();
int i2 = this.mask == -1 ? Integer.MAX_VALUE : this.mask + 1;
this.size = i2;
this.locks = new AtomicReferenceArray<>(i2);
this.supplier = supplier;
}
@Override // com.google.common.util.concurrent.Striped
public L getAt(int i) {
if (this.size != Integer.MAX_VALUE) {
Preconditions.checkElementIndex(i, size());
}
ArrayReference<? extends L> arrayReference = this.locks.get(i);
L l = arrayReference == null ? null : arrayReference.get();
if (l != null) {
return l;
}
L l2 = this.supplier.get();
ArrayReference arrayReference2 = new ArrayReference(l2, i, this.queue);
while (!Striped$SmallLazyStriped$$ExternalSyntheticBackportWithForwarding0.m(this.locks, i, arrayReference, arrayReference2)) {
arrayReference = this.locks.get(i);
L l3 = arrayReference == null ? null : arrayReference.get();
if (l3 != null) {
return l3;
}
}
drainQueue();
return l2;
}
private void drainQueue() {
while (true) {
Reference<? extends L> poll = this.queue.poll();
if (poll == null) {
return;
}
ArrayReference arrayReference = (ArrayReference) poll;
Striped$SmallLazyStriped$$ExternalSyntheticBackportWithForwarding0.m(this.locks, arrayReference.index, arrayReference, null);
}
}
/* JADX INFO: Access modifiers changed from: package-private */
/* loaded from: classes2.dex */
public static final class ArrayReference<L> extends WeakReference<L> {
final int index;
ArrayReference(L l, int i, ReferenceQueue<L> referenceQueue) {
super(l, referenceQueue);
this.index = i;
}
}
@Override // com.google.common.util.concurrent.Striped
public int size() {
return this.size;
}
}
/* JADX INFO: Access modifiers changed from: package-private */
/* loaded from: classes2.dex */
public static class LargeLazyStriped<L> extends PowerOfTwoStriped<L> {
final ConcurrentMap<Integer, L> locks;
final int size;
final Supplier<L> supplier;
LargeLazyStriped(int i, Supplier<L> supplier) {
super(i);
this.size = this.mask == -1 ? Integer.MAX_VALUE : this.mask + 1;
this.supplier = supplier;
this.locks = new MapMaker().weakValues().makeMap();
}
@Override // com.google.common.util.concurrent.Striped
public L getAt(int i) {
if (this.size != Integer.MAX_VALUE) {
Preconditions.checkElementIndex(i, size());
}
L l = this.locks.get(Integer.valueOf(i));
if (l != null) {
return l;
}
L l2 = this.supplier.get();
return (L) MoreObjects.firstNonNull(this.locks.putIfAbsent(Integer.valueOf(i), l2), l2);
}
@Override // com.google.common.util.concurrent.Striped
public int size() {
return this.size;
}
}
/* JADX INFO: Access modifiers changed from: private */
public static int ceilToPowerOfTwo(int i) {
return 1 << IntMath.log2(i, RoundingMode.CEILING);
}
/* JADX INFO: Access modifiers changed from: package-private */
/* loaded from: classes2.dex */
public static class PaddedLock extends ReentrantLock {
long unused1;
long unused2;
long unused3;
PaddedLock() {
super(false);
}
}
/* JADX INFO: Access modifiers changed from: package-private */
/* loaded from: classes2.dex */
public static class PaddedSemaphore extends Semaphore {
long unused1;
long unused2;
long unused3;
PaddedSemaphore(int i) {
super(i, false);
}
}
}