Skip to content

Commit 70864ca

Browse files
Use immutable Documents in MemoryRemoteDocumentCache (#3225)
1 parent 7d86138 commit 70864ca

File tree

5 files changed

+29
-26
lines changed

5 files changed

+29
-26
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/MemoryRemoteDocumentCache.java

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,14 @@
3434
final class MemoryRemoteDocumentCache implements RemoteDocumentCache {
3535

3636
/** Underlying cache of documents and their read times. */
37-
private ImmutableSortedMap<DocumentKey, MutableDocument> docs;
37+
private ImmutableSortedMap<DocumentKey, Document> docs;
3838
/** Manages the collection group index. */
3939
private IndexManager indexManager;
4040
/** The latest read time of any document in the cache. */
4141
private SnapshotVersion latestReadTime;
4242

4343
MemoryRemoteDocumentCache() {
44-
docs = ImmutableSortedMap.Builder.emptyMap(DocumentKey.comparator());
44+
docs = emptyDocumentMap();
4545
latestReadTime = SnapshotVersion.NONE;
4646
}
4747

@@ -56,7 +56,7 @@ public void add(MutableDocument document, SnapshotVersion readTime) {
5656
hardAssert(
5757
!readTime.equals(SnapshotVersion.NONE),
5858
"Cannot add document to the RemoteDocumentCache with a read time of zero");
59-
docs = docs.insert(document.getKey(), document.clone().withReadTime(readTime));
59+
docs = docs.insert(document.getKey(), document.mutableCopy().withReadTime(readTime));
6060
latestReadTime = readTime.compareTo(latestReadTime) > 0 ? readTime : latestReadTime;
6161

6262
indexManager.addToCollectionParentIndex(document.getKey().getCollectionPath());
@@ -77,8 +77,8 @@ public void removeAll(Collection<DocumentKey> keys) {
7777

7878
@Override
7979
public MutableDocument get(DocumentKey key) {
80-
MutableDocument doc = docs.get(key);
81-
return doc != null ? doc.clone() : MutableDocument.newInvalidDocument(key);
80+
Document doc = docs.get(key);
81+
return doc != null ? doc.mutableCopy() : MutableDocument.newInvalidDocument(key);
8282
}
8383

8484
@Override
@@ -104,11 +104,11 @@ public Map<DocumentKey, MutableDocument> getAll(ResourcePath collection, IndexOf
104104
// Documents are ordered by key, so we can use a prefix scan to narrow down the documents
105105
// we need to match the query against.
106106
DocumentKey prefix = DocumentKey.fromPath(collection.append(""));
107-
Iterator<Map.Entry<DocumentKey, MutableDocument>> iterator = docs.iteratorFrom(prefix);
107+
Iterator<Map.Entry<DocumentKey, Document>> iterator = docs.iteratorFrom(prefix);
108108

109109
while (iterator.hasNext()) {
110-
Map.Entry<DocumentKey, MutableDocument> entry = iterator.next();
111-
MutableDocument doc = entry.getValue();
110+
Map.Entry<DocumentKey, Document> entry = iterator.next();
111+
Document doc = entry.getValue();
112112

113113
DocumentKey key = entry.getKey();
114114
if (!collection.isPrefixOf(key.getPath())) {
@@ -126,7 +126,7 @@ public Map<DocumentKey, MutableDocument> getAll(ResourcePath collection, IndexOf
126126
continue;
127127
}
128128

129-
result.put(doc.getKey(), doc.clone());
129+
result.put(doc.getKey(), doc.mutableCopy());
130130
}
131131

132132
return result;
@@ -137,13 +137,13 @@ public SnapshotVersion getLatestReadTime() {
137137
return latestReadTime;
138138
}
139139

140-
Iterable<MutableDocument> getDocuments() {
140+
Iterable<Document> getDocuments() {
141141
return new DocumentIterable();
142142
}
143143

144144
long getByteSize(LocalSerializer serializer) {
145145
long count = 0;
146-
for (MutableDocument doc : new DocumentIterable()) {
146+
for (Document doc : new DocumentIterable()) {
147147
count += serializer.encodeMaybeDocument(doc).getSerializedSize();
148148
}
149149
return count;
@@ -152,20 +152,20 @@ long getByteSize(LocalSerializer serializer) {
152152
/**
153153
* A proxy that exposes an iterator over the current set of documents in the RemoteDocumentCache.
154154
*/
155-
private class DocumentIterable implements Iterable<MutableDocument> {
155+
private class DocumentIterable implements Iterable<Document> {
156156
@NonNull
157157
@Override
158-
public Iterator<MutableDocument> iterator() {
159-
Iterator<Map.Entry<DocumentKey, MutableDocument>> iterator =
158+
public Iterator<Document> iterator() {
159+
Iterator<Map.Entry<DocumentKey, Document>> iterator =
160160
MemoryRemoteDocumentCache.this.docs.iterator();
161-
return new Iterator<MutableDocument>() {
161+
return new Iterator<Document>() {
162162
@Override
163163
public boolean hasNext() {
164164
return iterator.hasNext();
165165
}
166166

167167
@Override
168-
public MutableDocument next() {
168+
public Document next() {
169169
return iterator.next().getValue();
170170
}
171171
};

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,4 +73,7 @@ public interface Document {
7373
* Whether this document has a local mutation applied that has not yet been acknowledged by Watch.
7474
*/
7575
boolean hasPendingWrites();
76+
77+
/** Creates a mutable copy of this document. */
78+
MutableDocument mutableCopy();
7679
}

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

Lines changed: 2 additions & 2 deletions
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
/**
@@ -229,7 +229,7 @@ public boolean isUnknownDocument() {
229229

230230
@Override
231231
@NonNull
232-
public MutableDocument clone() {
232+
public MutableDocument mutableCopy() {
233233
return new MutableDocument(key, documentType, version, readTime, value.clone(), documentState);
234234
}
235235

firebase-firestore/src/test/java/com/google/firebase/firestore/model/mutation/MutationTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -564,7 +564,7 @@ private void assertVersionTransitions(
564564
MutableDocument base,
565565
MutationResult mutationResult,
566566
MutableDocument expected) {
567-
MutableDocument clone = base.clone();
567+
MutableDocument clone = base.mutableCopy();
568568
mutation.applyToRemoteDocument(clone, mutationResult);
569569
assertEquals(expected, clone);
570570
}
@@ -1033,8 +1033,8 @@ private String getDescription(
10331033
}
10341034

10351035
private void verifyOverlayRoundTrips(MutableDocument doc, Mutation... mutations) {
1036-
MutableDocument docForMutations = doc.clone();
1037-
MutableDocument docForOverlay = doc.clone();
1036+
MutableDocument docForMutations = doc.mutableCopy();
1037+
MutableDocument docForOverlay = doc.mutableCopy();
10381038
Timestamp now = Timestamp.now();
10391039

10401040
FieldMask mask = null;

0 commit comments

Comments
 (0)