diff --git a/firebase-database-collection/src/main/java/com/google/firebase/database/collection/ImmutableSortedSet.java b/firebase-database-collection/src/main/java/com/google/firebase/database/collection/ImmutableSortedSet.java index 9fc7ea3d05d..48f328e6154 100644 --- a/firebase-database-collection/src/main/java/com/google/firebase/database/collection/ImmutableSortedSet.java +++ b/firebase-database-collection/src/main/java/com/google/firebase/database/collection/ImmutableSortedSet.java @@ -87,6 +87,22 @@ public ImmutableSortedSet insert(T entry) { return new ImmutableSortedSet(map.insert(entry, null)); } + public ImmutableSortedSet unionWith(ImmutableSortedSet other) { + ImmutableSortedSet result = this; + + // Make sure `result` always refers to the larger one of the two sets. + if (result.size() < other.size()) { + result = other; + other = this; + } + + for (T elem : other) { + result = result.insert(elem); + } + + return result; + } + public T getMinEntry() { return this.map.getMinKey(); } diff --git a/firebase-firestore/CHANGELOG.md b/firebase-firestore/CHANGELOG.md index 6d18ee22f24..62450c9eb20 100644 --- a/firebase-firestore/CHANGELOG.md +++ b/firebase-firestore/CHANGELOG.md @@ -1,4 +1,6 @@ # Unreleased +- [fixed] Fixed a performance regression introduced by the addition of + `Query.limitToLast(n: long)` in Firestore 23.3.1. - [changed] Changed the in-memory representation of Firestore documents to reduce memory allocations and improve performance. Calls to `DocumentSnapshot.getData()` and `DocumentSnapshot.toObject()` will see diff --git a/firebase-firestore/src/main/java/com/google/firebase/firestore/core/SyncEngine.java b/firebase-firestore/src/main/java/com/google/firebase/firestore/core/SyncEngine.java index 010367d070a..cf8790e9821 100644 --- a/firebase-firestore/src/main/java/com/google/firebase/firestore/core/SyncEngine.java +++ b/firebase-firestore/src/main/java/com/google/firebase/firestore/core/SyncEngine.java @@ -354,17 +354,17 @@ public ImmutableSortedSet getRemoteKeysForTarget(int targetId) { if (limboResolution != null && limboResolution.receivedDocument) { return DocumentKey.emptyKeySet().insert(limboResolution.key); } else { - List remoteKeys = Lists.newArrayList(); + ImmutableSortedSet remoteKeys = DocumentKey.emptyKeySet(); if (queriesByTarget.containsKey(targetId)) { for (Query query : queriesByTarget.get(targetId)) { if (queryViewsByQuery.containsKey(query)) { - remoteKeys.addAll( - Lists.newArrayList(queryViewsByQuery.get(query).getView().getSyncedDocuments())); + remoteKeys = + remoteKeys.unionWith(queryViewsByQuery.get(query).getView().getSyncedDocuments()); } } } - return new ImmutableSortedSet(remoteKeys, DocumentKey.comparator()); + return remoteKeys; } }