Skip to content

Commit cd2a0e2

Browse files
Add Query to Target ID Map
1 parent 1ccb186 commit cd2a0e2

File tree

1 file changed

+40
-42
lines changed

1 file changed

+40
-42
lines changed

packages/firestore/src/local/local_store.ts

Lines changed: 40 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import { RemoteEvent, TargetChange } from '../remote/remote_event';
3939
import { assert } from '../util/assert';
4040
import * as log from '../util/log';
4141
import * as objUtils from '../util/obj';
42+
import { ObjectMap } from '../util/obj_map';
4243

4344
import { LocalDocumentsView } from './local_documents_view';
4445
import { LocalViewChanges } from './local_view_changes';
@@ -162,6 +163,11 @@ export class LocalStore {
162163
/** Maps a targetID to data about its query. */
163164
private queryDataByTarget = {} as { [targetId: number]: QueryData };
164165

166+
/** Maps a query to its targetID. */
167+
private targetIdByQuery = new ObjectMap<Query, TargetId>(q =>
168+
q.canonicalId()
169+
);
170+
165171
constructor(
166172
/** Manages our in-memory or durable persistence. */
167173
private persistence: Persistence,
@@ -774,6 +780,7 @@ export class LocalStore {
774780
'Tried to allocate an already allocated query: ' + query
775781
);
776782
this.queryDataByTarget[queryData.targetId] = queryData;
783+
this.targetIdByQuery.set(query, queryData.targetId);
777784
return queryData;
778785
});
779786
}
@@ -789,22 +796,14 @@ export class LocalStore {
789796
transaction: PersistenceTransaction,
790797
query: Query
791798
): PersistencePromise<QueryData | null> {
792-
let queryData: QueryData | null = null;
793-
794-
// Look up the query data in our local map first, as this avoids a potential
795-
// lookup in IndexedDb.
796-
objUtils.forEachNumber(
797-
this.queryDataByTarget,
798-
(targetId, cachedQueryData) => {
799-
if (cachedQueryData.query.isEqual(query)) {
800-
queryData = cachedQueryData;
801-
}
802-
}
803-
);
804-
805-
return queryData
806-
? PersistencePromise.resolve<QueryData | null>(queryData)
807-
: this.queryCache.getQueryData(transaction, query);
799+
let targetId = this.targetIdByQuery.get(query);
800+
if (targetId !== undefined) {
801+
return PersistencePromise.resolve<QueryData | null>(
802+
this.queryDataByTarget[targetId]
803+
);
804+
} else {
805+
return this.queryCache.getQueryData(transaction, query);
806+
}
808807
}
809808

810809
/**
@@ -816,32 +815,31 @@ export class LocalStore {
816815
releaseQuery(query: Query, keepPersistedQueryData: boolean): Promise<void> {
817816
const mode = keepPersistedQueryData ? 'readwrite' : 'readwrite-primary';
818817
return this.persistence.runTransaction('Release query', mode, txn => {
819-
return this.getQueryData(txn, query).next(queryData => {
820-
assert(
821-
queryData != null,
822-
'Tried to release nonexistent query: ' + query
823-
);
824-
const targetId = queryData!.targetId;
825-
826-
// References for documents sent via Watch are automatically removed
827-
// when we delete a query's target data from the reference delegate.
828-
// Since this does not remove references for locally mutated documents,
829-
// we have to remove the target associations for these documents
830-
// manually.
831-
const removed = this.localViewReferences.removeReferencesForId(
832-
targetId
833-
);
834-
delete this.queryDataByTarget[targetId];
835-
if (!keepPersistedQueryData) {
836-
return PersistencePromise.forEach(removed, (key: DocumentKey) =>
837-
this.persistence.referenceDelegate.removeReference(txn, key)
838-
).next(() =>
839-
this.persistence.referenceDelegate.removeTarget(txn, queryData!)
840-
);
841-
} else {
842-
return PersistencePromise.resolve();
843-
}
844-
});
818+
const targetId = this.targetIdByQuery.get(query);
819+
assert(
820+
targetId !== undefined,
821+
'Tried to release nonexistent query: ' + query
822+
);
823+
const queryData = this.queryDataByTarget[targetId!]!;
824+
825+
// References for documents sent via Watch are automatically removed
826+
// when we delete a query's target data from the reference delegate.
827+
// Since this does not remove references for locally mutated documents,
828+
// we have to remove the target associations for these documents
829+
// manually.
830+
const removed = this.localViewReferences.removeReferencesForId(targetId!);
831+
delete this.queryDataByTarget[targetId!];
832+
this.targetIdByQuery.delete(query);
833+
834+
if (!keepPersistedQueryData) {
835+
return PersistencePromise.forEach(removed, (key: DocumentKey) =>
836+
this.persistence.referenceDelegate.removeReference(txn, key)
837+
).next(() => {
838+
this.persistence.referenceDelegate.removeTarget(txn, queryData);
839+
});
840+
} else {
841+
return PersistencePromise.resolve();
842+
}
845843
});
846844
}
847845

0 commit comments

Comments
 (0)