Files
rr3-apk/decompiled-community/sources/okhttp3/internal/cache/DiskLruCache.java
Daniel Elliott c080f0d97f Add Discord community version (64-bit only)
- Added realracing3-community.apk (71.57 MB)
- Removed 32-bit support (armeabi-v7a)
- Only includes arm64-v8a libraries
- Decompiled source code included
- Added README-community.md with analysis
2026-02-18 15:48:36 -08:00

711 lines
26 KiB
Java

package okhttp3.internal.cache;
import com.ironsource.v8;
import java.io.Closeable;
import java.io.EOFException;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.Flushable;
import java.io.IOException;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
import okhttp3.internal.Util;
import okhttp3.internal.io.FileSystem;
import okhttp3.internal.platform.Platform;
import okio.BufferedSink;
import okio.BufferedSource;
import okio.Okio;
import okio.Sink;
import okio.Source;
/* loaded from: classes5.dex */
public final class DiskLruCache implements Closeable, Flushable {
public static final Pattern LEGAL_KEY_PATTERN = Pattern.compile("[a-z0-9_-]{1,120}");
public final int appVersion;
public boolean closed;
public final File directory;
public final Executor executor;
public final FileSystem fileSystem;
public boolean hasJournalErrors;
public boolean initialized;
public final File journalFile;
public final File journalFileBackup;
public final File journalFileTmp;
public BufferedSink journalWriter;
public long maxSize;
public boolean mostRecentRebuildFailed;
public boolean mostRecentTrimFailed;
public int redundantOpCount;
public final int valueCount;
public long size = 0;
public final LinkedHashMap lruEntries = new LinkedHashMap(0, 0.75f, true);
public long nextSequenceNumber = 0;
public final Runnable cleanupRunnable = new Runnable() { // from class: okhttp3.internal.cache.DiskLruCache.1
@Override // java.lang.Runnable
public void run() {
synchronized (DiskLruCache.this) {
DiskLruCache diskLruCache = DiskLruCache.this;
if ((!diskLruCache.initialized) || diskLruCache.closed) {
return;
}
try {
diskLruCache.trimToSize();
} catch (IOException unused) {
DiskLruCache.this.mostRecentTrimFailed = true;
}
try {
if (DiskLruCache.this.journalRebuildRequired()) {
DiskLruCache.this.rebuildJournal();
DiskLruCache.this.redundantOpCount = 0;
}
} catch (IOException unused2) {
DiskLruCache diskLruCache2 = DiskLruCache.this;
diskLruCache2.mostRecentRebuildFailed = true;
diskLruCache2.journalWriter = Okio.buffer(Okio.blackhole());
}
}
}
};
public DiskLruCache(FileSystem fileSystem, File file, int i, int i2, long j, Executor executor) {
this.fileSystem = fileSystem;
this.directory = file;
this.appVersion = i;
this.journalFile = new File(file, "journal");
this.journalFileTmp = new File(file, "journal.tmp");
this.journalFileBackup = new File(file, "journal.bkp");
this.valueCount = i2;
this.maxSize = j;
this.executor = executor;
}
public synchronized void initialize() {
try {
if (this.initialized) {
return;
}
if (this.fileSystem.exists(this.journalFileBackup)) {
if (this.fileSystem.exists(this.journalFile)) {
this.fileSystem.delete(this.journalFileBackup);
} else {
this.fileSystem.rename(this.journalFileBackup, this.journalFile);
}
}
if (this.fileSystem.exists(this.journalFile)) {
try {
readJournal();
processJournal();
this.initialized = true;
return;
} catch (IOException e) {
Platform.get().log(5, "DiskLruCache " + this.directory + " is corrupt: " + e.getMessage() + ", removing", e);
try {
delete();
this.closed = false;
} catch (Throwable th) {
this.closed = false;
throw th;
}
}
}
rebuildJournal();
this.initialized = true;
} catch (Throwable th2) {
throw th2;
}
}
public static DiskLruCache create(FileSystem fileSystem, File file, int i, int i2, long j) {
if (j <= 0) {
throw new IllegalArgumentException("maxSize <= 0");
}
if (i2 <= 0) {
throw new IllegalArgumentException("valueCount <= 0");
}
return new DiskLruCache(fileSystem, file, i, i2, j, new ThreadPoolExecutor(0, 1, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue(), Util.threadFactory("OkHttp DiskLruCache", true)));
}
public final void readJournal() {
BufferedSource buffer = Okio.buffer(this.fileSystem.source(this.journalFile));
try {
String readUtf8LineStrict = buffer.readUtf8LineStrict();
String readUtf8LineStrict2 = buffer.readUtf8LineStrict();
String readUtf8LineStrict3 = buffer.readUtf8LineStrict();
String readUtf8LineStrict4 = buffer.readUtf8LineStrict();
String readUtf8LineStrict5 = buffer.readUtf8LineStrict();
if (!"libcore.io.DiskLruCache".equals(readUtf8LineStrict) || !"1".equals(readUtf8LineStrict2) || !Integer.toString(this.appVersion).equals(readUtf8LineStrict3) || !Integer.toString(this.valueCount).equals(readUtf8LineStrict4) || !"".equals(readUtf8LineStrict5)) {
throw new IOException("unexpected journal header: [" + readUtf8LineStrict + ", " + readUtf8LineStrict2 + ", " + readUtf8LineStrict4 + ", " + readUtf8LineStrict5 + v8.i.e);
}
int i = 0;
while (true) {
try {
readJournalLine(buffer.readUtf8LineStrict());
i++;
} catch (EOFException unused) {
this.redundantOpCount = i - this.lruEntries.size();
if (!buffer.exhausted()) {
rebuildJournal();
} else {
this.journalWriter = newJournalWriter();
}
$closeResource(null, buffer);
return;
}
}
} finally {
}
}
public static /* synthetic */ void $closeResource(Throwable th, AutoCloseable autoCloseable) {
if (th == null) {
autoCloseable.close();
return;
}
try {
autoCloseable.close();
} catch (Throwable th2) {
th.addSuppressed(th2);
}
}
public final BufferedSink newJournalWriter() {
return Okio.buffer(new FaultHidingSink(this.fileSystem.appendingSink(this.journalFile)) { // from class: okhttp3.internal.cache.DiskLruCache.2
@Override // okhttp3.internal.cache.FaultHidingSink
public void onException(IOException iOException) {
DiskLruCache.this.hasJournalErrors = true;
}
});
}
public final void readJournalLine(String str) {
String substring;
int indexOf = str.indexOf(32);
if (indexOf == -1) {
throw new IOException("unexpected journal line: " + str);
}
int i = indexOf + 1;
int indexOf2 = str.indexOf(32, i);
if (indexOf2 == -1) {
substring = str.substring(i);
if (indexOf == 6 && str.startsWith("REMOVE")) {
this.lruEntries.remove(substring);
return;
}
} else {
substring = str.substring(i, indexOf2);
}
Entry entry = (Entry) this.lruEntries.get(substring);
if (entry == null) {
entry = new Entry(substring);
this.lruEntries.put(substring, entry);
}
if (indexOf2 != -1 && indexOf == 5 && str.startsWith("CLEAN")) {
String[] split = str.substring(indexOf2 + 1).split(" ");
entry.readable = true;
entry.currentEditor = null;
entry.setLengths(split);
return;
}
if (indexOf2 == -1 && indexOf == 5 && str.startsWith("DIRTY")) {
entry.currentEditor = new Editor(entry);
return;
}
if (indexOf2 == -1 && indexOf == 4 && str.startsWith("READ")) {
return;
}
throw new IOException("unexpected journal line: " + str);
}
public final void processJournal() {
this.fileSystem.delete(this.journalFileTmp);
Iterator it = this.lruEntries.values().iterator();
while (it.hasNext()) {
Entry entry = (Entry) it.next();
int i = 0;
if (entry.currentEditor == null) {
while (i < this.valueCount) {
this.size += entry.lengths[i];
i++;
}
} else {
entry.currentEditor = null;
while (i < this.valueCount) {
this.fileSystem.delete(entry.cleanFiles[i]);
this.fileSystem.delete(entry.dirtyFiles[i]);
i++;
}
it.remove();
}
}
}
public synchronized void rebuildJournal() {
try {
BufferedSink bufferedSink = this.journalWriter;
if (bufferedSink != null) {
bufferedSink.close();
}
BufferedSink buffer = Okio.buffer(this.fileSystem.sink(this.journalFileTmp));
try {
buffer.writeUtf8("libcore.io.DiskLruCache").writeByte(10);
buffer.writeUtf8("1").writeByte(10);
buffer.writeDecimalLong(this.appVersion).writeByte(10);
buffer.writeDecimalLong(this.valueCount).writeByte(10);
buffer.writeByte(10);
for (Entry entry : this.lruEntries.values()) {
if (entry.currentEditor != null) {
buffer.writeUtf8("DIRTY").writeByte(32);
buffer.writeUtf8(entry.key);
buffer.writeByte(10);
} else {
buffer.writeUtf8("CLEAN").writeByte(32);
buffer.writeUtf8(entry.key);
entry.writeLengths(buffer);
buffer.writeByte(10);
}
}
$closeResource(null, buffer);
if (this.fileSystem.exists(this.journalFile)) {
this.fileSystem.rename(this.journalFile, this.journalFileBackup);
}
this.fileSystem.rename(this.journalFileTmp, this.journalFile);
this.fileSystem.delete(this.journalFileBackup);
this.journalWriter = newJournalWriter();
this.hasJournalErrors = false;
this.mostRecentRebuildFailed = false;
} finally {
}
} catch (Throwable th) {
throw th;
}
}
public synchronized Snapshot get(String str) {
initialize();
checkNotClosed();
validateKey(str);
Entry entry = (Entry) this.lruEntries.get(str);
if (entry != null && entry.readable) {
Snapshot snapshot = entry.snapshot();
if (snapshot == null) {
return null;
}
this.redundantOpCount++;
this.journalWriter.writeUtf8("READ").writeByte(32).writeUtf8(str).writeByte(10);
if (journalRebuildRequired()) {
this.executor.execute(this.cleanupRunnable);
}
return snapshot;
}
return null;
}
public Editor edit(String str) {
return edit(str, -1L);
}
public synchronized Editor edit(String str, long j) {
initialize();
checkNotClosed();
validateKey(str);
Entry entry = (Entry) this.lruEntries.get(str);
if (j != -1 && (entry == null || entry.sequenceNumber != j)) {
return null;
}
if (entry != null && entry.currentEditor != null) {
return null;
}
if (!this.mostRecentTrimFailed && !this.mostRecentRebuildFailed) {
this.journalWriter.writeUtf8("DIRTY").writeByte(32).writeUtf8(str).writeByte(10);
this.journalWriter.flush();
if (this.hasJournalErrors) {
return null;
}
if (entry == null) {
entry = new Entry(str);
this.lruEntries.put(str, entry);
}
Editor editor = new Editor(entry);
entry.currentEditor = editor;
return editor;
}
this.executor.execute(this.cleanupRunnable);
return null;
}
public synchronized void completeEdit(Editor editor, boolean z) {
Entry entry = editor.entry;
if (entry.currentEditor != editor) {
throw new IllegalStateException();
}
if (z && !entry.readable) {
for (int i = 0; i < this.valueCount; i++) {
if (!editor.written[i]) {
editor.abort();
throw new IllegalStateException("Newly created entry didn't create value for index " + i);
}
if (!this.fileSystem.exists(entry.dirtyFiles[i])) {
editor.abort();
return;
}
}
}
for (int i2 = 0; i2 < this.valueCount; i2++) {
File file = entry.dirtyFiles[i2];
if (z) {
if (this.fileSystem.exists(file)) {
File file2 = entry.cleanFiles[i2];
this.fileSystem.rename(file, file2);
long j = entry.lengths[i2];
long size = this.fileSystem.size(file2);
entry.lengths[i2] = size;
this.size = (this.size - j) + size;
}
} else {
this.fileSystem.delete(file);
}
}
this.redundantOpCount++;
entry.currentEditor = null;
if (entry.readable | z) {
entry.readable = true;
this.journalWriter.writeUtf8("CLEAN").writeByte(32);
this.journalWriter.writeUtf8(entry.key);
entry.writeLengths(this.journalWriter);
this.journalWriter.writeByte(10);
if (z) {
long j2 = this.nextSequenceNumber;
this.nextSequenceNumber = 1 + j2;
entry.sequenceNumber = j2;
}
} else {
this.lruEntries.remove(entry.key);
this.journalWriter.writeUtf8("REMOVE").writeByte(32);
this.journalWriter.writeUtf8(entry.key);
this.journalWriter.writeByte(10);
}
this.journalWriter.flush();
if (this.size > this.maxSize || journalRebuildRequired()) {
this.executor.execute(this.cleanupRunnable);
}
}
public boolean journalRebuildRequired() {
int i = this.redundantOpCount;
return i >= 2000 && i >= this.lruEntries.size();
}
public synchronized boolean remove(String str) {
initialize();
checkNotClosed();
validateKey(str);
Entry entry = (Entry) this.lruEntries.get(str);
if (entry == null) {
return false;
}
boolean removeEntry = removeEntry(entry);
if (removeEntry && this.size <= this.maxSize) {
this.mostRecentTrimFailed = false;
}
return removeEntry;
}
public boolean removeEntry(Entry entry) {
Editor editor = entry.currentEditor;
if (editor != null) {
editor.detach();
}
for (int i = 0; i < this.valueCount; i++) {
this.fileSystem.delete(entry.cleanFiles[i]);
long j = this.size;
long[] jArr = entry.lengths;
this.size = j - jArr[i];
jArr[i] = 0;
}
this.redundantOpCount++;
this.journalWriter.writeUtf8("REMOVE").writeByte(32).writeUtf8(entry.key).writeByte(10);
this.lruEntries.remove(entry.key);
if (journalRebuildRequired()) {
this.executor.execute(this.cleanupRunnable);
}
return true;
}
public synchronized boolean isClosed() {
return this.closed;
}
public final synchronized void checkNotClosed() {
if (isClosed()) {
throw new IllegalStateException("cache is closed");
}
}
@Override // java.io.Flushable
public synchronized void flush() {
if (this.initialized) {
checkNotClosed();
trimToSize();
this.journalWriter.flush();
}
}
@Override // java.io.Closeable, java.lang.AutoCloseable
public synchronized void close() {
try {
if (this.initialized && !this.closed) {
for (Entry entry : (Entry[]) this.lruEntries.values().toArray(new Entry[this.lruEntries.size()])) {
Editor editor = entry.currentEditor;
if (editor != null) {
editor.abort();
}
}
trimToSize();
this.journalWriter.close();
this.journalWriter = null;
this.closed = true;
return;
}
this.closed = true;
} catch (Throwable th) {
throw th;
}
}
public void trimToSize() {
while (this.size > this.maxSize) {
removeEntry((Entry) this.lruEntries.values().iterator().next());
}
this.mostRecentTrimFailed = false;
}
public void delete() {
close();
this.fileSystem.deleteContents(this.directory);
}
public final void validateKey(String str) {
if (LEGAL_KEY_PATTERN.matcher(str).matches()) {
return;
}
throw new IllegalArgumentException("keys must match regex [a-z0-9_-]{1,120}: \"" + str + "\"");
}
public final class Snapshot implements Closeable {
public final String key;
public final long[] lengths;
public final long sequenceNumber;
public final Source[] sources;
public Snapshot(String str, long j, Source[] sourceArr, long[] jArr) {
this.key = str;
this.sequenceNumber = j;
this.sources = sourceArr;
this.lengths = jArr;
}
public Editor edit() {
return DiskLruCache.this.edit(this.key, this.sequenceNumber);
}
public Source getSource(int i) {
return this.sources[i];
}
@Override // java.io.Closeable, java.lang.AutoCloseable
public void close() {
for (Source source : this.sources) {
Util.closeQuietly(source);
}
}
}
public final class Editor {
public boolean done;
public final Entry entry;
public final boolean[] written;
public Editor(Entry entry) {
this.entry = entry;
this.written = entry.readable ? null : new boolean[DiskLruCache.this.valueCount];
}
public void detach() {
if (this.entry.currentEditor != this) {
return;
}
int i = 0;
while (true) {
DiskLruCache diskLruCache = DiskLruCache.this;
if (i < diskLruCache.valueCount) {
try {
diskLruCache.fileSystem.delete(this.entry.dirtyFiles[i]);
} catch (IOException unused) {
}
i++;
} else {
this.entry.currentEditor = null;
return;
}
}
}
public Sink newSink(int i) {
synchronized (DiskLruCache.this) {
try {
if (this.done) {
throw new IllegalStateException();
}
Entry entry = this.entry;
if (entry.currentEditor != this) {
return Okio.blackhole();
}
if (!entry.readable) {
this.written[i] = true;
}
try {
return new FaultHidingSink(DiskLruCache.this.fileSystem.sink(entry.dirtyFiles[i])) { // from class: okhttp3.internal.cache.DiskLruCache.Editor.1
@Override // okhttp3.internal.cache.FaultHidingSink
public void onException(IOException iOException) {
synchronized (DiskLruCache.this) {
Editor.this.detach();
}
}
};
} catch (FileNotFoundException unused) {
return Okio.blackhole();
}
} catch (Throwable th) {
throw th;
}
}
}
public void commit() {
synchronized (DiskLruCache.this) {
try {
if (this.done) {
throw new IllegalStateException();
}
if (this.entry.currentEditor == this) {
DiskLruCache.this.completeEdit(this, true);
}
this.done = true;
} catch (Throwable th) {
throw th;
}
}
}
public void abort() {
synchronized (DiskLruCache.this) {
try {
if (this.done) {
throw new IllegalStateException();
}
if (this.entry.currentEditor == this) {
DiskLruCache.this.completeEdit(this, false);
}
this.done = true;
} catch (Throwable th) {
throw th;
}
}
}
}
public final class Entry {
public final File[] cleanFiles;
public Editor currentEditor;
public final File[] dirtyFiles;
public final String key;
public final long[] lengths;
public boolean readable;
public long sequenceNumber;
public Entry(String str) {
this.key = str;
int i = DiskLruCache.this.valueCount;
this.lengths = new long[i];
this.cleanFiles = new File[i];
this.dirtyFiles = new File[i];
StringBuilder sb = new StringBuilder(str);
sb.append('.');
int length = sb.length();
for (int i2 = 0; i2 < DiskLruCache.this.valueCount; i2++) {
sb.append(i2);
this.cleanFiles[i2] = new File(DiskLruCache.this.directory, sb.toString());
sb.append(".tmp");
this.dirtyFiles[i2] = new File(DiskLruCache.this.directory, sb.toString());
sb.setLength(length);
}
}
public void setLengths(String[] strArr) {
if (strArr.length != DiskLruCache.this.valueCount) {
throw invalidLengths(strArr);
}
for (int i = 0; i < strArr.length; i++) {
try {
this.lengths[i] = Long.parseLong(strArr[i]);
} catch (NumberFormatException unused) {
throw invalidLengths(strArr);
}
}
}
public void writeLengths(BufferedSink bufferedSink) {
for (long j : this.lengths) {
bufferedSink.writeByte(32).writeDecimalLong(j);
}
}
public final IOException invalidLengths(String[] strArr) {
throw new IOException("unexpected journal line: " + Arrays.toString(strArr));
}
public Snapshot snapshot() {
Source source;
if (!Thread.holdsLock(DiskLruCache.this)) {
throw new AssertionError();
}
Source[] sourceArr = new Source[DiskLruCache.this.valueCount];
long[] jArr = (long[]) this.lengths.clone();
int i = 0;
int i2 = 0;
while (true) {
try {
DiskLruCache diskLruCache = DiskLruCache.this;
if (i2 < diskLruCache.valueCount) {
sourceArr[i2] = diskLruCache.fileSystem.source(this.cleanFiles[i2]);
i2++;
} else {
return diskLruCache.new Snapshot(this.key, this.sequenceNumber, sourceArr, jArr);
}
} catch (FileNotFoundException unused) {
while (true) {
DiskLruCache diskLruCache2 = DiskLruCache.this;
if (i < diskLruCache2.valueCount && (source = sourceArr[i]) != null) {
Util.closeQuietly(source);
i++;
} else {
try {
diskLruCache2.removeEntry(this);
return null;
} catch (IOException unused2) {
return null;
}
}
}
}
}
}
}
}