Skip to content

Commit d62f9cc

Browse files
committed
Only update mapping when query read time is updated.
1 parent 7d808c1 commit d62f9cc

File tree

4 files changed

+65
-66
lines changed

4 files changed

+65
-66
lines changed

packages/firestore/src/core/bundle.ts

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,19 @@ import * as bundleProto from '../protos/firestore_bundle_proto';
2828
import * as api from '../protos/firestore_proto_api';
2929
import { DocumentKey } from '../model/document_key';
3030
import { MaybeDocument, NoDocument } from '../model/document';
31-
import { debugAssert } from '../util/assert';
31+
import { debugAssert, debugCast } from '../util/assert';
3232
import {
3333
applyBundleDocuments,
34+
getQueryDocumentMapping,
3435
LocalStore,
3536
saveNamedQuery
3637
} from '../local/local_store';
3738
import { SizedBundleElement } from '../util/bundle_reader';
38-
import { MaybeDocumentMap } from '../model/collections';
39+
import {
40+
documentKeySet,
41+
DocumentKeySet,
42+
MaybeDocumentMap
43+
} from '../model/collections';
3944
import { BundleMetadata } from '../protos/firestore_bundle_proto';
4045

4146
/**
@@ -218,17 +223,20 @@ export class BundleLoader {
218223
'Bundled documents ends with a document metadata and missing document.'
219224
);
220225

221-
const result = await applyBundleDocuments(this.localStore, this.documents);
226+
const changedDocuments = await applyBundleDocuments(
227+
this.localStore,
228+
this.documents
229+
);
222230

231+
const queryDocumentMap = getQueryDocumentMapping(
232+
this.localStore,
233+
this.documents
234+
);
223235
for (const q of this.queries) {
224-
await saveNamedQuery(
225-
this.localStore,
226-
q,
227-
result.queryDocumentMap.get(q.name!)
228-
);
236+
await saveNamedQuery(this.localStore, q, queryDocumentMap.get(q.name!));
229237
}
230238

231239
this.progress.taskState = 'Success';
232-
return new BundleLoadResult({ ...this.progress }, result.changedDocuments);
240+
return new BundleLoadResult({ ...this.progress }, changedDocuments);
233241
}
234242
}

packages/firestore/src/local/local_store.ts

Lines changed: 44 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1249,9 +1249,28 @@ export async function ignoreIfPrimaryLeaseLoss(
12491249
}
12501250
}
12511251

1252-
export interface ApplyBundleDocumentsResult {
1253-
changedDocuments: MaybeDocumentMap;
1254-
queryDocumentMap: Map<string, DocumentKeySet>;
1252+
export function getQueryDocumentMapping(
1253+
localStore: LocalStore,
1254+
documents: BundledDocuments
1255+
): Map<string, DocumentKeySet> {
1256+
const localStoreImpl = debugCast(localStore, LocalStoreImpl);
1257+
const queryDocumentMap = new Map<string, DocumentKeySet>();
1258+
const bundleConverter = new BundleConverter(localStoreImpl.serializer);
1259+
for (const bundleDoc of documents) {
1260+
if (bundleDoc.metadata.queries) {
1261+
const documentKey = bundleConverter.toDocumentKey(
1262+
bundleDoc.metadata.name!
1263+
);
1264+
for (const queryName of bundleDoc.metadata.queries) {
1265+
const documentKeys = (
1266+
queryDocumentMap.get(queryName) || documentKeySet()
1267+
).add(documentKey);
1268+
queryDocumentMap.set(queryName, documentKeys);
1269+
}
1270+
}
1271+
}
1272+
1273+
return queryDocumentMap;
12551274
}
12561275

12571276
/**
@@ -1264,12 +1283,11 @@ export interface ApplyBundleDocumentsResult {
12641283
export function applyBundleDocuments(
12651284
localStore: LocalStore,
12661285
documents: BundledDocuments
1267-
): Promise<ApplyBundleDocumentsResult> {
1286+
): Promise<MaybeDocumentMap> {
12681287
const localStoreImpl = debugCast(localStore, LocalStoreImpl);
12691288
const bundleConverter = new BundleConverter(localStoreImpl.serializer);
12701289
let documentMap = maybeDocumentMap();
12711290
let versionMap = documentVersionMap();
1272-
const queryDocumentMap: Map<string, DocumentKeySet> = new Map();
12731291
for (const bundleDoc of documents) {
12741292
const documentKey = bundleConverter.toDocumentKey(bundleDoc.metadata.name!);
12751293
documentMap = documentMap.insert(
@@ -1280,14 +1298,6 @@ export function applyBundleDocuments(
12801298
documentKey,
12811299
bundleConverter.toSnapshotVersion(bundleDoc.metadata.readTime!)
12821300
);
1283-
if (bundleDoc.metadata.queries) {
1284-
for (const queryName of bundleDoc.metadata.queries) {
1285-
const documentKeys = (
1286-
queryDocumentMap.get(queryName) || documentKeySet()
1287-
).add(documentKey);
1288-
queryDocumentMap.set(queryName, documentKeys);
1289-
}
1290-
}
12911301
}
12921302

12931303
const documentBuffer = localStoreImpl.remoteDocuments.newChangeBuffer({
@@ -1316,10 +1326,7 @@ export function applyBundleDocuments(
13161326
);
13171327
})
13181328
.next(changedDocuments => {
1319-
return PersistencePromise.resolve({
1320-
changedDocuments,
1321-
queryDocumentMap
1322-
});
1329+
return PersistencePromise.resolve(changedDocuments);
13231330
});
13241331
}
13251332
);
@@ -1410,32 +1417,40 @@ export async function saveNamedQuery(
14101417
'readwrite',
14111418
transaction => {
14121419
// Update allocated target's read time, if the bundle's read time is newer.
1413-
let updateReadTime = PersistencePromise.resolve();
1420+
let updateReadTime = PersistencePromise.resolve(false);
14141421
const readTime = fromVersion(query.readTime!);
14151422
if (allocated.snapshotVersion.compareTo(readTime) < 0) {
14161423
const newTargetData = allocated.withResumeToken(
14171424
ByteString.EMPTY_BYTE_STRING,
14181425
readTime
14191426
);
1420-
updateReadTime = localStoreImpl.targetCache.updateTargetData(
1421-
transaction,
1422-
newTargetData
1423-
);
1427+
updateReadTime = localStoreImpl.targetCache
1428+
.updateTargetData(transaction, newTargetData)
1429+
.next(
1430+
() => true,
1431+
() => false
1432+
);
14241433
localStoreImpl.targetDataByTarget = localStoreImpl.targetDataByTarget.insert(
14251434
newTargetData.targetId,
14261435
newTargetData
14271436
);
14281437
}
14291438
return updateReadTime
1439+
.next(updated => {
1440+
if (updated) {
1441+
return localStoreImpl.targetCache
1442+
.removeMatchingKeysForTargetId(transaction, allocated.targetId)
1443+
.next(() =>
1444+
localStoreImpl.targetCache.addMatchingKeys(
1445+
transaction,
1446+
documents,
1447+
allocated.targetId
1448+
)
1449+
);
1450+
}
1451+
})
14301452
.next(() =>
14311453
localStoreImpl.bundleCache.saveNamedQuery(transaction, query)
1432-
)
1433-
.next(() =>
1434-
localStoreImpl.targetCache.addMatchingKeys(
1435-
transaction,
1436-
documents,
1437-
allocated.targetId
1438-
)
14391454
);
14401455
}
14411456
);

packages/firestore/src/protos/firestore_bundle_proto.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ export interface BundledDocumentMetadata {
5656
exists?: boolean | null;
5757

5858
/** The names of the queries in this bundle that this document matches to. */
59-
queries?: string[] | null;
59+
queries?: string[];
6060
}
6161

6262
/** Properties of a BundleMetadata. */

packages/firestore/test/unit/local/local_store.test.ts

Lines changed: 3 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ import { IndexFreeQueryEngine } from '../../../src/local/index_free_query_engine
3535
import { IndexedDbPersistence } from '../../../src/local/indexeddb_persistence';
3636
import {
3737
applyBundleDocuments,
38-
ApplyBundleDocumentsResult,
3938
getNamedQuery,
4039
hasNewerBundle,
4140
LocalStore,
@@ -116,7 +115,6 @@ export interface LocalStoreComponents {
116115
class LocalStoreTester {
117116
private promiseChain: Promise<void> = Promise.resolve();
118117
private lastChanges: MaybeDocumentMap | null = null;
119-
private lastBundleQueryDocumentMap: Map<string, DocumentKeySet> | null = null;
120118
private lastTargetId: TargetId | null = null;
121119
private batches: MutationBatch[] = [];
122120

@@ -129,7 +127,6 @@ class LocalStoreTester {
129127
private prepareNextStep(): void {
130128
this.promiseChain = this.promiseChain.then(() => {
131129
this.lastChanges = null;
132-
this.lastBundleQueryDocumentMap = null;
133130
this.lastTargetId = null;
134131
this.queryEngine.resetCounts();
135132
});
@@ -193,9 +190,8 @@ class LocalStoreTester {
193190

194191
this.promiseChain = this.promiseChain
195192
.then(() => applyBundleDocuments(this.localStore, documents))
196-
.then((result: ApplyBundleDocumentsResult) => {
197-
this.lastChanges = result.changedDocuments;
198-
this.lastBundleQueryDocumentMap = result.queryDocumentMap;
193+
.then(result => {
194+
this.lastChanges = result;
199195
});
200196
return this;
201197
}
@@ -382,25 +378,6 @@ class LocalStoreTester {
382378
return this;
383379
}
384380

385-
toReturnQueryDocumentMap(
386-
expected: Map<string, DocumentKeySet>
387-
): LocalStoreTester {
388-
this.promiseChain = this.promiseChain.then(() => {
389-
debugAssert(
390-
!!this.lastBundleQueryDocumentMap,
391-
'Expecting query document map to be returned from applying bundled documents'
392-
);
393-
for (const k of Array.from(this.lastBundleQueryDocumentMap.keys())) {
394-
expect(expected.has(k)).to.be.true;
395-
expect(
396-
this.lastBundleQueryDocumentMap.get(k)!.isEqual(expected.get(k)!)
397-
).to.be.true;
398-
}
399-
this.lastBundleQueryDocumentMap = null;
400-
});
401-
return this;
402-
}
403-
404381
toReturnRemoved(...keyStrings: string[]): LocalStoreTester {
405382
this.promiseChain = this.promiseChain.then(() => {
406383
debugAssert(
@@ -1758,7 +1735,7 @@ function genericLocalStoreTests(
17581735
.finish();
17591736
});
17601737

1761-
it('handles loading named queries allocates targets and updates target document mapping', async () => {
1738+
it('loading named queries allocates targets and updates target document mapping', async () => {
17621739
const expectedQueryDocumentMap = new Map([
17631740
['query-1', documentKeySet(key('foo1/bar'))],
17641741
['query-2', documentKeySet(key('foo2/bar'))]
@@ -1777,7 +1754,6 @@ function genericLocalStoreTests(
17771754
doc('foo1/bar', 1, { sum: 1337 }),
17781755
doc('foo2/bar', 2, { sum: 42 })
17791756
)
1780-
.toReturnQueryDocumentMap(expectedQueryDocumentMap)
17811757
.toContain(doc('foo1/bar', 1, { sum: 1337 }))
17821758
.toContain(doc('foo2/bar', 2, { sum: 42 }))
17831759
.after(

0 commit comments

Comments
 (0)