17
17
import { Query } from '../core/query' ;
18
18
import { SnapshotVersion } from '../core/snapshot_version' ;
19
19
import {
20
- documentKeySet ,
21
20
DocumentKeySet ,
22
21
DocumentMap ,
23
22
documentMap ,
@@ -26,6 +25,7 @@ import {
26
25
} from '../model/collections' ;
27
26
import { Document , MaybeDocument , NoDocument } from '../model/document' ;
28
27
import { DocumentKey } from '../model/document_key' ;
28
+ import { MutationBatch } from '../model/mutation_batch' ;
29
29
import { ResourcePath } from '../model/path' ;
30
30
import { fail } from '../util/assert' ;
31
31
@@ -56,11 +56,23 @@ export class LocalDocumentsView {
56
56
transaction : PersistenceTransaction ,
57
57
key : DocumentKey
58
58
) : PersistencePromise < MaybeDocument | null > {
59
- return this . remoteDocumentCache
60
- . getEntry ( transaction , key )
61
- . next ( remoteDoc => {
62
- return this . computeLocalDocument ( transaction , key , remoteDoc ) ;
63
- } ) ;
59
+ return this . mutationQueue
60
+ . getAllMutationBatchesAffectingDocumentKey ( transaction , key )
61
+ . next ( batches => this . getDocumentInternal ( transaction , key , batches ) ) ;
62
+ }
63
+
64
+ /** Internal version of `getDocument` that allows reusing batches. */
65
+ private getDocumentInternal (
66
+ transaction : PersistenceTransaction ,
67
+ key : DocumentKey ,
68
+ inBatches : MutationBatch [ ]
69
+ ) : PersistencePromise < MaybeDocument | null > {
70
+ return this . remoteDocumentCache . getEntry ( transaction , key ) . next ( doc => {
71
+ for ( const batch of inBatches ) {
72
+ doc = batch . applyToLocalView ( key , doc ) ;
73
+ }
74
+ return doc ;
75
+ } ) ;
64
76
}
65
77
66
78
/**
@@ -73,20 +85,29 @@ export class LocalDocumentsView {
73
85
transaction : PersistenceTransaction ,
74
86
keys : DocumentKeySet
75
87
) : PersistencePromise < MaybeDocumentMap > {
76
- const promises = [ ] as Array < PersistencePromise < void > > ;
77
- let results = maybeDocumentMap ( ) ;
78
- keys . forEach ( key => {
79
- promises . push (
80
- this . getDocument ( transaction , key ) . next ( maybeDoc => {
81
- // TODO(http://b/32275378): Don't conflate missing / deleted.
82
- if ( ! maybeDoc ) {
83
- maybeDoc = new NoDocument ( key , SnapshotVersion . forDeletedDoc ( ) ) ;
84
- }
85
- results = results . insert ( key , maybeDoc ) ;
86
- } )
87
- ) ;
88
- } ) ;
89
- return PersistencePromise . waitFor ( promises ) . next ( ( ) => results ) ;
88
+ return this . mutationQueue
89
+ . getAllMutationBatchesAffectingDocumentKeys ( transaction , keys )
90
+ . next ( batches => {
91
+ const promises = [ ] as Array < PersistencePromise < void > > ;
92
+ let results = maybeDocumentMap ( ) ;
93
+ keys . forEach ( key => {
94
+ promises . push (
95
+ this . getDocumentInternal ( transaction , key , batches ) . next (
96
+ maybeDoc => {
97
+ // TODO(http://b/32275378): Don't conflate missing / deleted.
98
+ if ( ! maybeDoc ) {
99
+ maybeDoc = new NoDocument (
100
+ key ,
101
+ SnapshotVersion . forDeletedDoc ( )
102
+ ) ;
103
+ }
104
+ results = results . insert ( key , maybeDoc ) ;
105
+ }
106
+ )
107
+ ) ;
108
+ } ) ;
109
+ return PersistencePromise . waitFor ( promises ) . next ( ( ) => results ) ;
110
+ } ) ;
90
111
}
91
112
92
113
/** Performs a query against the local view of all documents. */
@@ -122,48 +143,40 @@ export class LocalDocumentsView {
122
143
query : Query
123
144
) : PersistencePromise < DocumentMap > {
124
145
// Query the remote documents and overlay mutations.
125
- // TODO(mikelehen): There may be significant overlap between the mutations
126
- // affecting these remote documents and the
127
- // getAllMutationBatchesAffectingQuery() mutations. Consider optimizing.
128
146
let results : DocumentMap ;
129
147
return this . remoteDocumentCache
130
148
. getDocumentsMatchingQuery ( transaction , query )
131
149
. next ( queryResults => {
132
- return this . computeLocalDocuments ( transaction , queryResults ) ;
133
- } )
134
- . next ( promisedResults => {
135
- results = promisedResults ;
136
- // Now use the mutation queue to discover any other documents that may
137
- // match the query after applying mutations.
150
+ results = queryResults ;
138
151
return this . mutationQueue . getAllMutationBatchesAffectingQuery (
139
152
transaction ,
140
153
query
141
154
) ;
142
155
} )
143
156
. next ( matchingMutationBatches => {
144
- let matchingKeys = documentKeySet ( ) ;
145
157
for ( const batch of matchingMutationBatches ) {
146
158
for ( const mutation of batch . mutations ) {
147
- // TODO(mikelehen): PERF: Check if this mutation actually
148
- // affects the query to reduce work.
149
- if ( ! results . get ( mutation . key ) ) {
150
- matchingKeys = matchingKeys . add ( mutation . key ) ;
159
+ const key = mutation . key ;
160
+ // Only process documents belonging to the collection.
161
+ if ( ! query . path . isImmediateParentOf ( key . path ) ) {
162
+ continue ;
163
+ }
164
+
165
+ const baseDoc = results . get ( key ) ;
166
+ const mutatedDoc = mutation . applyToLocalView (
167
+ baseDoc ,
168
+ baseDoc ,
169
+ batch . localWriteTime
170
+ ) ;
171
+ if ( ! mutatedDoc || mutatedDoc instanceof NoDocument ) {
172
+ results = results . remove ( key ) ;
173
+ } else if ( mutatedDoc instanceof Document ) {
174
+ results = results . insert ( key , mutatedDoc ) ;
175
+ } else {
176
+ fail ( 'Unknown MaybeDocument: ' + mutatedDoc ) ;
151
177
}
152
178
}
153
179
}
154
-
155
- // Now add in the results for the matchingKeys.
156
- const promises = [ ] as Array < PersistencePromise < void > > ;
157
- matchingKeys . forEach ( key => {
158
- promises . push (
159
- this . getDocument ( transaction , key ) . next ( doc => {
160
- if ( doc instanceof Document ) {
161
- results = results . insert ( doc . key , doc ) ;
162
- }
163
- } )
164
- ) ;
165
- } ) ;
166
- return PersistencePromise . waitFor ( promises ) ;
167
180
} )
168
181
. next ( ( ) => {
169
182
// Finally, filter out any documents that don't actually match
@@ -177,57 +190,4 @@ export class LocalDocumentsView {
177
190
return results ;
178
191
} ) ;
179
192
}
180
-
181
- /**
182
- * Takes a remote document and applies local mutations to generate the local
183
- * view of the document.
184
- * @param transaction The transaction in which to perform any persistence
185
- * operations.
186
- * @param documentKey The key of the document (necessary when remoteDocument
187
- * is null).
188
- * @param document The base remote document to apply mutations to or null.
189
- */
190
- private computeLocalDocument (
191
- transaction : PersistenceTransaction ,
192
- documentKey : DocumentKey ,
193
- document : MaybeDocument | null
194
- ) : PersistencePromise < MaybeDocument | null > {
195
- return this . mutationQueue
196
- . getAllMutationBatchesAffectingDocumentKey ( transaction , documentKey )
197
- . next ( batches => {
198
- for ( const batch of batches ) {
199
- document = batch . applyToLocalView ( documentKey , document ) ;
200
- }
201
- return document ;
202
- } ) ;
203
- }
204
-
205
- /**
206
- * Takes a set of remote documents and applies local mutations to generate the
207
- * local view of the documents.
208
- * @param transaction The transaction in which to perform any persistence
209
- * operations.
210
- * @param documents The base remote documents to apply mutations to.
211
- * @return The local view of the documents.
212
- */
213
- private computeLocalDocuments (
214
- transaction : PersistenceTransaction ,
215
- documents : DocumentMap
216
- ) : PersistencePromise < DocumentMap > {
217
- const promises = [ ] as Array < PersistencePromise < void > > ;
218
- documents . forEach ( ( key , doc ) => {
219
- promises . push (
220
- this . computeLocalDocument ( transaction , key , doc ) . next ( mutatedDoc => {
221
- if ( mutatedDoc instanceof Document ) {
222
- documents = documents . insert ( mutatedDoc . key , mutatedDoc ) ;
223
- } else if ( mutatedDoc instanceof NoDocument ) {
224
- documents = documents . remove ( mutatedDoc . key ) ;
225
- } else {
226
- fail ( 'Unknown MaybeDocument: ' + mutatedDoc ) ;
227
- }
228
- } )
229
- ) ;
230
- } ) ;
231
- return PersistencePromise . waitFor ( promises ) . next ( ( ) => documents ) ;
232
- }
233
193
}
0 commit comments