Skip to content

Commit d46c5b2

Browse files
committed
Use ObjectMap instead of Map with proper comparator.
1 parent bd5b4d8 commit d46c5b2

File tree

7 files changed

+93
-46
lines changed

7 files changed

+93
-46
lines changed

packages/firestore/src/local/document_overlay_cache.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,12 @@
1515
* limitations under the License.
1616
*/
1717

18-
import { DocumentKeySet } from '../model/collections';
18+
import {
19+
DocumentKeySet,
20+
DocumentKeyToMutationMap,
21+
DocumentKeyToOverlayMap
22+
} from '../model/collections';
1923
import { DocumentKey } from '../model/document_key';
20-
import { Mutation } from '../model/mutation';
2124
import { Overlay } from '../model/overlay';
2225
import { ResourcePath } from '../model/path';
2326

@@ -51,7 +54,7 @@ export interface DocumentOverlayCache {
5154
saveOverlays(
5255
transaction: PersistenceTransaction,
5356
largestBatchId: number,
54-
overlays: Map<DocumentKey, Mutation>
57+
overlays: DocumentKeyToMutationMap
5558
): PersistencePromise<void>;
5659

5760
/** Removes overlays for the given document keys and batch ID. */
@@ -74,7 +77,7 @@ export interface DocumentOverlayCache {
7477
transaction: PersistenceTransaction,
7578
collection: ResourcePath,
7679
sinceBatchId: number
77-
): PersistencePromise<Map<DocumentKey, Overlay>>;
80+
): PersistencePromise<DocumentKeyToOverlayMap>;
7881

7982
/**
8083
* Returns `count` overlays with a batch ID higher than `sinceBatchId` for the
@@ -95,5 +98,5 @@ export interface DocumentOverlayCache {
9598
collectionGroup: string,
9699
sinceBatchId: number,
97100
count: number
98-
): PersistencePromise<Map<DocumentKey, Overlay>>;
101+
): PersistencePromise<DocumentKeyToOverlayMap>;
99102
}

packages/firestore/src/local/indexeddb_document_overlay_cache.ts

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,13 @@
1616
*/
1717

1818
import { User } from '../auth/user';
19-
import { DocumentKeySet } from '../model/collections';
19+
import {
20+
DocumentKeySet,
21+
DocumentKeyToMutationMap,
22+
DocumentKeyToOverlayMap,
23+
newDocumentKeyToOverlayMap
24+
} from '../model/collections';
2025
import { DocumentKey } from '../model/document_key';
21-
import { Mutation } from '../model/mutation';
2226
import { Overlay } from '../model/overlay';
2327
import { ResourcePath } from '../model/path';
2428

@@ -74,10 +78,10 @@ export class IndexedDbDocumentOverlayCache implements DocumentOverlayCache {
7478
saveOverlays(
7579
transaction: PersistenceTransaction,
7680
largestBatchId: number,
77-
overlays: Map<DocumentKey, Mutation>
81+
overlays: DocumentKeyToMutationMap
7882
): PersistencePromise<void> {
7983
const promises: Array<PersistencePromise<void>> = [];
80-
overlays.forEach(mutation => {
84+
overlays.forEach((_, mutation) => {
8185
const overlay = new Overlay(largestBatchId, mutation);
8286
promises.push(this.saveOverlay(transaction, overlay));
8387
});
@@ -118,8 +122,8 @@ export class IndexedDbDocumentOverlayCache implements DocumentOverlayCache {
118122
transaction: PersistenceTransaction,
119123
collection: ResourcePath,
120124
sinceBatchId: number
121-
): PersistencePromise<Map<DocumentKey, Overlay>> {
122-
const result = new Map<DocumentKey, Overlay>();
125+
): PersistencePromise<DocumentKeyToOverlayMap> {
126+
const result = newDocumentKeyToOverlayMap();
123127
const collectionPath = encodeResourcePath(collection);
124128
// We want batch IDs larger than `sinceBatchId`, and so the lower bound
125129
// is not inclusive.
@@ -144,8 +148,8 @@ export class IndexedDbDocumentOverlayCache implements DocumentOverlayCache {
144148
collectionGroup: string,
145149
sinceBatchId: number,
146150
count: number
147-
): PersistencePromise<Map<DocumentKey, Overlay>> {
148-
const result = new Map<DocumentKey, Overlay>();
151+
): PersistencePromise<DocumentKeyToOverlayMap> {
152+
const result = newDocumentKeyToOverlayMap();
149153
let currentBatchId: number | undefined = undefined;
150154
// We want batch IDs larger than `sinceBatchId`, and so the lower bound
151155
// is not inclusive.
@@ -167,7 +171,7 @@ export class IndexedDbDocumentOverlayCache implements DocumentOverlayCache {
167171
// `count` if there are more overlays from the `currentBatchId`.
168172
const overlay = fromDbDocumentOverlay(this.serializer, dbOverlay);
169173
if (
170-
result.size < count ||
174+
result.size() < count ||
171175
overlay.largestBatchId === currentBatchId
172176
) {
173177
result.set(overlay.getKey(), overlay);

packages/firestore/src/local/memory_document_overlay_cache.ts

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,18 @@
1515
* limitations under the License.
1616
*/
1717

18-
import { DocumentKeySet } from '../model/collections';
18+
import {
19+
DocumentKeySet,
20+
DocumentKeyToMutationMap,
21+
DocumentKeyToOverlayMap,
22+
newDocumentKeyToOverlayMap
23+
} from '../model/collections';
1924
import { DocumentKey } from '../model/document_key';
2025
import { Mutation } from '../model/mutation';
2126
import { Overlay } from '../model/overlay';
2227
import { ResourcePath } from '../model/path';
2328
import { SortedMap } from '../util/sorted_map';
29+
import { SortedSet } from '../util/sorted_set';
2430

2531
import { DocumentOverlayCache } from './document_overlay_cache';
2632
import { PersistencePromise } from './persistence_promise';
@@ -35,7 +41,7 @@ export class MemoryDocumentOverlayCache implements DocumentOverlayCache {
3541
private overlays = new SortedMap<DocumentKey, Overlay>(
3642
DocumentKey.comparator
3743
);
38-
private overlayByBatchId = new Map<number, Set<DocumentKey>>();
44+
private overlayByBatchId = new Map<number, DocumentKeySet>();
3945

4046
getOverlay(
4147
transaction: PersistenceTransaction,
@@ -47,9 +53,9 @@ export class MemoryDocumentOverlayCache implements DocumentOverlayCache {
4753
saveOverlays(
4854
transaction: PersistenceTransaction,
4955
largestBatchId: number,
50-
overlays: Map<DocumentKey, Mutation>
56+
overlays: DocumentKeyToMutationMap
5157
): PersistencePromise<void> {
52-
overlays.forEach(mutation => {
58+
overlays.forEach((_, mutation) => {
5359
this.saveOverlay(transaction, largestBatchId, mutation);
5460
});
5561
return PersistencePromise.resolve();
@@ -72,8 +78,8 @@ export class MemoryDocumentOverlayCache implements DocumentOverlayCache {
7278
transaction: PersistenceTransaction,
7379
collection: ResourcePath,
7480
sinceBatchId: number
75-
): PersistencePromise<Map<DocumentKey, Overlay>> {
76-
const result = new Map<DocumentKey, Overlay>();
81+
): PersistencePromise<DocumentKeyToOverlayMap> {
82+
const result = newDocumentKeyToOverlayMap();
7783

7884
const immediateChildrenPathLength = collection.length + 1;
7985
const prefix = new DocumentKey(collection.child(''));
@@ -102,8 +108,8 @@ export class MemoryDocumentOverlayCache implements DocumentOverlayCache {
102108
collectionGroup: string,
103109
sinceBatchId: number,
104110
count: number
105-
): PersistencePromise<Map<DocumentKey, Overlay>> {
106-
let batchIdToOverlays = new SortedMap<number, Map<DocumentKey, Overlay>>(
111+
): PersistencePromise<DocumentKeyToOverlayMap> {
112+
let batchIdToOverlays = new SortedMap<number, DocumentKeyToOverlayMap>(
107113
(key1: number, key2: number) => key1 - key2
108114
);
109115

@@ -118,7 +124,7 @@ export class MemoryDocumentOverlayCache implements DocumentOverlayCache {
118124
if (overlay.largestBatchId > sinceBatchId) {
119125
let overlaysForBatchId = batchIdToOverlays.get(overlay.largestBatchId);
120126
if (overlaysForBatchId === null) {
121-
overlaysForBatchId = new Map<DocumentKey, Overlay>();
127+
overlaysForBatchId = newDocumentKeyToOverlayMap();
122128
batchIdToOverlays = batchIdToOverlays.insert(
123129
overlay.largestBatchId,
124130
overlaysForBatchId
@@ -128,13 +134,13 @@ export class MemoryDocumentOverlayCache implements DocumentOverlayCache {
128134
}
129135
}
130136

131-
const result = new Map<DocumentKey, Overlay>();
137+
const result = newDocumentKeyToOverlayMap();
132138
const batchIter = batchIdToOverlays.getIterator();
133139
while (batchIter.hasNext()) {
134140
const entry = batchIter.getNext();
135141
const overlays = entry.value;
136-
overlays.forEach((overlay, key) => result.set(key, overlay));
137-
if (result.size >= count) {
142+
overlays.forEach((key, overlay) => result.set(key, overlay));
143+
if (result.size() >= count) {
138144
break;
139145
}
140146
}
@@ -153,7 +159,10 @@ export class MemoryDocumentOverlayCache implements DocumentOverlayCache {
153159
// Remove the association of the overlay to its batch id.
154160
const existing = this.overlays.get(mutation.key);
155161
if (existing !== null) {
156-
this.overlayByBatchId.get(existing.largestBatchId)!.delete(mutation.key);
162+
const newSet = this.overlayByBatchId
163+
.get(existing.largestBatchId)!
164+
.delete(mutation.key);
165+
this.overlayByBatchId.set(existing.largestBatchId, newSet);
157166
}
158167

159168
this.overlays = this.overlays.insert(
@@ -164,9 +173,9 @@ export class MemoryDocumentOverlayCache implements DocumentOverlayCache {
164173
// Create the association of this overlay to the given largestBatchId.
165174
let batch = this.overlayByBatchId.get(largestBatchId);
166175
if (batch === undefined) {
167-
batch = new Set<DocumentKey>();
176+
batch = new SortedSet(DocumentKey.comparator);
168177
this.overlayByBatchId.set(largestBatchId, batch);
169178
}
170-
batch.add(mutation.key);
179+
this.overlayByBatchId.set(largestBatchId, batch.add(mutation.key));
171180
}
172181
}

packages/firestore/src/model/collections.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,14 @@
1818
import { SnapshotVersion } from '../core/snapshot_version';
1919
import { TargetId } from '../core/types';
2020
import { primitiveComparator } from '../util/misc';
21+
import { ObjectMap } from '../util/obj_map';
2122
import { SortedMap } from '../util/sorted_map';
2223
import { SortedSet } from '../util/sorted_set';
2324

2425
import { Document, MutableDocument } from './document';
2526
import { DocumentKey } from './document_key';
27+
import { Mutation } from './mutation';
28+
import { Overlay } from './overlay';
2629

2730
/** Miscellaneous collection types / constants. */
2831

@@ -47,6 +50,22 @@ export function documentMap(): DocumentMap {
4750
return EMPTY_DOCUMENT_MAP;
4851
}
4952

53+
export type DocumentKeyToOverlayMap = ObjectMap<DocumentKey, Overlay>;
54+
export function newDocumentKeyToOverlayMap(): DocumentKeyToOverlayMap {
55+
return new ObjectMap<DocumentKey, Overlay>(
56+
key => key.toString(),
57+
(l, r) => l.isEqual(r)
58+
);
59+
}
60+
61+
export type DocumentKeyToMutationMap = ObjectMap<DocumentKey, Mutation>;
62+
export function newDocumentKeyToMutationMap(): DocumentKeyToMutationMap {
63+
return new ObjectMap<DocumentKey, Mutation>(
64+
key => key.toString(),
65+
(l, r) => l.isEqual(r)
66+
);
67+
}
68+
5069
export type DocumentVersionMap = SortedMap<DocumentKey, SnapshotVersion>;
5170
const EMPTY_DOCUMENT_VERSION_MAP = new SortedMap<DocumentKey, SnapshotVersion>(
5271
DocumentKey.comparator

packages/firestore/src/util/obj_map.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* limitations under the License.
1616
*/
1717

18-
import { forEach, isEmpty } from './obj';
18+
import { forEach, isEmpty, objectSize } from './obj';
1919

2020
type Entry<K, V> = [K, V];
2121

@@ -110,4 +110,8 @@ export class ObjectMap<KeyType, ValueType> {
110110
isEmpty(): boolean {
111111
return isEmpty(this.inner);
112112
}
113+
114+
size(): number {
115+
return objectSize(this.inner);
116+
}
113117
}

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

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,16 @@ import { expect } from 'chai';
1919
import { User } from '../../../src/auth/user';
2020
import { IndexedDbPersistence } from '../../../src/local/indexeddb_persistence';
2121
import { Persistence } from '../../../src/local/persistence';
22-
import { documentKeySet, DocumentKeySet } from '../../../src/model/collections';
22+
import {
23+
documentKeySet,
24+
DocumentKeySet,
25+
DocumentKeyToMutationMap,
26+
DocumentKeyToOverlayMap,
27+
newDocumentKeyToMutationMap
28+
} from '../../../src/model/collections';
2329
import { DocumentKey } from '../../../src/model/document_key';
2430
import { Mutation, mutationEquals } from '../../../src/model/mutation';
25-
import { Overlay } from '../../../src/model/overlay';
31+
import { SortedSet } from '../../../src/util/sorted_set';
2632
import { addEqualityMatcher } from '../../util/equality_matcher';
2733
import {
2834
deleteMutation,
@@ -86,7 +92,7 @@ function genericDocumentOverlayCacheTests(): void {
8692
largestBatch: number,
8793
...mutations: Mutation[]
8894
): Promise<void> {
89-
const data: Map<DocumentKey, Mutation> = new Map<DocumentKey, Mutation>();
95+
const data: DocumentKeyToMutationMap = newDocumentKeyToMutationMap();
9096
for (const mutation of mutations) {
9197
data.set(mutation.key, mutation);
9298
}
@@ -97,7 +103,7 @@ function genericDocumentOverlayCacheTests(): void {
97103
largestBatch: number,
98104
...overlayKeys: string[]
99105
): Promise<void> {
100-
const data: Map<DocumentKey, Mutation> = new Map<DocumentKey, Mutation>();
106+
const data: DocumentKeyToMutationMap = newDocumentKeyToMutationMap();
101107
for (const overlayKey of overlayKeys) {
102108
data.set(key(overlayKey), setMutation(overlayKey, {}));
103109
}
@@ -115,16 +121,14 @@ function genericDocumentOverlayCacheTests(): void {
115121
}
116122

117123
function verifyOverlayContains(
118-
overlays: Map<DocumentKey, Overlay>,
124+
overlays: DocumentKeyToOverlayMap,
119125
...keys: string[]
120126
): void {
121-
const overlayKeys: DocumentKeySet = documentKeySet(
122-
...Array.from(overlays.keys())
123-
);
124-
const expectedKeys: DocumentKeySet = documentKeySet(
125-
...Array.from(keys.map(value => key(value)))
126-
);
127-
expect(overlayKeys.isEqual(expectedKeys)).to.equal(true);
127+
const overlayKeys: DocumentKeySet = new SortedSet(DocumentKey.comparator);
128+
overlays.forEach(overlayKey => overlayKeys.add(overlayKey));
129+
const expectedKeys: DocumentKeySet = new SortedSet(DocumentKey.comparator);
130+
keys.forEach(value => expectedKeys.add(key(value)));
131+
expect(overlayKeys.isEqual(expectedKeys)).to.deep.equal(true);
128132
}
129133

130134
it('returns null when overlay is not found', async () => {

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

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@
1717

1818
import { DocumentOverlayCache } from '../../../src/local/document_overlay_cache';
1919
import { Persistence } from '../../../src/local/persistence';
20-
import { DocumentKeySet } from '../../../src/model/collections';
20+
import {
21+
DocumentKeySet,
22+
DocumentKeyToMutationMap,
23+
DocumentKeyToOverlayMap
24+
} from '../../../src/model/collections';
2125
import { DocumentKey } from '../../../src/model/document_key';
2226
import { Mutation } from '../../../src/model/mutation';
2327
import { Overlay } from '../../../src/model/overlay';
@@ -36,7 +40,7 @@ export class TestDocumentOverlayCache {
3640

3741
saveOverlays(
3842
largestBatch: number,
39-
data: Map<DocumentKey, Mutation>
43+
data: DocumentKeyToMutationMap
4044
): Promise<void> {
4145
return this.persistence.runTransaction('saveOverlays', 'readwrite', txn => {
4246
return this.cache.saveOverlays(txn, largestBatch, data);
@@ -61,7 +65,7 @@ export class TestDocumentOverlayCache {
6165
getOverlaysForCollection(
6266
path: ResourcePath,
6367
sinceBatchId: number
64-
): Promise<Map<DocumentKey, Overlay>> {
68+
): Promise<DocumentKeyToOverlayMap> {
6569
return this.persistence.runTransaction(
6670
'getOverlaysForCollection',
6771
'readonly',
@@ -75,7 +79,7 @@ export class TestDocumentOverlayCache {
7579
collectionGroup: string,
7680
sinceBatchId: number,
7781
count: number
78-
): Promise<Map<DocumentKey, Overlay>> {
82+
): Promise<DocumentKeyToOverlayMap> {
7983
return this.persistence.runTransaction(
8084
'getOverlaysForCollectionGroup',
8185
'readonly',

0 commit comments

Comments
 (0)