262 lines
11 KiB
Java
262 lines
11 KiB
Java
package com.google.firebase.firestore.local;
|
|
|
|
import android.util.SparseArray;
|
|
import com.google.firebase.firestore.local.LruGarbageCollector;
|
|
import com.google.firebase.firestore.util.AsyncQueue;
|
|
import com.google.firebase.firestore.util.Consumer;
|
|
import com.google.firebase.firestore.util.Logger;
|
|
import java.util.Comparator;
|
|
import java.util.Locale;
|
|
import java.util.PriorityQueue;
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
/* loaded from: classes2.dex */
|
|
public class LruGarbageCollector {
|
|
private static final long INITIAL_GC_DELAY_MS = TimeUnit.MINUTES.toMillis(1);
|
|
private static final long REGULAR_GC_DELAY_MS = TimeUnit.MINUTES.toMillis(5);
|
|
private final LruDelegate delegate;
|
|
private final Params params;
|
|
|
|
/* loaded from: classes2.dex */
|
|
public static class Params {
|
|
final int maximumSequenceNumbersToCollect;
|
|
final long minBytesThreshold;
|
|
final int percentileToCollect;
|
|
|
|
public static Params WithCacheSizeBytes(long j) {
|
|
return new Params(j, 10, 1000);
|
|
}
|
|
|
|
Params(long j, int i, int i2) {
|
|
this.minBytesThreshold = j;
|
|
this.percentileToCollect = i;
|
|
this.maximumSequenceNumbersToCollect = i2;
|
|
}
|
|
}
|
|
|
|
/* loaded from: classes2.dex */
|
|
public static class Results {
|
|
private final int documentsRemoved;
|
|
private final boolean hasRun;
|
|
private final int sequenceNumbersCollected;
|
|
private final int targetsRemoved;
|
|
|
|
static Results DidNotRun() {
|
|
return new Results(false, 0, 0, 0);
|
|
}
|
|
|
|
Results(boolean z, int i, int i2, int i3) {
|
|
this.hasRun = z;
|
|
this.sequenceNumbersCollected = i;
|
|
this.targetsRemoved = i2;
|
|
this.documentsRemoved = i3;
|
|
}
|
|
}
|
|
|
|
/* loaded from: classes2.dex */
|
|
public class GCScheduler implements Scheduler {
|
|
private final AsyncQueue asyncQueue;
|
|
private AsyncQueue.DelayedTask gcTask;
|
|
private boolean hasRun = false;
|
|
private final LocalStore localStore;
|
|
final LruGarbageCollector this$0;
|
|
|
|
public GCScheduler(LruGarbageCollector lruGarbageCollector, AsyncQueue asyncQueue, LocalStore localStore) {
|
|
this.this$0 = lruGarbageCollector;
|
|
this.asyncQueue = asyncQueue;
|
|
this.localStore = localStore;
|
|
}
|
|
|
|
@Override // com.google.firebase.firestore.local.Scheduler
|
|
public void start() {
|
|
if (this.this$0.params.minBytesThreshold != -1) {
|
|
scheduleGC();
|
|
}
|
|
}
|
|
|
|
private void scheduleGC() {
|
|
long j;
|
|
if (!this.hasRun) {
|
|
j = LruGarbageCollector.INITIAL_GC_DELAY_MS;
|
|
} else {
|
|
j = LruGarbageCollector.REGULAR_GC_DELAY_MS;
|
|
}
|
|
this.gcTask = this.asyncQueue.enqueueAfterDelay(AsyncQueue.TimerId.GARBAGE_COLLECTION, j, new Runnable(this) { // from class: com.google.firebase.firestore.local.LruGarbageCollector$GCScheduler$$ExternalSyntheticLambda0
|
|
public final LruGarbageCollector.GCScheduler f$0;
|
|
|
|
@Override // java.lang.Runnable
|
|
public final void run() {
|
|
this.f$0.m197xb32188f8();
|
|
}
|
|
|
|
{
|
|
this.f$0 = this;
|
|
}
|
|
});
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: package-private */
|
|
/* renamed from: lambda$scheduleGC$0$com-google-firebase-firestore-local-LruGarbageCollector$GCScheduler, reason: not valid java name */
|
|
public /* synthetic */ void m197xb32188f8() {
|
|
this.localStore.collectGarbage(this.this$0);
|
|
this.hasRun = true;
|
|
scheduleGC();
|
|
}
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: package-private */
|
|
public LruGarbageCollector(LruDelegate lruDelegate, Params params) {
|
|
this.delegate = lruDelegate;
|
|
this.params = params;
|
|
}
|
|
|
|
public GCScheduler newScheduler(AsyncQueue asyncQueue, LocalStore localStore) {
|
|
return new GCScheduler(this, asyncQueue, localStore);
|
|
}
|
|
|
|
int calculateQueryCount(int i) {
|
|
return (int) ((i / 100.0f) * ((float) this.delegate.getSequenceNumberCount()));
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: package-private */
|
|
/* loaded from: classes2.dex */
|
|
public static class RollingSequenceNumberBuffer {
|
|
private static final Comparator<Long> COMPARATOR = new Comparator() { // from class: com.google.firebase.firestore.local.LruGarbageCollector$RollingSequenceNumberBuffer$$ExternalSyntheticLambda0
|
|
@Override // java.util.Comparator
|
|
public final int compare(Object obj, Object obj2) {
|
|
int compareTo;
|
|
compareTo = ((Long) obj2).compareTo((Long) obj);
|
|
return compareTo;
|
|
}
|
|
};
|
|
private final int maxElements;
|
|
private final PriorityQueue<Long> queue;
|
|
|
|
RollingSequenceNumberBuffer(int i) {
|
|
this.maxElements = i;
|
|
this.queue = new PriorityQueue<>(i, COMPARATOR);
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: package-private */
|
|
public void addElement(Long l) {
|
|
if (this.queue.size() < this.maxElements) {
|
|
this.queue.add(l);
|
|
return;
|
|
}
|
|
if (l.longValue() < this.queue.peek().longValue()) {
|
|
this.queue.poll();
|
|
this.queue.add(l);
|
|
}
|
|
}
|
|
|
|
long getMaxValue() {
|
|
return this.queue.peek().longValue();
|
|
}
|
|
}
|
|
|
|
long getNthSequenceNumber(int i) {
|
|
if (i == 0) {
|
|
return -1L;
|
|
}
|
|
final RollingSequenceNumberBuffer rollingSequenceNumberBuffer = new RollingSequenceNumberBuffer(i);
|
|
this.delegate.forEachTarget(new Consumer(rollingSequenceNumberBuffer) { // from class: com.google.firebase.firestore.local.LruGarbageCollector$$ExternalSyntheticLambda0
|
|
public final LruGarbageCollector.RollingSequenceNumberBuffer f$0;
|
|
|
|
@Override // com.google.firebase.firestore.util.Consumer
|
|
public final void accept(Object obj) {
|
|
this.f$0.addElement(Long.valueOf(((TargetData) obj).getSequenceNumber()));
|
|
}
|
|
|
|
{
|
|
this.f$0 = rollingSequenceNumberBuffer;
|
|
}
|
|
});
|
|
this.delegate.forEachOrphanedDocumentSequenceNumber(new Consumer(rollingSequenceNumberBuffer) { // from class: com.google.firebase.firestore.local.LruGarbageCollector$$ExternalSyntheticLambda1
|
|
public final LruGarbageCollector.RollingSequenceNumberBuffer f$0;
|
|
|
|
@Override // com.google.firebase.firestore.util.Consumer
|
|
public final void accept(Object obj) {
|
|
this.f$0.addElement((Long) obj);
|
|
}
|
|
|
|
{
|
|
this.f$0 = rollingSequenceNumberBuffer;
|
|
}
|
|
});
|
|
return rollingSequenceNumberBuffer.getMaxValue();
|
|
}
|
|
|
|
int removeTargets(long j, SparseArray<?> sparseArray) {
|
|
return this.delegate.removeTargets(j, sparseArray);
|
|
}
|
|
|
|
int removeOrphanedDocuments(long j) {
|
|
return this.delegate.removeOrphanedDocuments(j);
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: package-private */
|
|
public Results collect(SparseArray<?> sparseArray) {
|
|
if (this.params.minBytesThreshold == -1) {
|
|
Logger.debug("LruGarbageCollector", "Garbage collection skipped; disabled", new Object[0]);
|
|
return Results.DidNotRun();
|
|
}
|
|
long byteSize = getByteSize();
|
|
if (byteSize < this.params.minBytesThreshold) {
|
|
StringBuilder sb = new StringBuilder("Garbage collection skipped; Cache size ");
|
|
sb.append(byteSize);
|
|
sb.append(" is lower than threshold ");
|
|
sb.append(this.params.minBytesThreshold);
|
|
Logger.debug("LruGarbageCollector", sb.toString(), new Object[0]);
|
|
return Results.DidNotRun();
|
|
}
|
|
return runGarbageCollection(sparseArray);
|
|
}
|
|
|
|
private Results runGarbageCollection(SparseArray<?> sparseArray) {
|
|
long currentTimeMillis = System.currentTimeMillis();
|
|
int calculateQueryCount = calculateQueryCount(this.params.percentileToCollect);
|
|
if (calculateQueryCount > this.params.maximumSequenceNumbersToCollect) {
|
|
StringBuilder sb = new StringBuilder("Capping sequence numbers to collect down to the maximum of ");
|
|
sb.append(this.params.maximumSequenceNumbersToCollect);
|
|
sb.append(" from ");
|
|
sb.append(calculateQueryCount);
|
|
Logger.debug("LruGarbageCollector", sb.toString(), new Object[0]);
|
|
calculateQueryCount = this.params.maximumSequenceNumbersToCollect;
|
|
}
|
|
long currentTimeMillis2 = System.currentTimeMillis();
|
|
long nthSequenceNumber = getNthSequenceNumber(calculateQueryCount);
|
|
long currentTimeMillis3 = System.currentTimeMillis();
|
|
int removeTargets = removeTargets(nthSequenceNumber, sparseArray);
|
|
long currentTimeMillis4 = System.currentTimeMillis();
|
|
int removeOrphanedDocuments = removeOrphanedDocuments(nthSequenceNumber);
|
|
long currentTimeMillis5 = System.currentTimeMillis();
|
|
if (Logger.isDebugEnabled()) {
|
|
StringBuilder sb2 = new StringBuilder("LRU Garbage Collection:\n\tCounted targets in ");
|
|
sb2.append(currentTimeMillis2 - currentTimeMillis);
|
|
sb2.append("ms\n");
|
|
String obj = sb2.toString();
|
|
StringBuilder sb3 = new StringBuilder();
|
|
sb3.append(obj);
|
|
sb3.append(String.format(Locale.ROOT, "\tDetermined least recently used %d sequence numbers in %dms\n", Integer.valueOf(calculateQueryCount), Long.valueOf(currentTimeMillis3 - currentTimeMillis2)));
|
|
String obj2 = sb3.toString();
|
|
StringBuilder sb4 = new StringBuilder();
|
|
sb4.append(obj2);
|
|
sb4.append(String.format(Locale.ROOT, "\tRemoved %d targets in %dms\n", Integer.valueOf(removeTargets), Long.valueOf(currentTimeMillis4 - currentTimeMillis3)));
|
|
String obj3 = sb4.toString();
|
|
StringBuilder sb5 = new StringBuilder();
|
|
sb5.append(obj3);
|
|
sb5.append(String.format(Locale.ROOT, "\tRemoved %d documents in %dms\n", Integer.valueOf(removeOrphanedDocuments), Long.valueOf(currentTimeMillis5 - currentTimeMillis4)));
|
|
String obj4 = sb5.toString();
|
|
StringBuilder sb6 = new StringBuilder();
|
|
sb6.append(obj4);
|
|
sb6.append(String.format(Locale.ROOT, "Total Duration: %dms", Long.valueOf(currentTimeMillis5 - currentTimeMillis)));
|
|
Logger.debug("LruGarbageCollector", sb6.toString(), new Object[0]);
|
|
}
|
|
return new Results(true, calculateQueryCount, removeTargets, removeOrphanedDocuments);
|
|
}
|
|
|
|
long getByteSize() {
|
|
return this.delegate.getByteSize();
|
|
}
|
|
}
|