|
15 | 15 | * limitations under the License.
|
16 | 16 | */
|
17 | 17 |
|
18 |
| -import { assert } from '../util/assert'; |
19 | 18 | import { TargetId } from './types';
|
20 | 19 |
|
21 |
| -const RESERVED_BITS = 1; |
22 |
| - |
23 |
| -const enum GeneratorIds { |
24 |
| - QueryCache = 0, // The target IDs for user-issued queries are even (end in 0). |
25 |
| - SyncEngine = 1 // The target IDs for limbo detection are odd (end in 1). |
26 |
| -} |
| 20 | +/** Offset to ensure non-overlapping target ids. */ |
| 21 | +const OFFSET = 2; |
27 | 22 |
|
28 | 23 | /**
|
29 | 24 | * Generates monotonically increasing target IDs for sending targets to the
|
30 | 25 | * watch stream.
|
31 | 26 | *
|
32 |
| - * The client constructs two generators, one for the query cache (via |
33 |
| - * forQueryCache()), and one for limbo documents (via forSyncEngine()). These |
34 |
| - * two generators produce non-overlapping IDs (by using even and odd IDs |
| 27 | + * The client constructs two generators, one for the target cache, and one for |
| 28 | + * for the sync engine (to generate limbo documents targets). These |
| 29 | + * generators produce non-overlapping IDs (by using even and odd IDs |
35 | 30 | * respectively).
|
36 | 31 | *
|
37 | 32 | * By separating the target ID space, the query cache can generate target IDs
|
38 | 33 | * that persist across client restarts, while sync engine can independently
|
39 | 34 | * generate in-memory target IDs that are transient and can be reused after a
|
40 | 35 | * restart.
|
41 | 36 | */
|
42 |
| -// TODO(mrschmidt): Explore removing this class in favor of generating these IDs |
43 |
| -// directly in SyncEngine and LocalStore. |
44 | 37 | export class TargetIdGenerator {
|
45 |
| - // Initialized in the constructor via call to seek(). |
46 |
| - private nextId!: TargetId; |
47 |
| - |
48 |
| - /** |
49 |
| - * Instantiates a new TargetIdGenerator. If a seed is provided, the generator |
50 |
| - * will use the seed value as the next target ID. |
51 |
| - */ |
52 |
| - constructor(private generatorId: number, seed?: number) { |
53 |
| - assert( |
54 |
| - (generatorId & RESERVED_BITS) === generatorId, |
55 |
| - `Generator ID ${generatorId} contains more than ${RESERVED_BITS} reserved bits` |
56 |
| - ); |
57 |
| - this.seek(seed !== undefined ? seed : this.generatorId); |
58 |
| - } |
| 38 | + constructor(private lastId: number) {} |
59 | 39 |
|
60 | 40 | next(): TargetId {
|
61 |
| - const nextId = this.nextId; |
62 |
| - this.nextId += 1 << RESERVED_BITS; |
63 |
| - return nextId; |
64 |
| - } |
65 |
| - |
66 |
| - /** |
67 |
| - * Returns the ID that follows the given ID. Subsequent calls to `next()` |
68 |
| - * use the newly returned target ID as their base. |
69 |
| - */ |
70 |
| - // PORTING NOTE: Multi-tab only. |
71 |
| - after(targetId: TargetId): TargetId { |
72 |
| - this.seek(targetId + (1 << RESERVED_BITS)); |
73 |
| - return this.next(); |
74 |
| - } |
75 |
| - |
76 |
| - private seek(targetId: TargetId): void { |
77 |
| - assert( |
78 |
| - (targetId & RESERVED_BITS) === this.generatorId, |
79 |
| - 'Cannot supply target ID from different generator ID' |
80 |
| - ); |
81 |
| - this.nextId = targetId; |
| 41 | + this.lastId += OFFSET; |
| 42 | + return this.lastId; |
82 | 43 | }
|
83 | 44 |
|
84 | 45 | static forTargetCache(): TargetIdGenerator {
|
85 |
| - // We seed the query cache generator to return '2' as its first ID, as there |
86 |
| - // is no differentiation in the protocol layer between an unset number and |
87 |
| - // the number '0'. If we were to sent a target with target ID '0', the |
88 |
| - // backend would consider it unset and replace it with its own ID. |
89 |
| - const targetIdGenerator = new TargetIdGenerator(GeneratorIds.QueryCache, 2); |
90 |
| - return targetIdGenerator; |
| 46 | + // The target cache generator must return '2' in its first call to `next()` |
| 47 | + // as there is no differentiation in the protocol layer between an unset |
| 48 | + // number and the number '0'. If we were to sent a target with target ID |
| 49 | + // '0', the backend would consider it unset and replace it with its own ID. |
| 50 | + return new TargetIdGenerator(2 - OFFSET); |
91 | 51 | }
|
92 | 52 |
|
93 | 53 | static forSyncEngine(): TargetIdGenerator {
|
94 | 54 | // Sync engine assigns target IDs for limbo document detection.
|
95 |
| - return new TargetIdGenerator(GeneratorIds.SyncEngine); |
| 55 | + return new TargetIdGenerator(1 - OFFSET); |
96 | 56 | }
|
97 | 57 | }
|
0 commit comments