Skip to content

Commit 4719d11

Browse files
Review
1 parent 473e8f4 commit 4719d11

File tree

7 files changed

+53
-26
lines changed

7 files changed

+53
-26
lines changed

firebase-firestore/src/main/java/com/google/firebase/firestore/local/MemoryRemoteDocumentCache.java

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import static com.google.firebase.firestore.model.DocumentCollections.emptyMutableDocumentMap;
1818
import static com.google.firebase.firestore.util.Assert.hardAssert;
19+
import static com.google.firebase.firestore.util.Util.trimMap;
1920

2021
import androidx.annotation.NonNull;
2122
import com.google.firebase.database.collection.ImmutableSortedMap;
@@ -86,10 +87,11 @@ public Map<DocumentKey, MutableDocument> getAll(Iterable<DocumentKey> keys) {
8687

8788
@Override
8889
public Map<DocumentKey, MutableDocument> getAll(
89-
String collectionGroup, IndexOffset offset, int count) {
90+
String collectionGroup, IndexOffset offset, int limit) {
91+
// Note: This method is pretty inefficient, but t is not called since the method is only used
92+
// during index backfill, which is not supported by memory persistence.
93+
9094
List<ResourcePath> collectionParents = indexManager.getCollectionParents(collectionGroup);
91-
Set<MutableDocument> allDocuments =
92-
new TreeSet<>((l, r) -> IndexOffset.fromDocument(l).compareTo(IndexOffset.fromDocument(r)));
9395
Map<DocumentKey, MutableDocument> matchingDocuments = new HashMap<>();
9496

9597
for (ResourcePath collectionParent : collectionParents) {
@@ -99,24 +101,17 @@ public Map<DocumentKey, MutableDocument> getAll(
99101
while (iterator.hasNext()) {
100102
Map.Entry<DocumentKey, MutableDocument> entry = iterator.next();
101103
DocumentKey key = entry.getKey();
102-
104+
MutableDocument document = entry.getValue();
103105
if (!documentParent.isPrefixOf(key.getPath())) {
104106
break;
105107
}
106-
107-
if (IndexOffset.fromDocument(entry.getValue()).compareTo(offset) > 0) {
108-
allDocuments.add(entry.getValue());
108+
if (IndexOffset.fromDocument(document).compareTo(offset) > 0) {
109+
matchingDocuments.put(key, document);
109110
}
110111
}
111112
}
112113

113-
Iterator<MutableDocument> it = allDocuments.iterator();
114-
while (it.hasNext() && matchingDocuments.size() < count) {
115-
MutableDocument document = it.next();
116-
matchingDocuments.put(document.getKey(), document);
117-
}
118-
119-
return matchingDocuments;
114+
return trimMap(matchingDocuments, limit, IndexOffset.DOCUMENT_COMPARATOR);
120115
}
121116

122117
@Override

firebase-firestore/src/main/java/com/google/firebase/firestore/local/RemoteDocumentCache.java

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,18 +66,15 @@ interface RemoteDocumentCache {
6666
Map<DocumentKey, MutableDocument> getAll(Iterable<DocumentKey> documentKeys);
6767

6868
/**
69-
* Looks up the next {@code count} documents for a collection group based on the provided offset.
69+
* Looks up the next {@code limit} documents for a collection group based on the provided offset.
7070
* The ordering is based on the document's read time and key.
7171
*
72-
* <p>This method may return more results than requested if a collection group scan scans more
73-
* than 100 collections.
74-
*
7572
* @param collectionGroup The collection group to scan.
7673
* @param offset The offset to start the scan at.
77-
* @param count The number of results to return.
74+
* @param limit The maximum number of results to return.
7875
* @return A map with next set of documents.
7976
*/
80-
Map<DocumentKey, MutableDocument> getAll(String collectionGroup, IndexOffset offset, int count);
77+
Map<DocumentKey, MutableDocument> getAll(String collectionGroup, IndexOffset offset, int limit);
8178

8279
/**
8380
* Executes a query against the cached Document entries

firebase-firestore/src/main/java/com/google/firebase/firestore/local/SQLiteRemoteDocumentCache.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import static com.google.firebase.firestore.util.Assert.fail;
1818
import static com.google.firebase.firestore.util.Assert.hardAssert;
1919
import static com.google.firebase.firestore.util.Util.repeatSequence;
20+
import static com.google.firebase.firestore.util.Util.trimMap;
2021

2122
import androidx.annotation.VisibleForTesting;
2223
import com.google.firebase.Timestamp;
@@ -136,7 +137,7 @@ public Map<DocumentKey, MutableDocument> getAll(Iterable<DocumentKey> documentKe
136137

137138
@Override
138139
public Map<DocumentKey, MutableDocument> getAll(
139-
String collectionGroup, IndexOffset offset, int count) {
140+
String collectionGroup, IndexOffset offset, int limit) {
140141
List<ResourcePath> collectionParents = indexManager.getCollectionParents(collectionGroup);
141142
List<ResourcePath> collections = new ArrayList<>(collectionParents.size());
142143
for (ResourcePath collectionParent : collectionParents) {
@@ -146,17 +147,17 @@ public Map<DocumentKey, MutableDocument> getAll(
146147
if (collections.isEmpty()) {
147148
return Collections.emptyMap();
148149
} else if (BINDS_PER_STATEMENT * collections.size() < SQLitePersistence.MAX_ARGS) {
149-
return getAll(collections, offset, count);
150+
return getAll(collections, offset, limit);
150151
} else {
151152
// We need to fan out our collection scan since SQLite only supports 999 binds per statement.
152153
Map<DocumentKey, MutableDocument> results = new HashMap<>();
153154
int pageSize = SQLitePersistence.MAX_ARGS / BINDS_PER_STATEMENT;
154155
for (int i = 0; i < collections.size(); i += pageSize) {
155156
results.putAll(
156157
getAll(
157-
collections.subList(i, Math.min(collections.size(), i + pageSize)), offset, count));
158+
collections.subList(i, Math.min(collections.size(), i + pageSize)), offset, limit));
158159
}
159-
return results;
160+
return trimMap(results, limit, IndexOffset.DOCUMENT_COMPARATOR);
160161
}
161162
}
162163

firebase-firestore/src/main/java/com/google/firebase/firestore/model/FieldIndex.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ public static IndexState create(
116116
/** Stores the latest read time and document that were processed for an index. */
117117
@AutoValue
118118
public abstract static class IndexOffset implements Comparable<IndexOffset> {
119+
public static final Comparator<MutableDocument> DOCUMENT_COMPARATOR = (l,r)->IndexOffset.fromDocument(l).compareTo(IndexOffset.fromDocument(r));
120+
119121
public static final IndexOffset NONE = create(SnapshotVersion.NONE, DocumentKey.empty());
120122

121123
/**

firebase-firestore/src/main/java/com/google/firebase/firestore/util/Util.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,10 @@
3131
import java.util.Collection;
3232
import java.util.Collections;
3333
import java.util.Comparator;
34+
import java.util.HashMap;
3435
import java.util.Iterator;
3536
import java.util.List;
37+
import java.util.Map;
3638
import java.util.Random;
3739
import java.util.SortedSet;
3840

@@ -366,4 +368,19 @@ private static <T> void diffCollections(
366368
private static <T> T advanceIterator(Iterator<T> it) {
367369
return it.hasNext() ? it.next() : null;
368370
}
371+
372+
/** Returns a map with the first {#code count} elements of {#code data} when sorted by comp. */
373+
public static <K, V> Map<K, V> trimMap(Map<K, V> data, int count, Comparator<V> comp) {
374+
if (data.size() <= count) {
375+
return data;
376+
} else {
377+
List<Map.Entry<K, V>> sortedVlaues = new ArrayList<>(data.entrySet());
378+
Collections.sort(sortedVlaues, (l, r) -> comp.compare(l.getValue(), r.getValue()));
379+
Map<K, V> result = new HashMap<>();
380+
for (int i = 0; i < count; ++i) {
381+
result.put(sortedVlaues.get(i).getKey(), sortedVlaues.get(i).getValue());
382+
}
383+
return result;
384+
}
385+
}
369386
}

firebase-firestore/src/test/java/com/google/firebase/firestore/local/CountingQueryEngine.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,8 @@ public Map<DocumentKey, MutableDocument> getAll(Iterable<DocumentKey> documentKe
151151

152152
@Override
153153
public Map<DocumentKey, MutableDocument> getAll(
154-
String collectionGroup, IndexOffset offset, int count) {
155-
Map<DocumentKey, MutableDocument> result = subject.getAll(collectionGroup, offset, count);
154+
String collectionGroup, IndexOffset offset, int limit) {
155+
Map<DocumentKey, MutableDocument> result = subject.getAll(collectionGroup, offset, limit);
156156
documentsReadByQuery[0] += result.size();
157157
return result;
158158
}

firebase-firestore/src/test/java/com/google/firebase/firestore/util/UtilTest.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,18 @@
1515
package com.google.firebase.firestore.util;
1616

1717
import static com.google.common.truth.Truth.assertThat;
18+
import static com.google.firebase.firestore.util.Util.trimMap;
1819
import static org.junit.Assert.assertEquals;
1920

2021
import com.google.firebase.firestore.testutil.TestUtil;
2122
import com.google.protobuf.ByteString;
2223
import java.util.ArrayList;
2324
import java.util.Arrays;
2425
import java.util.Collections;
26+
import java.util.HashMap;
2527
import java.util.List;
28+
import java.util.Map;
29+
2630
import org.junit.Test;
2731
import org.junit.runner.RunWith;
2832
import org.junit.runners.JUnit4;
@@ -69,6 +73,17 @@ public void testDiffCollectionsWithEmptyLists() {
6973
validateDiffCollection(Collections.emptyList(), Collections.emptyList());
7074
}
7175

76+
77+
@Test
78+
public void testTrimMap() {
79+
Map<Integer, Integer> data = new HashMap<>();
80+
data.put(1, 1);
81+
data.put(3, 3);
82+
data.put(2, 2);
83+
data = trimMap(data, 2, Integer::compare);
84+
assertThat(data).containsExactly(1, 1, 2,2);
85+
}
86+
7287
private void validateDiffCollection(List<String> before, List<String> after) {
7388
List<String> result = new ArrayList<>(before);
7489
Util.diffCollections(before, after, String::compareTo, result::add, result::remove);

0 commit comments

Comments
 (0)