235 lines
12 KiB
Java
235 lines
12 KiB
Java
package com.google.firebase.firestore.local;
|
|
|
|
import android.database.Cursor;
|
|
import com.google.firebase.Timestamp;
|
|
import com.google.firebase.database.collection.ImmutableSortedMap;
|
|
import com.google.firebase.firestore.local.SQLitePersistence;
|
|
import com.google.firebase.firestore.model.Document;
|
|
import com.google.firebase.firestore.model.DocumentCollections;
|
|
import com.google.firebase.firestore.model.DocumentKey;
|
|
import com.google.firebase.firestore.model.FieldIndex;
|
|
import com.google.firebase.firestore.model.MutableDocument;
|
|
import com.google.firebase.firestore.model.ResourcePath;
|
|
import com.google.firebase.firestore.model.SnapshotVersion;
|
|
import com.google.firebase.firestore.proto.MaybeDocument;
|
|
import com.google.firebase.firestore.util.Assert;
|
|
import com.google.firebase.firestore.util.BackgroundQueue;
|
|
import com.google.firebase.firestore.util.Consumer;
|
|
import com.google.firebase.firestore.util.Executors;
|
|
import com.google.firebase.firestore.util.Util;
|
|
import com.google.protobuf.InvalidProtocolBufferException;
|
|
import java.util.ArrayList;
|
|
import java.util.Collection;
|
|
import java.util.Collections;
|
|
import java.util.HashMap;
|
|
import java.util.Iterator;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
|
|
/* JADX INFO: Access modifiers changed from: package-private */
|
|
/* loaded from: classes2.dex */
|
|
public final class SQLiteRemoteDocumentCache implements RemoteDocumentCache {
|
|
private final SQLitePersistence db;
|
|
private IndexManager indexManager;
|
|
private final LocalSerializer serializer;
|
|
|
|
/* JADX INFO: Access modifiers changed from: package-private */
|
|
public SQLiteRemoteDocumentCache(SQLitePersistence sQLitePersistence, LocalSerializer localSerializer) {
|
|
this.db = sQLitePersistence;
|
|
this.serializer = localSerializer;
|
|
}
|
|
|
|
@Override // com.google.firebase.firestore.local.RemoteDocumentCache
|
|
public final void add(MutableDocument mutableDocument, SnapshotVersion snapshotVersion) {
|
|
Assert.hardAssert(!snapshotVersion.equals(SnapshotVersion.NONE), "Cannot add document to the RemoteDocumentCache with a read time of zero", new Object[0]);
|
|
DocumentKey key = mutableDocument.getKey();
|
|
Timestamp timestamp = snapshotVersion.getTimestamp();
|
|
MaybeDocument encodeMaybeDocument = this.serializer.encodeMaybeDocument(mutableDocument);
|
|
this.db.execute("INSERT OR REPLACE INTO remote_documents (path, path_length, read_time_seconds, read_time_nanos, contents) VALUES (?, ?, ?, ?, ?)", EncodedPath.encode(key.getPath()), Integer.valueOf(key.getPath().length()), Long.valueOf(timestamp.getSeconds()), Integer.valueOf(timestamp.getNanoseconds()), encodeMaybeDocument.toByteArray());
|
|
this.indexManager.addToCollectionParentIndex(mutableDocument.getKey().getCollectionPath());
|
|
}
|
|
|
|
@Override // com.google.firebase.firestore.local.RemoteDocumentCache
|
|
public final void removeAll(Collection<DocumentKey> collection) {
|
|
if (collection.isEmpty()) {
|
|
return;
|
|
}
|
|
ArrayList arrayList = new ArrayList();
|
|
ImmutableSortedMap<DocumentKey, Document> emptyDocumentMap = DocumentCollections.emptyDocumentMap();
|
|
for (DocumentKey documentKey : collection) {
|
|
arrayList.add(EncodedPath.encode(documentKey.getPath()));
|
|
emptyDocumentMap = emptyDocumentMap.insert(documentKey, MutableDocument.newNoDocument(documentKey, SnapshotVersion.NONE));
|
|
}
|
|
SQLitePersistence.LongQuery longQuery = new SQLitePersistence.LongQuery(this.db, "DELETE FROM remote_documents WHERE path IN (", arrayList, ")");
|
|
while (longQuery.hasMoreSubqueries()) {
|
|
longQuery.executeNextSubquery();
|
|
}
|
|
this.indexManager.updateIndexEntries(emptyDocumentMap);
|
|
}
|
|
|
|
@Override // com.google.firebase.firestore.local.RemoteDocumentCache
|
|
public final MutableDocument get(DocumentKey documentKey) {
|
|
return getAll(Collections.singletonList(documentKey)).get(documentKey);
|
|
}
|
|
|
|
@Override // com.google.firebase.firestore.local.RemoteDocumentCache
|
|
public final Map<DocumentKey, MutableDocument> getAll(Iterable<DocumentKey> iterable) {
|
|
final HashMap hashMap = new HashMap();
|
|
ArrayList arrayList = new ArrayList();
|
|
for (DocumentKey documentKey : iterable) {
|
|
arrayList.add(EncodedPath.encode(documentKey.getPath()));
|
|
hashMap.put(documentKey, MutableDocument.newInvalidDocument(documentKey));
|
|
}
|
|
SQLitePersistence.LongQuery longQuery = new SQLitePersistence.LongQuery(this.db, "SELECT contents, read_time_seconds, read_time_nanos FROM remote_documents WHERE path IN (", arrayList, ") ORDER BY path");
|
|
final BackgroundQueue backgroundQueue = new BackgroundQueue();
|
|
while (longQuery.hasMoreSubqueries()) {
|
|
longQuery.performNextSubquery().forEach(new Consumer(this, backgroundQueue, hashMap) { // from class: com.google.firebase.firestore.local.SQLiteRemoteDocumentCache$$ExternalSyntheticLambda2
|
|
public final SQLiteRemoteDocumentCache f$0;
|
|
public final BackgroundQueue f$1;
|
|
public final Map f$2;
|
|
|
|
@Override // com.google.firebase.firestore.util.Consumer
|
|
public final void accept(Object obj) {
|
|
this.f$0.m215xca14d1c3(this.f$1, this.f$2, (Cursor) obj);
|
|
}
|
|
|
|
{
|
|
this.f$0 = this;
|
|
this.f$1 = backgroundQueue;
|
|
this.f$2 = hashMap;
|
|
}
|
|
});
|
|
}
|
|
backgroundQueue.drain();
|
|
return hashMap;
|
|
}
|
|
|
|
@Override // com.google.firebase.firestore.local.RemoteDocumentCache
|
|
public final Map<DocumentKey, MutableDocument> getAll(String str, FieldIndex.IndexOffset indexOffset, int i) {
|
|
List<ResourcePath> collectionParents = this.indexManager.getCollectionParents(str);
|
|
ArrayList arrayList = new ArrayList(collectionParents.size());
|
|
Iterator<ResourcePath> it = collectionParents.iterator();
|
|
while (it.hasNext()) {
|
|
arrayList.add(it.next().append(str));
|
|
}
|
|
if (arrayList.isEmpty()) {
|
|
return Collections.emptyMap();
|
|
}
|
|
if (arrayList.size() * 9 < 900) {
|
|
return getAll(arrayList, indexOffset, i);
|
|
}
|
|
HashMap hashMap = new HashMap();
|
|
int i2 = 0;
|
|
while (i2 < arrayList.size()) {
|
|
int i3 = i2 + 100;
|
|
hashMap.putAll(getAll(arrayList.subList(i2, Math.min(arrayList.size(), i3)), indexOffset, i));
|
|
i2 = i3;
|
|
}
|
|
return Util.firstNEntries(hashMap, i, FieldIndex.IndexOffset.DOCUMENT_COMPARATOR);
|
|
}
|
|
|
|
private Map<DocumentKey, MutableDocument> getAll(List<ResourcePath> list, FieldIndex.IndexOffset indexOffset, int i) {
|
|
Timestamp timestamp = indexOffset.getReadTime().getTimestamp();
|
|
DocumentKey documentKey = indexOffset.getDocumentKey();
|
|
StringBuilder repeatSequence = Util.repeatSequence("SELECT contents, read_time_seconds, read_time_nanos, path FROM remote_documents WHERE path >= ? AND path < ? AND path_length = ? AND (read_time_seconds > ? OR ( read_time_seconds = ? AND read_time_nanos > ?) OR ( read_time_seconds = ? AND read_time_nanos = ? and path > ?)) ", list.size(), " UNION ");
|
|
repeatSequence.append("ORDER BY read_time_seconds, read_time_nanos, path LIMIT ?");
|
|
Object[] objArr = new Object[(list.size() * 9) + 1];
|
|
int i2 = 0;
|
|
for (ResourcePath resourcePath : list) {
|
|
String encode = EncodedPath.encode(resourcePath);
|
|
objArr[i2] = encode;
|
|
objArr[i2 + 1] = EncodedPath.prefixSuccessor(encode);
|
|
objArr[i2 + 2] = Integer.valueOf(resourcePath.length() + 1);
|
|
objArr[i2 + 3] = Long.valueOf(timestamp.getSeconds());
|
|
objArr[i2 + 4] = Long.valueOf(timestamp.getSeconds());
|
|
objArr[i2 + 5] = Integer.valueOf(timestamp.getNanoseconds());
|
|
objArr[i2 + 6] = Long.valueOf(timestamp.getSeconds());
|
|
objArr[i2 + 7] = Integer.valueOf(timestamp.getNanoseconds());
|
|
objArr[i2 + 8] = EncodedPath.encode(documentKey.getPath());
|
|
i2 += 9;
|
|
}
|
|
objArr[i2] = Integer.valueOf(i);
|
|
final BackgroundQueue backgroundQueue = new BackgroundQueue();
|
|
final HashMap hashMap = new HashMap();
|
|
this.db.query(repeatSequence.toString()).binding(objArr).forEach(new Consumer(this, backgroundQueue, hashMap) { // from class: com.google.firebase.firestore.local.SQLiteRemoteDocumentCache$$ExternalSyntheticLambda1
|
|
public final SQLiteRemoteDocumentCache f$0;
|
|
public final BackgroundQueue f$1;
|
|
public final Map f$2;
|
|
|
|
@Override // com.google.firebase.firestore.util.Consumer
|
|
public final void accept(Object obj) {
|
|
this.f$0.m216xbda45604(this.f$1, this.f$2, (Cursor) obj);
|
|
}
|
|
|
|
{
|
|
this.f$0 = this;
|
|
this.f$1 = backgroundQueue;
|
|
this.f$2 = hashMap;
|
|
}
|
|
});
|
|
backgroundQueue.drain();
|
|
return hashMap;
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: private */
|
|
/* JADX WARN: Multi-variable type inference failed */
|
|
/* JADX WARN: Type inference failed for: r8v2, types: [java.util.concurrent.Executor] */
|
|
/* renamed from: processRowInBackground, reason: merged with bridge method [inline-methods] and merged with bridge method [inline-methods] */
|
|
public void m216xbda45604(BackgroundQueue backgroundQueue, final Map<DocumentKey, MutableDocument> map, Cursor cursor) {
|
|
final byte[] blob = cursor.getBlob(0);
|
|
final int i = cursor.getInt(1);
|
|
final int i2 = cursor.getInt(2);
|
|
BackgroundQueue backgroundQueue2 = backgroundQueue;
|
|
if (cursor.isLast()) {
|
|
backgroundQueue2 = Executors.DIRECT_EXECUTOR;
|
|
}
|
|
backgroundQueue2.execute(new Runnable(this, blob, i, i2, map) { // from class: com.google.firebase.firestore.local.SQLiteRemoteDocumentCache$$ExternalSyntheticLambda0
|
|
public final SQLiteRemoteDocumentCache f$0;
|
|
public final byte[] f$1;
|
|
public final int f$2;
|
|
public final int f$3;
|
|
public final Map f$4;
|
|
|
|
@Override // java.lang.Runnable
|
|
public final void run() {
|
|
this.f$0.m217x16ef698(this.f$1, this.f$2, this.f$3, this.f$4);
|
|
}
|
|
|
|
{
|
|
this.f$0 = this;
|
|
this.f$1 = blob;
|
|
this.f$2 = i;
|
|
this.f$3 = i2;
|
|
this.f$4 = map;
|
|
}
|
|
});
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: package-private */
|
|
/* renamed from: lambda$processRowInBackground$2$com-google-firebase-firestore-local-SQLiteRemoteDocumentCache, reason: not valid java name */
|
|
public final /* synthetic */ void m217x16ef698(byte[] bArr, int i, int i2, Map map) {
|
|
MutableDocument decodeMaybeDocument = decodeMaybeDocument(bArr, i, i2);
|
|
synchronized (map) {
|
|
map.put(decodeMaybeDocument.getKey(), decodeMaybeDocument);
|
|
}
|
|
}
|
|
|
|
@Override // com.google.firebase.firestore.local.RemoteDocumentCache
|
|
public final Map<DocumentKey, MutableDocument> getAll(ResourcePath resourcePath, FieldIndex.IndexOffset indexOffset) {
|
|
return getAll(Collections.singletonList(resourcePath), indexOffset, Integer.MAX_VALUE);
|
|
}
|
|
|
|
private MutableDocument decodeMaybeDocument(byte[] bArr, int i, int i2) {
|
|
try {
|
|
return this.serializer.decodeMaybeDocument(MaybeDocument.parseFrom(bArr)).setReadTime(new SnapshotVersion(new Timestamp(i, i2)));
|
|
} catch (InvalidProtocolBufferException e) {
|
|
throw Assert.fail("MaybeDocument failed to parse: %s", e);
|
|
}
|
|
}
|
|
|
|
@Override // com.google.firebase.firestore.local.RemoteDocumentCache
|
|
public final void setIndexManager(IndexManager indexManager) {
|
|
this.indexManager = indexManager;
|
|
}
|
|
}
|