Skip to content

Commit 7294e9a

Browse files
Merge cca6406 into e7c83bc
2 parents e7c83bc + cca6406 commit 7294e9a

File tree

2 files changed

+42
-35
lines changed

2 files changed

+42
-35
lines changed

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

Lines changed: 12 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@
3232
import com.google.firebase.firestore.model.MutableDocument;
3333
import com.google.firebase.firestore.model.ResourcePath;
3434
import com.google.firebase.firestore.model.SnapshotVersion;
35-
import com.google.firebase.firestore.util.BackgroundQueue;
36-
import com.google.firebase.firestore.util.Executors;
3735
import com.google.firebase.firestore.util.Function;
3836
import com.google.protobuf.InvalidProtocolBufferException;
3937
import com.google.protobuf.MessageLite;
@@ -47,7 +45,6 @@
4745
import java.util.Objects;
4846
import java.util.Set;
4947
import java.util.concurrent.ConcurrentHashMap;
50-
import java.util.concurrent.Executor;
5148
import javax.annotation.Nonnull;
5249
import javax.annotation.Nullable;
5350

@@ -170,13 +167,9 @@ public Map<DocumentKey, MutableDocument> getAll(Iterable<DocumentKey> documentKe
170167
bindVars,
171168
") ORDER BY path");
172169

173-
BackgroundQueue backgroundQueue = new BackgroundQueue();
174170
while (longQuery.hasMoreSubqueries()) {
175-
longQuery
176-
.performNextSubquery()
177-
.forEach(row -> processRowInBackground(backgroundQueue, results, row, /*filter*/ null));
171+
longQuery.performNextSubquery().forEach(row -> processRow(results, row, /*filter*/ null));
178172
}
179-
backgroundQueue.drain();
180173

181174
// Backfill any rows with null "document_type" discovered by processRowInBackground().
182175
documentTypeBackfiller.backfill(db);
@@ -266,18 +259,16 @@ private Map<DocumentKey, MutableDocument> getAll(
266259
}
267260
bindVars[i] = count;
268261

269-
BackgroundQueue backgroundQueue = new BackgroundQueue();
270262
Map<DocumentKey, MutableDocument> results = new HashMap<>();
271263
db.query(sql.toString())
272264
.binding(bindVars)
273265
.forEach(
274266
row -> {
275-
processRowInBackground(backgroundQueue, results, row, filter);
267+
processRow(results, row, filter);
276268
if (context != null) {
277269
context.incrementDocumentReadCount();
278270
}
279271
});
280-
backgroundQueue.drain();
281272

282273
// Backfill any null "document_type" columns discovered by processRowInBackground().
283274
documentTypeBackfiller.backfill(db);
@@ -297,8 +288,7 @@ private Map<DocumentKey, MutableDocument> getAll(
297288
collections, offset, count, /*tryFilterDocumentType*/ null, filter, /*context*/ null);
298289
}
299290

300-
private void processRowInBackground(
301-
BackgroundQueue backgroundQueue,
291+
private void processRow(
302292
Map<DocumentKey, MutableDocument> results,
303293
Cursor row,
304294
@Nullable Function<MutableDocument, Boolean> filter) {
@@ -308,22 +298,15 @@ private void processRowInBackground(
308298
boolean documentTypeIsNull = row.isNull(3);
309299
String path = row.getString(4);
310300

311-
// Since scheduling background tasks incurs overhead, we only dispatch to a
312-
// background thread if there are still some documents remaining.
313-
Executor executor = row.isLast() ? Executors.DIRECT_EXECUTOR : backgroundQueue;
314-
executor.execute(
315-
() -> {
316-
MutableDocument document =
317-
decodeMaybeDocument(rawDocument, readTimeSeconds, readTimeNanos);
318-
if (documentTypeIsNull) {
319-
documentTypeBackfiller.enqueue(path, readTimeSeconds, readTimeNanos, document);
320-
}
321-
if (filter == null || filter.apply(document)) {
322-
synchronized (results) {
323-
results.put(document.getKey(), document);
324-
}
325-
}
326-
});
301+
MutableDocument document = decodeMaybeDocument(rawDocument, readTimeSeconds, readTimeNanos);
302+
if (documentTypeIsNull) {
303+
documentTypeBackfiller.enqueue(path, readTimeSeconds, readTimeNanos, document);
304+
}
305+
if (filter == null || filter.apply(document)) {
306+
synchronized (results) {
307+
results.put(document.getKey(), document);
308+
}
309+
}
327310
}
328311

329312
@Override

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

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import androidx.annotation.NonNull;
2020
import com.google.firebase.firestore.util.Util;
21+
import java.nio.charset.StandardCharsets;
2122
import java.util.ArrayList;
2223
import java.util.List;
2324

@@ -27,6 +28,7 @@
2728
*/
2829
public abstract class BasePath<B extends BasePath<B>> implements Comparable<B> {
2930
final List<String> segments;
31+
List<byte[]> utf8Segments = null;
3032

3133
BasePath(List<String> segments) {
3234
this.segments = segments;
@@ -93,8 +95,12 @@ public int compareTo(@NonNull B o) {
9395
int i = 0;
9496
int myLength = length();
9597
int theirLength = o.length();
98+
List<byte[]> myUtf8Segments = ensureUtf8Segments();
99+
List<byte[]> theirUtf8Segments = o.ensureUtf8Segments();
96100
while (i < myLength && i < theirLength) {
97-
int localCompare = compareSegments(getSegment(i), o.getSegment(i));
101+
int localCompare =
102+
compareSegments(
103+
myUtf8Segments.get(i), theirUtf8Segments.get(i), getSegment(i), o.getSegment(i));
98104
if (localCompare != 0) {
99105
return localCompare;
100106
}
@@ -103,21 +109,39 @@ public int compareTo(@NonNull B o) {
103109
return Integer.compare(myLength, theirLength);
104110
}
105111

106-
private static int compareSegments(String lhs, String rhs) {
107-
boolean isLhsNumeric = isNumericId(lhs);
108-
boolean isRhsNumeric = isNumericId(rhs);
112+
private static int compareSegments(byte[] lhs, byte[] rhs, String lhsString, String rhsString) {
113+
boolean isLhsNumeric = lhs == null;
114+
boolean isRhsNumeric = rhs == null;
109115

110116
if (isLhsNumeric && !isRhsNumeric) { // Only lhs is numeric
111117
return -1;
112118
} else if (!isLhsNumeric && isRhsNumeric) { // Only rhs is numeric
113119
return 1;
114120
} else if (isLhsNumeric && isRhsNumeric) { // both numeric
115-
return Long.compare(extractNumericId(lhs), extractNumericId(rhs));
121+
return Long.compare(extractNumericId(lhsString), extractNumericId(rhsString));
116122
} else { // both string
117-
return Util.compareUtf8Strings(lhs, rhs);
123+
return Util.compareByteArrays(lhs, rhs);
118124
}
119125
}
120126

127+
public List<byte[]> ensureUtf8Segments() {
128+
if (this.utf8Segments == null) {
129+
this.utf8Segments = new ArrayList<>(this.segments.size());
130+
for (int i = 0; i < this.segments.size(); i++) {
131+
String segment = this.segments.get(i);
132+
boolean isNumeric = isNumericId(segment);
133+
if (!isNumeric) {
134+
byte[] utf8Bytes = segment.getBytes(StandardCharsets.UTF_8);
135+
this.utf8Segments.add(utf8Bytes);
136+
} else {
137+
this.utf8Segments.add(null);
138+
}
139+
}
140+
}
141+
142+
return this.utf8Segments;
143+
}
144+
121145
/** Checks if a segment is a numeric ID (starts with "__id" and ends with "__"). */
122146
private static boolean isNumericId(String segment) {
123147
return segment.startsWith("__id") && segment.endsWith("__");

0 commit comments

Comments
 (0)