Skip to content

Commit 2fed47b

Browse files
Simplify
1 parent 5534c07 commit 2fed47b

File tree

3 files changed

+21
-77
lines changed

3 files changed

+21
-77
lines changed

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,15 @@ public Map<DocumentKey, MutableDocument> getAll(
9595
ResourcePath documentParent = collectionParent.append(collectionGroup);
9696
Iterator<Map.Entry<DocumentKey, MutableDocument>> iterator =
9797
docs.iteratorFrom(DocumentKey.fromPath(documentParent.append("")));
98+
9899
while (iterator.hasNext()) {
99100
Map.Entry<DocumentKey, MutableDocument> entry = iterator.next();
100101
DocumentKey key = entry.getKey();
102+
101103
if (!documentParent.isPrefixOf(key.getPath())) {
102104
break;
103105
}
106+
104107
if (IndexOffset.fromDocument(entry.getValue()).compareTo(offset) > 0) {
105108
allDocuments.add(entry.getValue());
106109
}

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

Lines changed: 17 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141

4242
final class SQLiteRemoteDocumentCache implements RemoteDocumentCache {
4343
/** The number of bind args per collection group in {@link #getAll(String, IndexOffset, int)} */
44-
@VisibleForTesting static final int GET_ALL_BINDS_PER_STATEMENT = 8;
44+
@VisibleForTesting static final int BINDS_PER_STATEMENT = 9;
4545

4646
private final SQLitePersistence db;
4747
private final LocalSerializer serializer;
@@ -83,14 +83,12 @@ public void add(MutableDocument document, SnapshotVersion readTime) {
8383
@Override
8484
public void remove(DocumentKey documentKey) {
8585
String path = EncodedPath.encode(documentKey.getPath());
86-
8786
db.execute("DELETE FROM remote_documents WHERE path = ?", path);
8887
}
8988

9089
@Override
9190
public MutableDocument get(DocumentKey documentKey) {
9291
String path = EncodedPath.encode(documentKey.getPath());
93-
9492
MutableDocument document =
9593
db.query(
9694
"SELECT contents, read_time_seconds, read_time_nanos "
@@ -145,12 +143,12 @@ public Map<DocumentKey, MutableDocument> getAll(
145143

146144
if (collections.isEmpty()) {
147145
return Collections.emptyMap();
148-
} else if (GET_ALL_BINDS_PER_STATEMENT * collections.size() < SQLitePersistence.MAX_ARGS) {
146+
} else if (BINDS_PER_STATEMENT * collections.size() < SQLitePersistence.MAX_ARGS) {
149147
return getAll(collections, offset, count);
150148
} else {
151149
// We need to fan out our collection scan since SQLite only supports 999 binds per statement.
152150
Map<DocumentKey, MutableDocument> results = new HashMap<>();
153-
int pageSize = SQLitePersistence.MAX_ARGS / GET_ALL_BINDS_PER_STATEMENT;
151+
int pageSize = SQLitePersistence.MAX_ARGS / BINDS_PER_STATEMENT;
154152
for (int i = 0; i < collections.size(); i += pageSize) {
155153
results.putAll(
156154
getAll(
@@ -168,26 +166,25 @@ private Map<DocumentKey, MutableDocument> getAll(
168166
Timestamp readTime = offset.getReadTime().getTimestamp();
169167
DocumentKey documentKey = offset.getDocumentKey();
170168

171-
// TODO(indexing): Add path_length
172-
173169
StringBuilder sql =
174170
repeatSequence(
175171
"SELECT contents, read_time_seconds, read_time_nanos, path "
176172
+ "FROM remote_documents "
177-
+ "WHERE path >= ? AND path < ? "
173+
+ "WHERE path >= ? AND path < ? AND path_length = ? "
178174
+ "AND (read_time_seconds > ? OR ( "
179175
+ "read_time_seconds = ? AND read_time_nanos > ?) OR ( "
180176
+ "read_time_seconds = ? AND read_time_nanos = ? and path > ?)) ",
181177
collections.size(),
182178
" UNION ");
183179
sql.append("ORDER BY read_time_seconds, read_time_nanos, path LIMIT ?");
184180

185-
Object[] bindVars = new Object[GET_ALL_BINDS_PER_STATEMENT * collections.size() + 1];
181+
Object[] bindVars = new Object[BINDS_PER_STATEMENT * collections.size() + 1];
186182
int i = 0;
187-
for (ResourcePath collectionParent : collections) {
188-
String prefixPath = EncodedPath.encode(collectionParent);
183+
for (ResourcePath collection : collections) {
184+
String prefixPath = EncodedPath.encode(collection);
189185
bindVars[i++] = prefixPath;
190186
bindVars[i++] = EncodedPath.prefixSuccessor(prefixPath);
187+
bindVars[i++] = collection.length() + 1;
191188
bindVars[i++] = readTime.getSeconds();
192189
bindVars[i++] = readTime.getSeconds();
193190
bindVars[i++] = readTime.getNanoseconds();
@@ -236,73 +233,17 @@ public ImmutableSortedMap<DocumentKey, MutableDocument> getAllDocumentsMatchingQ
236233
!query.isCollectionGroupQuery(),
237234
"CollectionGroup queries should be handled in LocalDocumentsView");
238235

239-
StringBuilder sql =
240-
new StringBuilder(
241-
"SELECT contents, read_time_seconds, read_time_nanos "
242-
+ "FROM remote_documents WHERE path >= ? AND path < ? AND path_length = ?");
243-
244-
Object[] bindVars = new Object[3 + (IndexOffset.NONE.equals(offset) ? 0 : 6)];
245-
246-
String prefix = EncodedPath.encode(query.getPath());
247-
248-
int i = 0;
249-
bindVars[i++] = prefix;
250-
bindVars[i++] = EncodedPath.prefixSuccessor(prefix);
251-
bindVars[i++] = query.getPath().length() + 1;
252-
253-
if (!IndexOffset.NONE.equals(offset)) {
254-
Timestamp readTime = offset.getReadTime().getTimestamp();
255-
DocumentKey documentKey = offset.getDocumentKey();
256-
257-
sql.append(
258-
" AND (read_time_seconds > ? OR ("
259-
+ "read_time_seconds = ? AND read_time_nanos > ?) OR ("
260-
+ "read_time_seconds = ? AND read_time_nanos = ? and path > ?))");
261-
bindVars[i++] = readTime.getSeconds();
262-
bindVars[i++] = readTime.getSeconds();
263-
bindVars[i++] = readTime.getNanoseconds();
264-
bindVars[i++] = readTime.getSeconds();
265-
bindVars[i++] = readTime.getNanoseconds();
266-
bindVars[i] = EncodedPath.encode(documentKey.getPath());
267-
}
268-
269-
ImmutableSortedMap<DocumentKey, MutableDocument>[] results =
270-
(ImmutableSortedMap<DocumentKey, MutableDocument>[])
271-
new ImmutableSortedMap[] {DocumentCollections.emptyMutableDocumentMap()};
272-
BackgroundQueue backgroundQueue = new BackgroundQueue();
273-
274-
db.query(sql.toString())
275-
.binding(bindVars)
276-
.forEach(
277-
row -> {
278-
// Store row values in array entries to provide the correct context inside the
279-
// executor.
280-
final byte[] rawDocument = row.getBlob(0);
281-
final int[] readTimeSeconds = {row.getInt(1)};
282-
final int[] readTimeNanos = {row.getInt(2)};
283-
284-
// Since scheduling background tasks incurs overhead, we only dispatch to a
285-
// background thread if there are still some documents remaining.
286-
Executor executor = row.isLast() ? Executors.DIRECT_EXECUTOR : backgroundQueue;
287-
executor.execute(
288-
() -> {
289-
MutableDocument document =
290-
decodeMaybeDocument(rawDocument, readTimeSeconds[0], readTimeNanos[0]);
291-
if (document.isFoundDocument() && query.matches(document)) {
292-
synchronized (SQLiteRemoteDocumentCache.this) {
293-
results[0] = results[0].insert(document.getKey(), document);
294-
}
295-
}
296-
});
297-
});
298-
299-
try {
300-
backgroundQueue.drain();
301-
} catch (InterruptedException e) {
302-
fail("Interrupted while deserializing documents", e);
236+
Map<DocumentKey, MutableDocument> allDocuments =
237+
getAll(Collections.singletonList(query.getPath()), offset, Integer.MAX_VALUE);
238+
ImmutableSortedMap<DocumentKey, MutableDocument> matchingDocuments =
239+
DocumentCollections.emptyMutableDocumentMap();
240+
for (MutableDocument document : allDocuments.values()) {
241+
if (document.isFoundDocument() && query.matches(document)) {
242+
matchingDocuments = matchingDocuments.insert(document.getKey(), document);
243+
}
303244
}
304245

305-
return results[0];
246+
return matchingDocuments;
306247
}
307248

308249
@Override

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ public void testNextDocumentsForNonExistingCollectionGroup() {
288288

289289
@Test
290290
public void testNextDocumentsForLargeCollectionGroup() {
291-
int size = 999 / SQLiteRemoteDocumentCache.GET_ALL_BINDS_PER_STATEMENT + 1;
291+
int size = 999 / SQLiteRemoteDocumentCache.BINDS_PER_STATEMENT + 1;
292292
for (int i = 0; i < size; ++i) {
293293
addTestDocumentAtPath("a/" + i + "/b/doc");
294294
}

0 commit comments

Comments
 (0)