what-the-bank/sources/com/google/firebase/firestore/local/SQLiteIndexManager.java

631 lines
31 KiB
Java
Raw Permalink Normal View History

2024-07-27 18:17:47 +07:00
package com.google.firebase.firestore.local;
import android.database.Cursor;
import android.text.TextUtils;
import com.airbnb.deeplinkdispatch.UrlTreeKt;
import com.google.firebase.Timestamp;
import com.google.firebase.database.collection.ImmutableSortedMap;
import com.google.firebase.firestore.auth.User;
import com.google.firebase.firestore.core.Bound;
import com.google.firebase.firestore.core.CompositeFilter;
import com.google.firebase.firestore.core.FieldFilter;
import com.google.firebase.firestore.core.Filter;
import com.google.firebase.firestore.core.OrderBy;
import com.google.firebase.firestore.core.Target;
import com.google.firebase.firestore.index.FirestoreIndexValueWriter;
import com.google.firebase.firestore.index.IndexByteEncoder;
import com.google.firebase.firestore.index.IndexEntry;
import com.google.firebase.firestore.local.IndexManager;
import com.google.firebase.firestore.local.MemoryIndexManager;
import com.google.firebase.firestore.local.SQLitePersistence;
import com.google.firebase.firestore.model.Document;
import com.google.firebase.firestore.model.DocumentKey;
import com.google.firebase.firestore.model.FieldIndex;
import com.google.firebase.firestore.model.FieldPath;
import com.google.firebase.firestore.model.ResourcePath;
import com.google.firebase.firestore.model.SnapshotVersion;
import com.google.firebase.firestore.model.TargetIndexMatcher;
import com.google.firebase.firestore.model.Values;
import com.google.firebase.firestore.util.Assert;
import com.google.firebase.firestore.util.Consumer;
import com.google.firebase.firestore.util.Logger;
import com.google.firebase.firestore.util.LogicUtils;
import com.google.firebase.firestore.util.Util;
import com.google.protobuf.InvalidProtocolBufferException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.SortedSet;
import java.util.TreeSet;
import o.ECo;
import o.sbb;
import o.uOO;
/* JADX INFO: Access modifiers changed from: package-private */
/* loaded from: classes2.dex */
public final class SQLiteIndexManager implements IndexManager {
private static final byte[] EMPTY_BYTES_VALUE = new byte[0];
private static final String TAG = "SQLiteIndexManager";
private final SQLitePersistence db;
private final LocalSerializer serializer;
private final String uid;
private final Map<Target, List<Target>> targetToDnfSubTargets = new HashMap();
private final MemoryIndexManager.MemoryCollectionParentIndex collectionParentsCache = new MemoryIndexManager.MemoryCollectionParentIndex();
private final Map<String, Map<Integer, FieldIndex>> memoizedIndexes = new HashMap();
private final Queue<FieldIndex> nextIndexToUpdate = new PriorityQueue(10, new Comparator() { // from class: com.google.firebase.firestore.local.SQLiteIndexManager$$ExternalSyntheticLambda3
@Override // java.util.Comparator
public final int compare(Object obj, Object obj2) {
return SQLiteIndexManager.lambda$new$0((FieldIndex) obj, (FieldIndex) obj2);
}
});
private boolean started = false;
private int memoizedMaxIndexId = -1;
private long memoizedMaxSequenceNumber = -1;
/* JADX INFO: Access modifiers changed from: package-private */
public static /* synthetic */ int lambda$new$0(FieldIndex fieldIndex, FieldIndex fieldIndex2) {
int compare = Long.compare(fieldIndex.getIndexState().getSequenceNumber(), fieldIndex2.getIndexState().getSequenceNumber());
return compare == 0 ? fieldIndex.getCollectionGroup().compareTo(fieldIndex2.getCollectionGroup()) : compare;
}
/* JADX INFO: Access modifiers changed from: package-private */
public SQLiteIndexManager(SQLitePersistence sQLitePersistence, LocalSerializer localSerializer, User user) {
this.db = sQLitePersistence;
this.serializer = localSerializer;
this.uid = user.isAuthenticated() ? user.getUid() : "";
}
@Override // com.google.firebase.firestore.local.IndexManager
public final void start() {
final HashMap hashMap = new HashMap();
this.db.query("SELECT index_id, sequence_number, read_time_seconds, read_time_nanos, document_key, largest_batch_id FROM index_state WHERE uid = ?").binding(this.uid).forEach(new Consumer(hashMap) { // from class: com.google.firebase.firestore.local.SQLiteIndexManager$$ExternalSyntheticLambda6
public final Map f$0;
@Override // com.google.firebase.firestore.util.Consumer
public final void accept(Object obj) {
SQLiteIndexManager.lambda$start$1(this.f$0, (Cursor) obj);
}
{
this.f$0 = hashMap;
}
});
this.db.query("SELECT index_id, collection_group, index_proto FROM index_configuration").forEach(new Consumer(this, hashMap) { // from class: com.google.firebase.firestore.local.SQLiteIndexManager$$ExternalSyntheticLambda7
public final SQLiteIndexManager f$0;
public final Map f$1;
@Override // com.google.firebase.firestore.util.Consumer
public final void accept(Object obj) {
this.f$0.m204x30c0807a(this.f$1, (Cursor) obj);
}
{
this.f$0 = this;
this.f$1 = hashMap;
}
});
this.started = true;
}
/* JADX INFO: Access modifiers changed from: package-private */
public static /* synthetic */ void lambda$start$1(Map map, Cursor cursor) {
int i = cursor.getInt(0);
map.put(Integer.valueOf(i), FieldIndex.IndexState.create(cursor.getLong(1), new SnapshotVersion(new Timestamp(cursor.getLong(2), cursor.getInt(3))), DocumentKey.fromPath(EncodedPath.decodeResourcePath(cursor.getString(4))), cursor.getInt(5)));
}
/* JADX INFO: Access modifiers changed from: package-private */
/* renamed from: lambda$start$2$com-google-firebase-firestore-local-SQLiteIndexManager, reason: not valid java name */
public final /* synthetic */ void m204x30c0807a(Map map, Cursor cursor) {
FieldIndex.IndexState indexState;
try {
int i = cursor.getInt(0);
String string = cursor.getString(1);
List<FieldIndex.Segment> decodeFieldIndexSegments = this.serializer.decodeFieldIndexSegments(ECo.c(cursor.getBlob(2)));
if (map.containsKey(Integer.valueOf(i))) {
indexState = (FieldIndex.IndexState) map.get(Integer.valueOf(i));
} else {
indexState = FieldIndex.INITIAL_STATE;
}
memoizeIndex(FieldIndex.create(i, string, decodeFieldIndexSegments, indexState));
} catch (InvalidProtocolBufferException e) {
throw Assert.fail("Failed to decode index: ".concat(String.valueOf(e)), new Object[0]);
}
}
@Override // com.google.firebase.firestore.local.IndexManager
public final void addToCollectionParentIndex(ResourcePath resourcePath) {
Assert.hardAssert(this.started, "IndexManager not started", new Object[0]);
Assert.hardAssert(resourcePath.length() % 2 == 1, "Expected a collection path.", new Object[0]);
if (this.collectionParentsCache.add(resourcePath)) {
this.db.execute("INSERT OR REPLACE INTO collection_parents (collection_id, parent) VALUES (?, ?)", resourcePath.getLastSegment(), EncodedPath.encode(resourcePath.popLast()));
}
}
@Override // com.google.firebase.firestore.local.IndexManager
public final List<ResourcePath> getCollectionParents(String str) {
Assert.hardAssert(this.started, "IndexManager not started", new Object[0]);
final ArrayList arrayList = new ArrayList();
this.db.query("SELECT parent FROM collection_parents WHERE collection_id = ?").binding(str).forEach(new Consumer(arrayList) { // from class: com.google.firebase.firestore.local.SQLiteIndexManager$$ExternalSyntheticLambda4
public final ArrayList f$0;
@Override // com.google.firebase.firestore.util.Consumer
public final void accept(Object obj) {
this.f$0.add(EncodedPath.decodeResourcePath(((Cursor) obj).getString(0)));
}
{
this.f$0 = arrayList;
}
});
return arrayList;
}
@Override // com.google.firebase.firestore.local.IndexManager
public final String getNextCollectionGroupToUpdate() {
Assert.hardAssert(this.started, "IndexManager not started", new Object[0]);
FieldIndex peek = this.nextIndexToUpdate.peek();
if (peek != null) {
return peek.getCollectionGroup();
}
return null;
}
@Override // com.google.firebase.firestore.local.IndexManager
public final void updateIndexEntries(ImmutableSortedMap<DocumentKey, Document> immutableSortedMap) {
Assert.hardAssert(this.started, "IndexManager not started", new Object[0]);
Iterator<Map.Entry<DocumentKey, Document>> it = immutableSortedMap.iterator();
while (it.hasNext()) {
Map.Entry<DocumentKey, Document> next = it.next();
for (FieldIndex fieldIndex : getFieldIndexes(next.getKey().getCollectionGroup())) {
SortedSet<IndexEntry> existingIndexEntries = getExistingIndexEntries(next.getKey(), fieldIndex);
SortedSet<IndexEntry> computeIndexEntries = computeIndexEntries(next.getValue(), fieldIndex);
if (!existingIndexEntries.equals(computeIndexEntries)) {
updateEntries(next.getValue(), existingIndexEntries, computeIndexEntries);
}
}
}
}
private void updateEntries(final Document document, SortedSet<IndexEntry> sortedSet, SortedSet<IndexEntry> sortedSet2) {
Logger.debug(TAG, "Updating index entries for document '%s'", document.getKey());
Util.diffCollections(sortedSet, sortedSet2, new Consumer(this, document) { // from class: com.google.firebase.firestore.local.SQLiteIndexManager$$ExternalSyntheticLambda1
public final SQLiteIndexManager f$0;
public final Document f$1;
@Override // com.google.firebase.firestore.util.Consumer
public final void accept(Object obj) {
this.f$0.m205x55deb5b3(this.f$1, (IndexEntry) obj);
}
{
this.f$0 = this;
this.f$1 = document;
}
}, new Consumer(this, document) { // from class: com.google.firebase.firestore.local.SQLiteIndexManager$$ExternalSyntheticLambda2
public final SQLiteIndexManager f$0;
public final Document f$1;
@Override // com.google.firebase.firestore.util.Consumer
public final void accept(Object obj) {
this.f$0.m206x57150892(this.f$1, (IndexEntry) obj);
}
{
this.f$0 = this;
this.f$1 = document;
}
});
}
public final Collection<FieldIndex> getFieldIndexes(String str) {
Assert.hardAssert(this.started, "IndexManager not started", new Object[0]);
Map<Integer, FieldIndex> map = this.memoizedIndexes.get(str);
return map == null ? Collections.emptyList() : map.values();
}
private FieldIndex.IndexOffset getMinOffset(Collection<FieldIndex> collection) {
Assert.hardAssert(!collection.isEmpty(), "Found empty index group when looking for least recent index offset.", new Object[0]);
Iterator<FieldIndex> it = collection.iterator();
FieldIndex.IndexOffset offset = it.next().getIndexState().getOffset();
int largestBatchId = offset.getLargestBatchId();
while (it.hasNext()) {
FieldIndex.IndexOffset offset2 = it.next().getIndexState().getOffset();
if (offset2.compareTo(offset) < 0) {
offset = offset2;
}
largestBatchId = Math.max(offset2.getLargestBatchId(), largestBatchId);
}
return FieldIndex.IndexOffset.create(offset.getReadTime(), offset.getDocumentKey(), largestBatchId);
}
@Override // com.google.firebase.firestore.local.IndexManager
public final FieldIndex.IndexOffset getMinOffset(String str) {
Collection<FieldIndex> fieldIndexes = getFieldIndexes(str);
Assert.hardAssert(!fieldIndexes.isEmpty(), "minOffset was called for collection without indexes", new Object[0]);
return getMinOffset(fieldIndexes);
}
@Override // com.google.firebase.firestore.local.IndexManager
public final IndexManager.IndexType getIndexType(Target target) {
IndexManager.IndexType indexType = IndexManager.IndexType.FULL;
List<Target> subTargets = getSubTargets(target);
Iterator<Target> it = subTargets.iterator();
while (true) {
if (!it.hasNext()) {
break;
}
Target next = it.next();
FieldIndex fieldIndex = getFieldIndex(next);
if (fieldIndex == null) {
indexType = IndexManager.IndexType.NONE;
break;
}
if (fieldIndex.getSegments().size() < next.getSegmentCount()) {
indexType = IndexManager.IndexType.PARTIAL;
}
}
return (target.hasLimit() && subTargets.size() > 1 && indexType == IndexManager.IndexType.FULL) ? IndexManager.IndexType.PARTIAL : indexType;
}
@Override // com.google.firebase.firestore.local.IndexManager
public final FieldIndex.IndexOffset getMinOffset(Target target) {
ArrayList arrayList = new ArrayList();
Iterator<Target> it = getSubTargets(target).iterator();
while (it.hasNext()) {
FieldIndex fieldIndex = getFieldIndex(it.next());
if (fieldIndex != null) {
arrayList.add(fieldIndex);
}
}
return getMinOffset(arrayList);
}
private List<Target> getSubTargets(Target target) {
if (this.targetToDnfSubTargets.containsKey(target)) {
return this.targetToDnfSubTargets.get(target);
}
ArrayList arrayList = new ArrayList();
if (target.getFilters().isEmpty()) {
arrayList.add(target);
} else {
Iterator<Filter> it = LogicUtils.getDnfTerms(new CompositeFilter(target.getFilters(), CompositeFilter.Operator.AND)).iterator();
while (it.hasNext()) {
arrayList.add(new Target(target.getPath(), target.getCollectionGroup(), it.next().getFilters(), target.getOrderBy(), target.getLimit(), target.getStartAt(), target.getEndAt()));
}
}
this.targetToDnfSubTargets.put(target, arrayList);
return arrayList;
}
private void memoizeIndex(FieldIndex fieldIndex) {
Map<Integer, FieldIndex> map = this.memoizedIndexes.get(fieldIndex.getCollectionGroup());
if (map == null) {
map = new HashMap<>();
this.memoizedIndexes.put(fieldIndex.getCollectionGroup(), map);
}
FieldIndex fieldIndex2 = map.get(Integer.valueOf(fieldIndex.getIndexId()));
if (fieldIndex2 != null) {
this.nextIndexToUpdate.remove(fieldIndex2);
}
map.put(Integer.valueOf(fieldIndex.getIndexId()), fieldIndex);
this.nextIndexToUpdate.add(fieldIndex);
this.memoizedMaxIndexId = Math.max(this.memoizedMaxIndexId, fieldIndex.getIndexId());
this.memoizedMaxSequenceNumber = Math.max(this.memoizedMaxSequenceNumber, fieldIndex.getIndexState().getSequenceNumber());
}
private SortedSet<IndexEntry> computeIndexEntries(Document document, FieldIndex fieldIndex) {
uOO e;
TreeSet treeSet = new TreeSet();
byte[] encodeDirectionalElements = encodeDirectionalElements(fieldIndex, document);
if (encodeDirectionalElements == null) {
return treeSet;
}
FieldIndex.Segment arraySegment = fieldIndex.getArraySegment();
if (arraySegment != null) {
sbb field = document.getField(arraySegment.getFieldPath());
if (Values.isArray(field)) {
if (field.valueTypeCase_ == 9) {
e = (uOO) field.valueType_;
} else {
e = uOO.e();
}
Iterator<sbb> it = e.values_.iterator();
while (it.hasNext()) {
treeSet.add(IndexEntry.create(fieldIndex.getIndexId(), document.getKey(), encodeSingleElement(it.next()), encodeDirectionalElements));
}
}
} else {
treeSet.add(IndexEntry.create(fieldIndex.getIndexId(), document.getKey(), new byte[0], encodeDirectionalElements));
}
return treeSet;
}
/* JADX INFO: Access modifiers changed from: private */
/* renamed from: addIndexEntry, reason: merged with bridge method [inline-methods] */
public void m205x55deb5b3(Document document, IndexEntry indexEntry) {
SQLitePersistence sQLitePersistence = this.db;
int indexId = indexEntry.getIndexId();
sQLitePersistence.execute("INSERT INTO index_entries (index_id, uid, array_value, directional_value, document_key) VALUES(?, ?, ?, ?, ?)", Integer.valueOf(indexId), this.uid, indexEntry.getArrayValue(), indexEntry.getDirectionalValue(), document.getKey().toString());
}
/* JADX INFO: Access modifiers changed from: private */
/* renamed from: deleteIndexEntry, reason: merged with bridge method [inline-methods] */
public void m206x57150892(Document document, IndexEntry indexEntry) {
SQLitePersistence sQLitePersistence = this.db;
int indexId = indexEntry.getIndexId();
sQLitePersistence.execute("DELETE FROM index_entries WHERE index_id = ? AND uid = ? AND array_value = ? AND directional_value = ? AND document_key = ?", Integer.valueOf(indexId), this.uid, indexEntry.getArrayValue(), indexEntry.getDirectionalValue(), document.getKey().toString());
}
private SortedSet<IndexEntry> getExistingIndexEntries(final DocumentKey documentKey, final FieldIndex fieldIndex) {
final TreeSet treeSet = new TreeSet();
SQLitePersistence.Query query = this.db.query("SELECT array_value, directional_value FROM index_entries WHERE index_id = ? AND document_key = ? AND uid = ?");
int indexId = fieldIndex.getIndexId();
query.binding(Integer.valueOf(indexId), documentKey.toString(), this.uid).forEach(new Consumer(treeSet, fieldIndex, documentKey) { // from class: com.google.firebase.firestore.local.SQLiteIndexManager$$ExternalSyntheticLambda5
public final SortedSet f$0;
public final FieldIndex f$1;
public final DocumentKey f$2;
@Override // com.google.firebase.firestore.util.Consumer
public final void accept(Object obj) {
this.f$0.add(IndexEntry.create(this.f$1.getIndexId(), this.f$2, r4.getBlob(0), ((Cursor) obj).getBlob(1)));
}
{
this.f$0 = treeSet;
this.f$1 = fieldIndex;
this.f$2 = documentKey;
}
});
return treeSet;
}
@Override // com.google.firebase.firestore.local.IndexManager
public final List<DocumentKey> getDocumentsMatchingTarget(Target target) {
Assert.hardAssert(this.started, "IndexManager not started", new Object[0]);
ArrayList arrayList = new ArrayList();
ArrayList arrayList2 = new ArrayList();
Iterator<Target> it = getSubTargets(target).iterator();
while (true) {
if (it.hasNext()) {
Target next = it.next();
FieldIndex fieldIndex = getFieldIndex(next);
if (fieldIndex == null) {
return null;
}
List<sbb> arrayValues = next.getArrayValues(fieldIndex);
Collection<sbb> notInValues = next.getNotInValues(fieldIndex);
Bound lowerBound = next.getLowerBound(fieldIndex);
Bound upperBound = next.getUpperBound(fieldIndex);
if (Logger.isDebugEnabled()) {
Logger.debug(TAG, "Using index '%s' to execute '%s' (Arrays: %s, Lower bound: %s, Upper bound: %s)", fieldIndex, next, arrayValues, lowerBound, upperBound);
}
Object[] encodeBound = encodeBound(fieldIndex, next, lowerBound);
String str = lowerBound.isInclusive() ? ">=" : UrlTreeKt.configurablePathSegmentSuffix;
Object[] encodeBound2 = encodeBound(fieldIndex, next, upperBound);
String str2 = upperBound.isInclusive() ? "<=" : UrlTreeKt.configurablePathSegmentPrefix;
Object[] generateQueryAndBindings = generateQueryAndBindings(next, fieldIndex.getIndexId(), arrayValues, encodeBound, str, encodeBound2, str2, encodeValues(fieldIndex, next, notInValues));
arrayList.add(String.valueOf(generateQueryAndBindings[0]));
arrayList2.addAll(Arrays.asList(generateQueryAndBindings).subList(1, generateQueryAndBindings.length));
} else {
StringBuilder sb = new StringBuilder();
sb.append(TextUtils.join(" UNION ", arrayList));
sb.append("ORDER BY directional_value, document_key ");
sb.append(target.getKeyOrder().equals(OrderBy.Direction.ASCENDING) ? "asc " : "desc ");
String obj = sb.toString();
StringBuilder sb2 = new StringBuilder("SELECT DISTINCT document_key FROM (");
sb2.append(obj);
sb2.append(")");
String obj2 = sb2.toString();
if (target.hasLimit()) {
StringBuilder sb3 = new StringBuilder();
sb3.append(obj2);
sb3.append(" LIMIT ");
sb3.append(target.getLimit());
obj2 = sb3.toString();
}
Assert.hardAssert(arrayList2.size() < 1000, "Cannot perform query with more than 999 bind elements", new Object[0]);
SQLitePersistence.Query binding = this.db.query(obj2).binding(arrayList2.toArray());
final ArrayList arrayList3 = new ArrayList();
binding.forEach(new Consumer(arrayList3) { // from class: com.google.firebase.firestore.local.SQLiteIndexManager$$ExternalSyntheticLambda0
public final List f$0;
@Override // com.google.firebase.firestore.util.Consumer
public final void accept(Object obj3) {
this.f$0.add(DocumentKey.fromPath(ResourcePath.fromString(((Cursor) obj3).getString(0))));
}
{
this.f$0 = arrayList3;
}
});
Logger.debug(TAG, "Index scan returned %s documents", Integer.valueOf(arrayList3.size()));
return arrayList3;
}
}
}
private Object[] generateQueryAndBindings(Target target, int i, List<sbb> list, Object[] objArr, String str, Object[] objArr2, String str2, Object[] objArr3) {
StringBuilder sb;
int max = Math.max(objArr.length, objArr2.length) * (list != null ? list.size() : 1);
StringBuilder sb2 = new StringBuilder();
sb2.append("SELECT document_key, directional_value FROM index_entries WHERE index_id = ? AND uid = ? AND array_value = ? AND directional_value ");
sb2.append(str);
sb2.append(" ? AND directional_value ");
sb2.append(str2);
sb2.append(" ? ");
CharSequence repeatSequence = Util.repeatSequence(sb2, max, " UNION ");
if (objArr3 != null) {
StringBuilder sb3 = new StringBuilder("SELECT document_key, directional_value FROM (");
sb3.append(repeatSequence);
sb3.append(") WHERE directional_value NOT IN (");
sb3.append((CharSequence) Util.repeatSequence("?", objArr3.length, ", "));
sb3.append(")");
sb = sb3;
} else {
sb = repeatSequence;
}
Object[] fillBounds = fillBounds(max, i, list, objArr, objArr2, objArr3);
ArrayList arrayList = new ArrayList();
arrayList.add(sb.toString());
arrayList.addAll(Arrays.asList(fillBounds));
return arrayList.toArray();
}
private Object[] fillBounds(int i, int i2, List<sbb> list, Object[] objArr, Object[] objArr2, Object[] objArr3) {
int size = i / (list != null ? list.size() : 1);
int i3 = 0;
Object[] objArr4 = new Object[(i * 5) + (objArr3 != null ? objArr3.length : 0)];
int i4 = 0;
int i5 = 0;
while (i4 < i) {
objArr4[i5] = Integer.valueOf(i2);
objArr4[i5 + 1] = this.uid;
objArr4[i5 + 2] = list != null ? encodeSingleElement(list.get(i4 / size)) : EMPTY_BYTES_VALUE;
int i6 = i4 % size;
objArr4[i5 + 3] = objArr[i6];
objArr4[i5 + 4] = objArr2[i6];
i4++;
i5 += 5;
}
if (objArr3 != null) {
int length = objArr3.length;
while (i3 < length) {
objArr4[i5] = objArr3[i3];
i3++;
i5++;
}
}
return objArr4;
}
private FieldIndex getFieldIndex(Target target) {
String lastSegment;
Assert.hardAssert(this.started, "IndexManager not started", new Object[0]);
TargetIndexMatcher targetIndexMatcher = new TargetIndexMatcher(target);
if (target.getCollectionGroup() != null) {
lastSegment = target.getCollectionGroup();
} else {
lastSegment = target.getPath().getLastSegment();
}
Collection<FieldIndex> fieldIndexes = getFieldIndexes(lastSegment);
FieldIndex fieldIndex = null;
if (fieldIndexes.isEmpty()) {
return null;
}
for (FieldIndex fieldIndex2 : fieldIndexes) {
if (targetIndexMatcher.servedByIndex(fieldIndex2) && (fieldIndex == null || fieldIndex2.getSegments().size() > fieldIndex.getSegments().size())) {
fieldIndex = fieldIndex2;
}
}
return fieldIndex;
}
private byte[] encodeDirectionalElements(FieldIndex fieldIndex, Document document) {
IndexByteEncoder indexByteEncoder = new IndexByteEncoder();
for (FieldIndex.Segment segment : fieldIndex.getDirectionalSegments()) {
sbb field = document.getField(segment.getFieldPath());
if (field == null) {
return null;
}
FirestoreIndexValueWriter.INSTANCE.writeIndexValue(field, indexByteEncoder.forKind(segment.getKind()));
}
return indexByteEncoder.getEncodedBytes();
}
private byte[] encodeSingleElement(sbb sbbVar) {
IndexByteEncoder indexByteEncoder = new IndexByteEncoder();
FirestoreIndexValueWriter.INSTANCE.writeIndexValue(sbbVar, indexByteEncoder.forKind(FieldIndex.Segment.Kind.ASCENDING));
return indexByteEncoder.getEncodedBytes();
}
private Object[] encodeValues(FieldIndex fieldIndex, Target target, Collection<sbb> collection) {
if (collection == null) {
return null;
}
List<IndexByteEncoder> arrayList = new ArrayList<>();
arrayList.add(new IndexByteEncoder());
Iterator<sbb> it = collection.iterator();
for (FieldIndex.Segment segment : fieldIndex.getDirectionalSegments()) {
sbb next = it.next();
for (IndexByteEncoder indexByteEncoder : arrayList) {
if (isInFilter(target, segment.getFieldPath()) && Values.isArray(next)) {
arrayList = expandIndexValues(arrayList, segment, next);
} else {
FirestoreIndexValueWriter.INSTANCE.writeIndexValue(next, indexByteEncoder.forKind(segment.getKind()));
}
}
}
return getEncodedBytes(arrayList);
}
private Object[] encodeBound(FieldIndex fieldIndex, Target target, Bound bound) {
return encodeValues(fieldIndex, target, bound.getPosition());
}
private Object[] getEncodedBytes(List<IndexByteEncoder> list) {
Object[] objArr = new Object[list.size()];
for (int i = 0; i < list.size(); i++) {
objArr[i] = list.get(i).getEncodedBytes();
}
return objArr;
}
private List<IndexByteEncoder> expandIndexValues(List<IndexByteEncoder> list, FieldIndex.Segment segment, sbb sbbVar) {
uOO e;
ArrayList<IndexByteEncoder> arrayList = new ArrayList(list);
ArrayList arrayList2 = new ArrayList();
if (sbbVar.valueTypeCase_ == 9) {
e = (uOO) sbbVar.valueType_;
} else {
e = uOO.e();
}
for (sbb sbbVar2 : e.values_) {
for (IndexByteEncoder indexByteEncoder : arrayList) {
IndexByteEncoder indexByteEncoder2 = new IndexByteEncoder();
indexByteEncoder2.seed(indexByteEncoder.getEncodedBytes());
FirestoreIndexValueWriter.INSTANCE.writeIndexValue(sbbVar2, indexByteEncoder2.forKind(segment.getKind()));
arrayList2.add(indexByteEncoder2);
}
}
return arrayList2;
}
private boolean isInFilter(Target target, FieldPath fieldPath) {
for (Filter filter : target.getFilters()) {
if (filter instanceof FieldFilter) {
FieldFilter fieldFilter = (FieldFilter) filter;
if (fieldFilter.getField().equals(fieldPath)) {
FieldFilter.Operator operator = fieldFilter.getOperator();
if (operator.equals(FieldFilter.Operator.IN) || operator.equals(FieldFilter.Operator.NOT_IN)) {
return true;
}
} else {
continue;
}
}
}
return false;
}
@Override // com.google.firebase.firestore.local.IndexManager
public final void updateCollectionGroup(String str, FieldIndex.IndexOffset indexOffset) {
Assert.hardAssert(this.started, "IndexManager not started", new Object[0]);
this.memoizedMaxSequenceNumber++;
for (FieldIndex fieldIndex : getFieldIndexes(str)) {
FieldIndex create = FieldIndex.create(fieldIndex.getIndexId(), fieldIndex.getCollectionGroup(), fieldIndex.getSegments(), FieldIndex.IndexState.create(this.memoizedMaxSequenceNumber, indexOffset));
SQLitePersistence sQLitePersistence = this.db;
int indexId = fieldIndex.getIndexId();
sQLitePersistence.execute("REPLACE INTO index_state (index_id, uid, sequence_number, read_time_seconds, read_time_nanos, document_key, largest_batch_id) VALUES(?, ?, ?, ?, ?, ?, ?)", Integer.valueOf(indexId), this.uid, Long.valueOf(this.memoizedMaxSequenceNumber), Long.valueOf(indexOffset.getReadTime().getTimestamp().getSeconds()), Integer.valueOf(indexOffset.getReadTime().getTimestamp().getNanoseconds()), EncodedPath.encode(indexOffset.getDocumentKey().getPath()), Integer.valueOf(indexOffset.getLargestBatchId()));
memoizeIndex(create);
}
}
}