Skip to content

Commit 0c71f27

Browse files
Use immutable Documents in MemoryRemoteDocumentCache
1 parent dfa2231 commit 0c71f27

File tree

5 files changed

+28
-21
lines changed

5 files changed

+28
-21
lines changed

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import com.google.firebase.firestore.bundle.BundledQuery;
2222
import com.google.firebase.firestore.core.Query.LimitType;
2323
import com.google.firebase.firestore.core.Target;
24+
import com.google.firebase.firestore.model.Document;
2425
import com.google.firebase.firestore.model.DocumentKey;
2526
import com.google.firebase.firestore.model.FieldIndex;
2627
import com.google.firebase.firestore.model.FieldPath;
@@ -48,7 +49,7 @@ public LocalSerializer(RemoteSerializer rpcSerializer) {
4849
}
4950

5051
/** Encodes a MaybeDocument model to the equivalent protocol buffer for local storage. */
51-
com.google.firebase.firestore.proto.MaybeDocument encodeMaybeDocument(MutableDocument document) {
52+
com.google.firebase.firestore.proto.MaybeDocument encodeMaybeDocument(Document document) {
5253
com.google.firebase.firestore.proto.MaybeDocument.Builder builder =
5354
com.google.firebase.firestore.proto.MaybeDocument.newBuilder();
5455

@@ -88,7 +89,7 @@ MutableDocument decodeMaybeDocument(com.google.firebase.firestore.proto.MaybeDoc
8889
* Encodes a Document for local storage. This differs from the v1 RPC serializer for Documents in
8990
* that it preserves the updateTime, which is considered an output only value by the server.
9091
*/
91-
private com.google.firestore.v1.Document encodeDocument(MutableDocument document) {
92+
private com.google.firestore.v1.Document encodeDocument(Document document) {
9293
com.google.firestore.v1.Document.Builder builder =
9394
com.google.firestore.v1.Document.newBuilder();
9495
builder.setName(rpcSerializer.encodeKey(document.getKey()));
@@ -110,8 +111,7 @@ private MutableDocument decodeDocument(
110111
}
111112

112113
/** Encodes a NoDocument value to the equivalent proto. */
113-
private com.google.firebase.firestore.proto.NoDocument encodeNoDocument(
114-
MutableDocument document) {
114+
private com.google.firebase.firestore.proto.NoDocument encodeNoDocument(Document document) {
115115
com.google.firebase.firestore.proto.NoDocument.Builder builder =
116116
com.google.firebase.firestore.proto.NoDocument.newBuilder();
117117
builder.setName(rpcSerializer.encodeKey(document.getKey()));
@@ -130,7 +130,7 @@ private MutableDocument decodeNoDocument(
130130

131131
/** Encodes a UnknownDocument value to the equivalent proto. */
132132
private com.google.firebase.firestore.proto.UnknownDocument encodeUnknownDocument(
133-
MutableDocument document) {
133+
Document document) {
134134
com.google.firebase.firestore.proto.UnknownDocument.Builder builder =
135135
com.google.firebase.firestore.proto.UnknownDocument.newBuilder();
136136
builder.setName(rpcSerializer.encodeKey(document.getKey()));

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import android.util.SparseArray;
2020
import com.google.firebase.firestore.core.ListenSequence;
21+
import com.google.firebase.firestore.model.Document;
2122
import com.google.firebase.firestore.model.DocumentKey;
2223
import com.google.firebase.firestore.model.MutableDocument;
2324
import com.google.firebase.firestore.util.Consumer;
@@ -117,7 +118,7 @@ public int removeTargets(long upperBound, SparseArray<?> activeTargetIds) {
117118
public int removeOrphanedDocuments(long upperBound) {
118119
int count = 0;
119120
MemoryRemoteDocumentCache cache = persistence.getRemoteDocumentCache();
120-
for (MutableDocument doc : cache.getDocuments()) {
121+
for (Document doc : cache.getDocuments()) {
121122
DocumentKey key = doc.getKey();
122123
if (!isPinned(key, upperBound)) {
123124
cache.remove(key);

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

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@
1414

1515
package com.google.firebase.firestore.local;
1616

17+
import static com.google.firebase.firestore.model.DocumentCollections.emptyDocumentMap;
1718
import static com.google.firebase.firestore.util.Assert.hardAssert;
1819

1920
import androidx.annotation.NonNull;
2021
import com.google.firebase.database.collection.ImmutableSortedMap;
22+
import com.google.firebase.firestore.model.Document;
2123
import com.google.firebase.firestore.model.DocumentKey;
2224
import com.google.firebase.firestore.model.FieldIndex.IndexOffset;
2325
import com.google.firebase.firestore.model.MutableDocument;
@@ -31,14 +33,14 @@
3133
final class MemoryRemoteDocumentCache implements RemoteDocumentCache {
3234

3335
/** Underlying cache of documents and their read times. */
34-
private ImmutableSortedMap<DocumentKey, MutableDocument> docs;
36+
private ImmutableSortedMap<DocumentKey, Document> docs;
3537
/** Manages the collection group index. */
3638
private IndexManager indexManager;
3739
/** The latest read time of any document in the cache. */
3840
private SnapshotVersion latestReadTime;
3941

4042
MemoryRemoteDocumentCache() {
41-
docs = ImmutableSortedMap.Builder.emptyMap(DocumentKey.comparator());
43+
docs = emptyDocumentMap();
4244
latestReadTime = SnapshotVersion.NONE;
4345
}
4446

@@ -66,7 +68,7 @@ public void remove(DocumentKey key) {
6668

6769
@Override
6870
public MutableDocument get(DocumentKey key) {
69-
MutableDocument doc = docs.get(key);
71+
Document doc = docs.get(key);
7072
return doc != null ? doc.clone() : MutableDocument.newInvalidDocument(key);
7173
}
7274

@@ -93,11 +95,11 @@ public Map<DocumentKey, MutableDocument> getAll(ResourcePath collection, IndexOf
9395
// Documents are ordered by key, so we can use a prefix scan to narrow down the documents
9496
// we need to match the query against.
9597
DocumentKey prefix = DocumentKey.fromPath(collection.append(""));
96-
Iterator<Map.Entry<DocumentKey, MutableDocument>> iterator = docs.iteratorFrom(prefix);
98+
Iterator<Map.Entry<DocumentKey, Document>> iterator = docs.iteratorFrom(prefix);
9799

98100
while (iterator.hasNext()) {
99-
Map.Entry<DocumentKey, MutableDocument> entry = iterator.next();
100-
MutableDocument doc = entry.getValue();
101+
Map.Entry<DocumentKey, Document> entry = iterator.next();
102+
Document doc = entry.getValue();
101103

102104
DocumentKey key = entry.getKey();
103105
if (!collection.isPrefixOf(key.getPath())) {
@@ -126,13 +128,13 @@ public SnapshotVersion getLatestReadTime() {
126128
return latestReadTime;
127129
}
128130

129-
Iterable<MutableDocument> getDocuments() {
131+
Iterable<Document> getDocuments() {
130132
return new DocumentIterable();
131133
}
132134

133135
long getByteSize(LocalSerializer serializer) {
134136
long count = 0;
135-
for (MutableDocument doc : new DocumentIterable()) {
137+
for (Document doc : new DocumentIterable()) {
136138
count += serializer.encodeMaybeDocument(doc).getSerializedSize();
137139
}
138140
return count;
@@ -141,20 +143,20 @@ long getByteSize(LocalSerializer serializer) {
141143
/**
142144
* A proxy that exposes an iterator over the current set of documents in the RemoteDocumentCache.
143145
*/
144-
private class DocumentIterable implements Iterable<MutableDocument> {
146+
private class DocumentIterable implements Iterable<Document> {
145147
@NonNull
146148
@Override
147-
public Iterator<MutableDocument> iterator() {
148-
Iterator<Map.Entry<DocumentKey, MutableDocument>> iterator =
149+
public Iterator<Document> iterator() {
150+
Iterator<Map.Entry<DocumentKey, Document>> iterator =
149151
MemoryRemoteDocumentCache.this.docs.iterator();
150-
return new Iterator<MutableDocument>() {
152+
return new Iterator<Document>() {
151153
@Override
152154
public boolean hasNext() {
153155
return iterator.hasNext();
154156
}
155157

156158
@Override
157-
public MutableDocument next() {
159+
public Document next() {
158160
return iterator.next().getValue();
159161
}
160162
};

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
package com.google.firebase.firestore.model;
1616

17+
import androidx.annotation.NonNull;
1718
import androidx.annotation.Nullable;
1819
import com.google.firestore.v1.Value;
1920
import java.util.Comparator;
@@ -22,7 +23,7 @@
2223
* Represents a document in Firestore with a key, version, data and whether the data has local
2324
* mutations applied to it.
2425
*/
25-
public interface Document {
26+
public interface Document extends Cloneable {
2627
/** A document comparator that returns document by key and key only. */
2728
Comparator<Document> KEY_COMPARATOR = (left, right) -> left.getKey().compareTo(right.getKey());
2829

@@ -73,4 +74,7 @@ public interface Document {
7374
* Whether this document has a local mutation applied that has not yet been acknowledged by Watch.
7475
*/
7576
boolean hasPendingWrites();
77+
78+
@NonNull
79+
MutableDocument clone();
7680
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
* one of these states even after all mutations have been applied, {@link #isValidDocument} returns
2727
* false and the document should be removed from all views.
2828
*/
29-
public final class MutableDocument implements Document, Cloneable {
29+
public final class MutableDocument implements Document {
3030

3131
private enum DocumentType {
3232
/**

0 commit comments

Comments
 (0)