@fluidframework/container-runtime 2.0.0-dev.7.4.0.217212 → 2.0.0-dev.7.4.0.221926
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/api-extractor.json +0 -3
- package/api-report/container-runtime.api.md +77 -73
- package/dist/blobManager.d.ts +4 -4
- package/dist/blobManager.d.ts.map +1 -1
- package/dist/blobManager.js.map +1 -1
- package/dist/container-runtime-alpha.d.ts +1361 -132
- package/dist/container-runtime-beta.d.ts +40 -2
- package/dist/container-runtime-public.d.ts +40 -2
- package/dist/container-runtime-untrimmed.d.ts +106 -93
- package/dist/containerRuntime.d.ts +19 -17
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +44 -24
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStores.d.ts +10 -15
- package/dist/dataStores.d.ts.map +1 -1
- package/dist/dataStores.js +63 -36
- package/dist/dataStores.js.map +1 -1
- package/dist/gc/garbageCollection.d.ts +29 -10
- package/dist/gc/garbageCollection.d.ts.map +1 -1
- package/dist/gc/garbageCollection.js +149 -67
- package/dist/gc/garbageCollection.js.map +1 -1
- package/dist/gc/gcConfigs.d.ts.map +1 -1
- package/dist/gc/gcConfigs.js +34 -37
- package/dist/gc/gcConfigs.js.map +1 -1
- package/dist/gc/gcDefinitions.d.ts +97 -44
- package/dist/gc/gcDefinitions.d.ts.map +1 -1
- package/dist/gc/gcDefinitions.js +26 -16
- package/dist/gc/gcDefinitions.js.map +1 -1
- package/dist/gc/gcHelpers.d.ts +18 -25
- package/dist/gc/gcHelpers.d.ts.map +1 -1
- package/dist/gc/gcHelpers.js +29 -45
- package/dist/gc/gcHelpers.js.map +1 -1
- package/dist/gc/gcTelemetry.d.ts.map +1 -1
- package/dist/gc/gcTelemetry.js +14 -3
- package/dist/gc/gcTelemetry.js.map +1 -1
- package/dist/gc/gcUnreferencedStateTracker.d.ts +11 -5
- package/dist/gc/gcUnreferencedStateTracker.d.ts.map +1 -1
- package/dist/gc/gcUnreferencedStateTracker.js +43 -19
- package/dist/gc/gcUnreferencedStateTracker.js.map +1 -1
- package/dist/gc/index.d.ts +1 -1
- package/dist/gc/index.d.ts.map +1 -1
- package/dist/gc/index.js +4 -4
- package/dist/gc/index.js.map +1 -1
- package/dist/index.d.ts +13 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -5
- package/dist/index.js.map +1 -1
- package/dist/messageTypes.d.ts +13 -5
- package/dist/messageTypes.d.ts.map +1 -1
- package/dist/messageTypes.js +5 -0
- package/dist/messageTypes.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/pendingStateManager.d.ts +1 -0
- package/dist/pendingStateManager.d.ts.map +1 -1
- package/dist/pendingStateManager.js +1 -0
- package/dist/pendingStateManager.js.map +1 -1
- package/dist/summary/orderedClientElection.d.ts +1 -1
- package/dist/summary/orderedClientElection.js.map +1 -1
- package/dist/summary/summarizerTypes.d.ts +28 -28
- package/dist/summary/summarizerTypes.js.map +1 -1
- package/dist/summary/summaryCollection.d.ts +3 -3
- package/dist/summary/summaryCollection.js.map +1 -1
- package/dist/summary/summaryFormat.d.ts +3 -3
- package/dist/summary/summaryFormat.js.map +1 -1
- package/lib/blobManager.d.ts +4 -4
- package/lib/blobManager.d.ts.map +1 -1
- package/lib/blobManager.js.map +1 -1
- package/lib/container-runtime-alpha.d.ts +1361 -132
- package/lib/container-runtime-beta.d.ts +40 -2
- package/lib/container-runtime-public.d.ts +40 -2
- package/lib/container-runtime-untrimmed.d.ts +106 -93
- package/lib/containerRuntime.d.ts +19 -17
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +46 -26
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStores.d.ts +10 -15
- package/lib/dataStores.d.ts.map +1 -1
- package/lib/dataStores.js +65 -38
- package/lib/dataStores.js.map +1 -1
- package/lib/gc/garbageCollection.d.ts +29 -10
- package/lib/gc/garbageCollection.d.ts.map +1 -1
- package/lib/gc/garbageCollection.js +151 -69
- package/lib/gc/garbageCollection.js.map +1 -1
- package/lib/gc/gcConfigs.d.ts.map +1 -1
- package/lib/gc/gcConfigs.js +37 -40
- package/lib/gc/gcConfigs.js.map +1 -1
- package/lib/gc/gcDefinitions.d.ts +97 -44
- package/lib/gc/gcDefinitions.d.ts.map +1 -1
- package/lib/gc/gcDefinitions.js +25 -15
- package/lib/gc/gcDefinitions.js.map +1 -1
- package/lib/gc/gcHelpers.d.ts +18 -25
- package/lib/gc/gcHelpers.d.ts.map +1 -1
- package/lib/gc/gcHelpers.js +27 -43
- package/lib/gc/gcHelpers.js.map +1 -1
- package/lib/gc/gcTelemetry.d.ts.map +1 -1
- package/lib/gc/gcTelemetry.js +14 -3
- package/lib/gc/gcTelemetry.js.map +1 -1
- package/lib/gc/gcUnreferencedStateTracker.d.ts +11 -5
- package/lib/gc/gcUnreferencedStateTracker.d.ts.map +1 -1
- package/lib/gc/gcUnreferencedStateTracker.js +43 -19
- package/lib/gc/gcUnreferencedStateTracker.js.map +1 -1
- package/lib/gc/index.d.ts +1 -1
- package/lib/gc/index.d.ts.map +1 -1
- package/lib/gc/index.js +1 -1
- package/lib/gc/index.js.map +1 -1
- package/lib/index.d.ts +13 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +15 -1
- package/lib/index.js.map +1 -1
- package/lib/messageTypes.d.ts +13 -5
- package/lib/messageTypes.d.ts.map +1 -1
- package/lib/messageTypes.js +5 -0
- package/lib/messageTypes.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/pendingStateManager.d.ts +1 -0
- package/lib/pendingStateManager.d.ts.map +1 -1
- package/lib/pendingStateManager.js +1 -0
- package/lib/pendingStateManager.js.map +1 -1
- package/lib/summary/orderedClientElection.d.ts +1 -1
- package/lib/summary/orderedClientElection.js.map +1 -1
- package/lib/summary/summarizerTypes.d.ts +28 -28
- package/lib/summary/summarizerTypes.js.map +1 -1
- package/lib/summary/summaryCollection.d.ts +3 -3
- package/lib/summary/summaryCollection.js.map +1 -1
- package/lib/summary/summaryFormat.d.ts +3 -3
- package/lib/summary/summaryFormat.js.map +1 -1
- package/package.json +18 -15
- package/src/blobManager.ts +5 -5
- package/src/containerRuntime.ts +66 -40
- package/src/dataStores.ts +118 -59
- package/src/gc/garbageCollection.md +14 -15
- package/src/gc/garbageCollection.ts +182 -75
- package/src/gc/gcConfigs.ts +50 -52
- package/src/gc/gcDefinitions.ts +112 -50
- package/src/gc/gcHelpers.ts +31 -52
- package/src/gc/gcTelemetry.ts +16 -4
- package/src/gc/gcUnreferencedStateTracker.ts +61 -22
- package/src/gc/index.ts +4 -3
- package/src/index.ts +17 -1
- package/src/messageTypes.ts +16 -2
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +1 -0
- package/src/summary/orderedClientElection.ts +1 -1
- package/src/summary/summarizerTypes.ts +28 -28
- package/src/summary/summaryCollection.ts +3 -3
- package/src/summary/summaryFormat.ts +3 -3
- package/dist/id-compressor/appendOnlySortedMap.d.ts +0 -124
- package/dist/id-compressor/appendOnlySortedMap.d.ts.map +0 -1
- package/dist/id-compressor/appendOnlySortedMap.js +0 -318
- package/dist/id-compressor/appendOnlySortedMap.js.map +0 -1
- package/dist/id-compressor/finalSpace.d.ts +0 -29
- package/dist/id-compressor/finalSpace.d.ts.map +0 -1
- package/dist/id-compressor/finalSpace.js +0 -62
- package/dist/id-compressor/finalSpace.js.map +0 -1
- package/dist/id-compressor/idCompressor.d.ts +0 -54
- package/dist/id-compressor/idCompressor.d.ts.map +0 -1
- package/dist/id-compressor/idCompressor.js +0 -495
- package/dist/id-compressor/idCompressor.js.map +0 -1
- package/dist/id-compressor/identifiers.d.ts +0 -32
- package/dist/id-compressor/identifiers.d.ts.map +0 -1
- package/dist/id-compressor/identifiers.js +0 -15
- package/dist/id-compressor/identifiers.js.map +0 -1
- package/dist/id-compressor/index.d.ts +0 -13
- package/dist/id-compressor/index.d.ts.map +0 -1
- package/dist/id-compressor/index.js +0 -32
- package/dist/id-compressor/index.js.map +0 -1
- package/dist/id-compressor/persistanceUtilities.d.ts +0 -22
- package/dist/id-compressor/persistanceUtilities.d.ts.map +0 -1
- package/dist/id-compressor/persistanceUtilities.js +0 -43
- package/dist/id-compressor/persistanceUtilities.js.map +0 -1
- package/dist/id-compressor/sessionSpaceNormalizer.d.ts +0 -46
- package/dist/id-compressor/sessionSpaceNormalizer.d.ts.map +0 -1
- package/dist/id-compressor/sessionSpaceNormalizer.js +0 -80
- package/dist/id-compressor/sessionSpaceNormalizer.js.map +0 -1
- package/dist/id-compressor/sessions.d.ts +0 -115
- package/dist/id-compressor/sessions.d.ts.map +0 -1
- package/dist/id-compressor/sessions.js +0 -305
- package/dist/id-compressor/sessions.js.map +0 -1
- package/dist/id-compressor/utilities.d.ts +0 -52
- package/dist/id-compressor/utilities.d.ts.map +0 -1
- package/dist/id-compressor/utilities.js +0 -169
- package/dist/id-compressor/utilities.js.map +0 -1
- package/lib/id-compressor/appendOnlySortedMap.d.ts +0 -124
- package/lib/id-compressor/appendOnlySortedMap.d.ts.map +0 -1
- package/lib/id-compressor/appendOnlySortedMap.js +0 -314
- package/lib/id-compressor/appendOnlySortedMap.js.map +0 -1
- package/lib/id-compressor/finalSpace.d.ts +0 -29
- package/lib/id-compressor/finalSpace.d.ts.map +0 -1
- package/lib/id-compressor/finalSpace.js +0 -58
- package/lib/id-compressor/finalSpace.js.map +0 -1
- package/lib/id-compressor/idCompressor.d.ts +0 -54
- package/lib/id-compressor/idCompressor.d.ts.map +0 -1
- package/lib/id-compressor/idCompressor.js +0 -491
- package/lib/id-compressor/idCompressor.js.map +0 -1
- package/lib/id-compressor/identifiers.d.ts +0 -32
- package/lib/id-compressor/identifiers.d.ts.map +0 -1
- package/lib/id-compressor/identifiers.js +0 -11
- package/lib/id-compressor/identifiers.js.map +0 -1
- package/lib/id-compressor/index.d.ts +0 -13
- package/lib/id-compressor/index.d.ts.map +0 -1
- package/lib/id-compressor/index.js +0 -13
- package/lib/id-compressor/index.js.map +0 -1
- package/lib/id-compressor/persistanceUtilities.d.ts +0 -22
- package/lib/id-compressor/persistanceUtilities.d.ts.map +0 -1
- package/lib/id-compressor/persistanceUtilities.js +0 -34
- package/lib/id-compressor/persistanceUtilities.js.map +0 -1
- package/lib/id-compressor/sessionSpaceNormalizer.d.ts +0 -46
- package/lib/id-compressor/sessionSpaceNormalizer.d.ts.map +0 -1
- package/lib/id-compressor/sessionSpaceNormalizer.js +0 -76
- package/lib/id-compressor/sessionSpaceNormalizer.js.map +0 -1
- package/lib/id-compressor/sessions.d.ts +0 -115
- package/lib/id-compressor/sessions.d.ts.map +0 -1
- package/lib/id-compressor/sessions.js +0 -290
- package/lib/id-compressor/sessions.js.map +0 -1
- package/lib/id-compressor/utilities.d.ts +0 -52
- package/lib/id-compressor/utilities.d.ts.map +0 -1
- package/lib/id-compressor/utilities.js +0 -151
- package/lib/id-compressor/utilities.js.map +0 -1
- package/src/id-compressor/README.md +0 -69
- package/src/id-compressor/appendOnlySortedMap.ts +0 -366
- package/src/id-compressor/finalSpace.ts +0 -67
- package/src/id-compressor/idCompressor.ts +0 -630
- package/src/id-compressor/identifiers.ts +0 -42
- package/src/id-compressor/index.ts +0 -26
- package/src/id-compressor/persistanceUtilities.ts +0 -58
- package/src/id-compressor/sessionSpaceNormalizer.ts +0 -83
- package/src/id-compressor/sessions.ts +0 -405
- package/src/id-compressor/utilities.ts +0 -190
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sessions.js","sourceRoot":"","sources":["../../src/id-compressor/sessions.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport BTree from \"sorted-btree\";\nimport { SessionId, StableId } from \"@fluidframework/runtime-definitions\";\nimport { assert } from \"@fluidframework/core-utils\";\nimport {\n\tcompareBigints,\n\tlocalIdFromGenCount,\n\tgenCountFromLocalId,\n\tnumericUuidFromStableId,\n\tstableIdFromNumericUuid,\n\tsubtractNumericUuids,\n\toffsetNumericUuid,\n} from \"./utilities\";\nimport { FinalCompressedId, LocalCompressedId, NumericUuid } from \"./identifiers\";\n\n/**\n * A collection of all sessions known to the compressor (i.e. all finalized/acked allocated UUIDs and their corresponding local and final forms).\n * This collection of all sessions comprises a distributed document's IDs.\n */\nexport class Sessions {\n\t// A range-queryable store of all sessions. A btree is used as it solves the predecessor problem for any given UUID, allowing\n\t// us to quickly find the session that may have produced it.\n\tprivate readonly uuidSpace = new BTree<NumericUuid, Session>(undefined, compareBigints);\n\t// A fast lookup table from session ID to the session object, used to avoid accessing the slower btree\n\tprivate readonly sessionCache = new Map<SessionId, Session>();\n\n\tpublic constructor(sessions?: [sessionBase: NumericUuid, session: Session][]) {\n\t\tif (sessions !== undefined) {\n\t\t\t// bulk load path\n\t\t\tfor (const [numeric, session] of sessions) {\n\t\t\t\tthis.sessionCache.set(stableIdFromNumericUuid(numeric) as SessionId, session);\n\t\t\t}\n\t\t\tthis.uuidSpace = new BTree(sessions, compareBigints);\n\t\t\tif (\n\t\t\t\tthis.sessionCache.size !== sessions.length ||\n\t\t\t\tsessions.length !== this.uuidSpace.size\n\t\t\t) {\n\t\t\t\tthrow new Error(\"Cannot resume existing session.\");\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic sessions(): IterableIterator<Session> {\n\t\treturn this.sessionCache.values();\n\t}\n\n\tpublic getOrCreate(sessionId: SessionId): Session {\n\t\tconst existing = this.sessionCache.get(sessionId);\n\t\tif (existing !== undefined) {\n\t\t\treturn existing;\n\t\t}\n\t\tconst session = new Session(sessionId);\n\t\tassert(\n\t\t\tthis.uuidSpace.set(session.sessionUuid, session),\n\t\t\t0x760 /* Duplicate session in map. */,\n\t\t);\n\t\tthis.sessionCache.set(sessionId, session);\n\t\treturn session;\n\t}\n\n\tpublic get(sessionId: SessionId): Session | undefined {\n\t\treturn this.sessionCache.get(sessionId);\n\t}\n\n\tpublic getContainingCluster(\n\t\tquery: StableId,\n\t): [cluster: IdCluster, alignedLocal: LocalCompressedId] | undefined {\n\t\tconst numericStable = numericUuidFromStableId(query);\n\t\tconst possibleMatch = this.uuidSpace.getPairOrNextLower(numericStable);\n\t\tif (possibleMatch === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst [_, session] = possibleMatch;\n\t\tconst numericDelta = subtractNumericUuids(numericStable, session.sessionUuid);\n\t\tif (numericDelta > Number.MAX_SAFE_INTEGER) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst alignedLocal = localIdFromGenCount(Number(numericDelta) + 1);\n\t\tconst containingCluster = session.getClusterByLocal(alignedLocal, true);\n\t\tif (containingCluster === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn [containingCluster, alignedLocal];\n\t}\n\n\tpublic clusterCollides(cluster: IdCluster): boolean {\n\t\tconst { session: owningSession, baseLocalId, capacity } = cluster;\n\t\tconst clusterBaseNumeric = offsetNumericUuid(\n\t\t\towningSession.sessionUuid,\n\t\t\tgenCountFromLocalId(baseLocalId) - 1,\n\t\t);\n\t\tconst clusterMaxNumeric = offsetNumericUuid(clusterBaseNumeric, capacity - 1);\n\t\tlet closestMatch: [NumericUuid, Session] | undefined =\n\t\t\tthis.uuidSpace.getPairOrNextLower(clusterMaxNumeric);\n\t\t// Find the first session that is not the owner of this new cluster.\n\t\t// Once we have that, check to see if its cluster chain overlaps with the new cluster.\n\t\t// Consider the following diagram of UUID space:\n\t\t// Cluster chain A: |----------------------|\n\t\t// Cluster chain B: |----------|\n\t\t// Cluster chain C: |-------|\n\t\t// While it is true that when adding a cluster to chain C, we would find\n\t\t// the next lower session (which is B) and erroneously determine we do not collide\n\t\t// with any other session, but this situation is impossible to get into as B would\n\t\t// have detected that it collided with A (or the other way around, depending on ordering).\n\t\twhile (closestMatch !== undefined && closestMatch[1] === owningSession) {\n\t\t\tclosestMatch = this.uuidSpace.nextLowerPair(closestMatch[0]);\n\t\t}\n\t\tif (closestMatch === undefined) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst [_, session] = closestMatch;\n\t\tassert(session !== owningSession, 0x761 /* Failed to attempt to detect collisions. */);\n\t\tconst lastCluster = session.getLastCluster();\n\t\tif (lastCluster === undefined) {\n\t\t\t// If the closest session is empty (the local session), then it is guaranteed (probabilistically) that there are no\n\t\t\t// non-empty sessions that have a cluster chain that starts prior to the empty session and collides with the cluster\n\t\t\t// we are checking, so we can return false.\n\t\t\treturn false;\n\t\t}\n\t\tconst lastAllocatedNumeric = offsetNumericUuid(\n\t\t\tsession.sessionUuid,\n\t\t\tgenCountFromLocalId(lastAllocatedLocal(lastCluster)) - 1,\n\t\t);\n\t\treturn lastAllocatedNumeric >= clusterBaseNumeric;\n\t}\n\n\tpublic equals(other: Sessions, includeLocalState: boolean): boolean {\n\t\tconst checkIsSubset = (sessionsA: Sessions, sessionsB: Sessions) => {\n\t\t\tconst first = sessionsA.sessions().next();\n\t\t\tconst firstSessionThis = first.done ? undefined : first.value;\n\t\t\tfor (const [stableId, session] of sessionsA.sessionCache.entries()) {\n\t\t\t\tconst otherSession = sessionsB.sessionCache.get(stableId);\n\t\t\t\tif (otherSession === undefined) {\n\t\t\t\t\tif (!session.isEmpty() || includeLocalState) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tassert(\n\t\t\t\t\t\tsession === firstSessionThis,\n\t\t\t\t\t\t0x762 /* The only non-empty session must be the local session. */,\n\t\t\t\t\t);\n\t\t\t\t} else if (!session.equals(otherSession)) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t};\n\t\treturn checkIsSubset(this, other) && checkIsSubset(other, this);\n\t}\n}\n\n/**\n * The IDs created by a specific session, stored as a cluster chain to allow for fast conversions.\n */\nexport class Session {\n\t// All clusters created by this session, in creation order (thus sorted by base final and local ID).\n\tprivate readonly clusterChain: IdCluster[] = [];\n\t// The numeric form of the SessionId\n\tpublic readonly sessionUuid: NumericUuid;\n\n\tpublic constructor(sessionId: SessionId | NumericUuid) {\n\t\tthis.sessionUuid =\n\t\t\ttypeof sessionId === \"string\" ? numericUuidFromStableId(sessionId) : sessionId;\n\t}\n\n\t/**\n\t * Adds a new empty cluster to the cluster chain of this session.\n\t */\n\tpublic addNewCluster(\n\t\tbaseFinalId: FinalCompressedId,\n\t\tcapacity: number,\n\t\tcount: number,\n\t): IdCluster {\n\t\tconst lastCluster = this.getLastCluster();\n\t\tconst newCluster: IdCluster = {\n\t\t\tsession: this,\n\t\t\tbaseFinalId,\n\t\t\tbaseLocalId: (lastCluster === undefined\n\t\t\t\t? -1\n\t\t\t\t: lastAllocatedLocal(lastCluster) - 1) as LocalCompressedId,\n\t\t\tcapacity,\n\t\t\tcount,\n\t\t};\n\t\tthis.clusterChain.push(newCluster);\n\t\treturn newCluster;\n\t}\n\n\tpublic isEmpty(): boolean {\n\t\treturn this.clusterChain.length === 0;\n\t}\n\n\t/**\n\t * Returns the last cluster in this session's cluster chain, if any.\n\t */\n\tpublic getLastCluster(): IdCluster | undefined {\n\t\treturn this.clusterChain[this.clusterChain.length - 1];\n\t}\n\n\t/**\n\t * Converts the local ID from this session to a final ID, if possible.\n\t * @param includeAllocated - true if the conversion should succeed even if the local ID aligns with a part of the cluster that is allocated but not finalized.\n\t */\n\tpublic tryConvertToFinal(\n\t\tsearchLocal: LocalCompressedId,\n\t\tincludeAllocated: boolean,\n\t): FinalCompressedId | undefined {\n\t\tconst containingCluster = this.getClusterByLocal(searchLocal, includeAllocated);\n\t\tif (containingCluster === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn getAlignedFinal(containingCluster, searchLocal);\n\t}\n\n\t/**\n\t * Returns the cluster containing the supplied local ID, if possible.\n\t * @param includeAllocated - true if the conversion should succeed even if the local ID aligns with a part of the cluster that is allocated but not finalized.\n\t */\n\tpublic getClusterByLocal(\n\t\tlocalId: LocalCompressedId,\n\t\tincludeAllocated: boolean,\n\t): IdCluster | undefined {\n\t\tconst lastValidLocal: (cluster: IdCluster) => LocalCompressedId = includeAllocated\n\t\t\t? lastAllocatedLocal\n\t\t\t: lastFinalizedLocal;\n\t\tconst matchedCluster = Session.binarySearch(\n\t\t\tlocalId,\n\t\t\tthis.clusterChain,\n\t\t\t(local, cluster): number => {\n\t\t\t\tconst lastLocal = lastValidLocal(cluster);\n\t\t\t\tif (local < lastLocal) {\n\t\t\t\t\treturn 1;\n\t\t\t\t} else if (local > cluster.baseLocalId) {\n\t\t\t\t\treturn -1;\n\t\t\t\t} else {\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\t\t\t},\n\t\t);\n\t\treturn matchedCluster;\n\t}\n\n\t/**\n\t * Returns the cluster containing the supplied final ID, if possible.\n\t */\n\tpublic getClusterByAllocatedFinal(final: FinalCompressedId): IdCluster | undefined {\n\t\treturn Session.getContainingCluster(final, this.clusterChain);\n\t}\n\n\t/**\n\t * Returns the cluster from the supplied cluster chain containing the supplied final ID, if possible.\n\t * `clusterChain` must be sorted by final/local base ID.\n\t */\n\tpublic static getContainingCluster(\n\t\tfinalId: FinalCompressedId,\n\t\tclusterChain: readonly IdCluster[],\n\t): IdCluster | undefined {\n\t\treturn Session.binarySearch(finalId, clusterChain, (final, cluster) => {\n\t\t\tconst lastFinal = lastAllocatedFinal(cluster);\n\t\t\tif (final < cluster.baseFinalId) {\n\t\t\t\treturn -1;\n\t\t\t} else if (final > lastFinal) {\n\t\t\t\treturn 1;\n\t\t\t} else {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t});\n\t}\n\n\tstatic binarySearch<S, T>(\n\t\tsearch: S,\n\t\tarr: readonly T[],\n\t\tcomparator: (a: S, b: T) => number,\n\t): T | undefined {\n\t\tlet left = 0;\n\t\tlet right = arr.length - 1;\n\t\twhile (left <= right) {\n\t\t\tconst mid = Math.floor((left + right) / 2);\n\t\t\tconst c = comparator(search, arr[mid]);\n\t\t\tif (c === 0) {\n\t\t\t\treturn arr[mid]; // Found the target, return its index.\n\t\t\t} else if (c > 0) {\n\t\t\t\tleft = mid + 1; // Continue search on right half.\n\t\t\t} else {\n\t\t\t\tright = mid - 1; // Continue search on left half.\n\t\t\t}\n\t\t}\n\t\treturn undefined; // If we reach here, target is not in array.\n\t}\n\n\tpublic equals(other: Session): boolean {\n\t\tfor (let i = 0; i < this.clusterChain.length; i++) {\n\t\t\tif (!clustersEqual(this.clusterChain[i], other.clusterChain[i])) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn this.sessionUuid === other.sessionUuid;\n\t}\n}\n\n/**\n * A cluster of final (sequenced via consensus), sequentially allocated compressed IDs.\n * A final ID in a cluster decompresses to a sequentially allocated UUID that is the result of adding its offset within\n * the cluster to base UUID for the session that created it.\n */\nexport interface IdCluster {\n\t/**\n\t * The session that created this cluster.\n\t */\n\treadonly session: Session;\n\n\t/**\n\t * The first final ID in the cluster.\n\t */\n\treadonly baseFinalId: FinalCompressedId;\n\n\t/**\n\t * The local ID aligned with `baseFinalId`.\n\t */\n\treadonly baseLocalId: LocalCompressedId;\n\n\t/**\n\t * The total number of final IDs reserved for allocation in the cluster.\n\t * Clusters are reserved in blocks as a performance optimization.\n\t */\n\tcapacity: number;\n\n\t/**\n\t * The number of final IDs currently allocated in the cluster.\n\t */\n\tcount: number;\n}\n\nexport function clustersEqual(a: IdCluster, b: IdCluster): boolean {\n\treturn (\n\t\ta.session.sessionUuid === b.session.sessionUuid &&\n\t\ta.baseFinalId === b.baseFinalId &&\n\t\ta.baseLocalId === b.baseLocalId &&\n\t\ta.capacity === b.capacity &&\n\t\ta.count === b.count\n\t);\n}\n\n/**\n * Returns the final ID that is aligned with the supplied local ID within a cluster.\n * Includes allocated IDs.\n */\nexport function getAlignedFinal(\n\tcluster: IdCluster,\n\tlocalWithin: LocalCompressedId,\n): FinalCompressedId | undefined {\n\tconst clusterOffset =\n\t\tgenCountFromLocalId(localWithin) - genCountFromLocalId(cluster.baseLocalId);\n\tif (clusterOffset < cluster.capacity) {\n\t\treturn ((cluster.baseFinalId as number) + clusterOffset) as FinalCompressedId;\n\t}\n\treturn undefined;\n}\n\n/**\n * Returns the local ID that is aligned with the supplied final ID within a cluster.\n * Fails if the supplied ID does not fall within the cluster bounds.\n */\nexport function getAlignedLocal(\n\tcluster: IdCluster,\n\tfinalWithin: FinalCompressedId,\n): LocalCompressedId {\n\tassert(\n\t\tfinalWithin >= cluster.baseFinalId && finalWithin <= lastAllocatedFinal(cluster),\n\t\t0x763 /* Supplied ID is not within the cluster. */,\n\t);\n\tconst finalDelta = finalWithin - cluster.baseFinalId;\n\treturn (cluster.baseLocalId - finalDelta) as LocalCompressedId;\n}\n\n/**\n * Returns the last allocated final ID (i.e. any ID between base final and base final + capacity) within a cluster\n */\nexport function lastAllocatedFinal(cluster: IdCluster): FinalCompressedId {\n\treturn ((cluster.baseFinalId as number) + (cluster.capacity - 1)) as FinalCompressedId;\n}\n\n/**\n * Returns the last allocated final ID (i.e. any ID between base final and base final + count) within a cluster\n */\nexport function lastFinalizedFinal(cluster: IdCluster): FinalCompressedId {\n\treturn ((cluster.baseFinalId as number) + (cluster.count - 1)) as FinalCompressedId;\n}\n\n/**\n * Returns the last allocated local ID (i.e. any ID between base local and base local + capacity) within a cluster\n */\nexport function lastAllocatedLocal(cluster: IdCluster): LocalCompressedId {\n\treturn ((cluster.baseLocalId as number) - (cluster.capacity - 1)) as LocalCompressedId;\n}\n\n/**\n * Returns the last allocated local ID (i.e. any ID between base local and base local + count) within a cluster\n */\nexport function lastFinalizedLocal(cluster: IdCluster): LocalCompressedId {\n\treturn ((cluster.baseLocalId as number) - (cluster.count - 1)) as LocalCompressedId;\n}\n"]}
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
-
* Licensed under the MIT License.
|
|
4
|
-
*/
|
|
5
|
-
import { SessionId, StableId } from "@fluidframework/runtime-definitions";
|
|
6
|
-
import { LocalCompressedId, NumericUuid } from "./identifiers";
|
|
7
|
-
/**
|
|
8
|
-
* Generate a random session ID
|
|
9
|
-
*/
|
|
10
|
-
export declare function createSessionId(): SessionId;
|
|
11
|
-
/**
|
|
12
|
-
* Asserts that the given string is a stable ID.
|
|
13
|
-
* @internal
|
|
14
|
-
*/
|
|
15
|
-
export declare function assertIsStableId(stableId: string): StableId;
|
|
16
|
-
/**
|
|
17
|
-
* Asserts that the given string is a stable ID.
|
|
18
|
-
*/
|
|
19
|
-
export declare function assertIsSessionId(stableId: string): SessionId;
|
|
20
|
-
/**
|
|
21
|
-
* Generate a random stable ID
|
|
22
|
-
* @internal
|
|
23
|
-
*/
|
|
24
|
-
export declare function generateStableId(): StableId;
|
|
25
|
-
/**
|
|
26
|
-
* Returns true iff the given string is a valid Version 4, variant 2 UUID
|
|
27
|
-
* 'xxxxxxxx-xxxx-4xxx-vxxx-xxxxxxxxxxxx'
|
|
28
|
-
* @internal
|
|
29
|
-
*/
|
|
30
|
-
export declare function isStableId(str: string): str is StableId;
|
|
31
|
-
/**
|
|
32
|
-
* A numeric comparator used for sorting in ascending order.
|
|
33
|
-
*
|
|
34
|
-
* Handles +/-0 like Map: -0 is equal to +0.
|
|
35
|
-
*/
|
|
36
|
-
export declare function compareFiniteNumbers<T extends number>(a: T, b: T): number;
|
|
37
|
-
/**
|
|
38
|
-
* Compares strings lexically to form a strict partial ordering.
|
|
39
|
-
*/
|
|
40
|
-
export declare function compareStrings<T extends string>(a: T, b: T): number;
|
|
41
|
-
/**
|
|
42
|
-
* Compares bigints to form a strict partial ordering.
|
|
43
|
-
*/
|
|
44
|
-
export declare function compareBigints<T extends bigint>(a: T, b: T): number;
|
|
45
|
-
export declare function genCountFromLocalId(localId: LocalCompressedId): number;
|
|
46
|
-
export declare function localIdFromGenCount(genCount: number): LocalCompressedId;
|
|
47
|
-
export declare function numericUuidFromStableId(stableId: StableId): NumericUuid;
|
|
48
|
-
export declare function stableIdFromNumericUuid(numericUuid: NumericUuid): StableId;
|
|
49
|
-
export declare function offsetNumericUuid(numericUuid: NumericUuid, offset: number): NumericUuid;
|
|
50
|
-
export declare function subtractNumericUuids(a: NumericUuid, b: NumericUuid): NumericUuid;
|
|
51
|
-
export declare function addNumericUuids(a: NumericUuid, b: NumericUuid): NumericUuid;
|
|
52
|
-
//# sourceMappingURL=utilities.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"utilities.d.ts","sourceRoot":"","sources":["../../src/id-compressor/utilities.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,qCAAqC,CAAC;AAE1E,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAmB/D;;GAEG;AACH,wBAAgB,eAAe,IAAI,SAAS,CAE3C;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAG3D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAG7D;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,QAAQ,CAE3C;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,IAAI,QAAQ,CAuCvD;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,MAAM,CAEzE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,MAAM,CAEnE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,MAAM,CAEnE;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,iBAAiB,GAAG,MAAM,CAEtE;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,iBAAiB,CAEvE;AAeD,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,QAAQ,GAAG,WAAW,CAWvE;AAED,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,WAAW,GAAG,QAAQ,CAY1E;AAED,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,GAAG,WAAW,CAGvF;AAED,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,WAAW,GAAG,WAAW,CAEhF;AAED,wBAAgB,eAAe,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,WAAW,GAAG,WAAW,CAG3E"}
|
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
-
* Licensed under the MIT License.
|
|
4
|
-
*/
|
|
5
|
-
/* eslint-disable no-bitwise */
|
|
6
|
-
import { assert } from "@fluidframework/core-utils";
|
|
7
|
-
import { v4 } from "uuid";
|
|
8
|
-
const hexadecimalCharCodes = Array.from("09afAF").map((c) => c.charCodeAt(0));
|
|
9
|
-
function isHexadecimalCharacter(charCode) {
|
|
10
|
-
return ((charCode >= hexadecimalCharCodes[0] && charCode <= hexadecimalCharCodes[1]) ||
|
|
11
|
-
(charCode >= hexadecimalCharCodes[2] && charCode <= hexadecimalCharCodes[3]) ||
|
|
12
|
-
(charCode >= hexadecimalCharCodes[4] && charCode <= hexadecimalCharCodes[5]));
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* Generate a random session ID
|
|
16
|
-
*/
|
|
17
|
-
export function createSessionId() {
|
|
18
|
-
return assertIsStableId(v4());
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Asserts that the given string is a stable ID.
|
|
22
|
-
* @internal
|
|
23
|
-
*/
|
|
24
|
-
export function assertIsStableId(stableId) {
|
|
25
|
-
assert(isStableId(stableId), 0x4a3 /* Expected a StableId */);
|
|
26
|
-
return stableId;
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Asserts that the given string is a stable ID.
|
|
30
|
-
*/
|
|
31
|
-
export function assertIsSessionId(stableId) {
|
|
32
|
-
assertIsStableId(stableId);
|
|
33
|
-
return stableId;
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* Generate a random stable ID
|
|
37
|
-
* @internal
|
|
38
|
-
*/
|
|
39
|
-
export function generateStableId() {
|
|
40
|
-
return assertIsStableId(v4());
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* Returns true iff the given string is a valid Version 4, variant 2 UUID
|
|
44
|
-
* 'xxxxxxxx-xxxx-4xxx-vxxx-xxxxxxxxxxxx'
|
|
45
|
-
* @internal
|
|
46
|
-
*/
|
|
47
|
-
export function isStableId(str) {
|
|
48
|
-
if (str.length !== 36) {
|
|
49
|
-
return false;
|
|
50
|
-
}
|
|
51
|
-
for (let i = 0; i < str.length; i++) {
|
|
52
|
-
switch (i) {
|
|
53
|
-
case 8:
|
|
54
|
-
case 13:
|
|
55
|
-
case 18:
|
|
56
|
-
case 23:
|
|
57
|
-
if (str.charAt(i) !== "-") {
|
|
58
|
-
return false;
|
|
59
|
-
}
|
|
60
|
-
break;
|
|
61
|
-
case 14:
|
|
62
|
-
if (str.charAt(i) !== "4") {
|
|
63
|
-
return false;
|
|
64
|
-
}
|
|
65
|
-
break;
|
|
66
|
-
case 19: {
|
|
67
|
-
const char = str.charAt(i);
|
|
68
|
-
if (char !== "8" && char !== "9" && char !== "a" && char !== "b") {
|
|
69
|
-
return false;
|
|
70
|
-
}
|
|
71
|
-
break;
|
|
72
|
-
}
|
|
73
|
-
default:
|
|
74
|
-
if (!isHexadecimalCharacter(str.charCodeAt(i))) {
|
|
75
|
-
return false;
|
|
76
|
-
}
|
|
77
|
-
break;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
return true;
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* A numeric comparator used for sorting in ascending order.
|
|
84
|
-
*
|
|
85
|
-
* Handles +/-0 like Map: -0 is equal to +0.
|
|
86
|
-
*/
|
|
87
|
-
export function compareFiniteNumbers(a, b) {
|
|
88
|
-
return a - b;
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Compares strings lexically to form a strict partial ordering.
|
|
92
|
-
*/
|
|
93
|
-
export function compareStrings(a, b) {
|
|
94
|
-
return a > b ? 1 : a === b ? 0 : -1;
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* Compares bigints to form a strict partial ordering.
|
|
98
|
-
*/
|
|
99
|
-
export function compareBigints(a, b) {
|
|
100
|
-
return a > b ? 1 : a === b ? 0 : -1;
|
|
101
|
-
}
|
|
102
|
-
export function genCountFromLocalId(localId) {
|
|
103
|
-
return -localId;
|
|
104
|
-
}
|
|
105
|
-
export function localIdFromGenCount(genCount) {
|
|
106
|
-
return -genCount;
|
|
107
|
-
}
|
|
108
|
-
// xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
|
|
109
|
-
const versionMask = 0x4n << (19n * 4n); // Version 4
|
|
110
|
-
const variantMask = 0x8n << (15n * 4n); // Variant RFC4122 (1 0 x x)
|
|
111
|
-
const upperMask = 0xffffffffffffn << (20n * 4n);
|
|
112
|
-
// Upper mask when version/variant bits are removed
|
|
113
|
-
const strippedUpperMask = upperMask >> 6n;
|
|
114
|
-
const middieBittiesMask = 0xfffn << (16n * 4n);
|
|
115
|
-
// Middie mask when version/variant bits are removed
|
|
116
|
-
const strippedMiddieBittiesMask = middieBittiesMask >> 2n;
|
|
117
|
-
// Note: leading character should be 3 to mask at 0011
|
|
118
|
-
// The more-significant half of the N nibble is used to denote the variant (10xx)
|
|
119
|
-
const lowerMask = 0x3fffffffffffffffn;
|
|
120
|
-
export function numericUuidFromStableId(stableId) {
|
|
121
|
-
const uuidU128 = BigInt(`0x${stableId.replace(/-/g, "")}`);
|
|
122
|
-
const upperMasked = uuidU128 & upperMask;
|
|
123
|
-
const middieBittiesMasked = uuidU128 & middieBittiesMask;
|
|
124
|
-
const lowerMasked = uuidU128 & lowerMask;
|
|
125
|
-
const upperMaskedPlaced = upperMasked >> 6n;
|
|
126
|
-
const middieBittiesMaskedPlaced = middieBittiesMasked >> 2n;
|
|
127
|
-
const id = upperMaskedPlaced | middieBittiesMaskedPlaced | lowerMasked;
|
|
128
|
-
return id;
|
|
129
|
-
}
|
|
130
|
-
export function stableIdFromNumericUuid(numericUuid) {
|
|
131
|
-
// bitwise reverse transform
|
|
132
|
-
const upperMasked = (numericUuid & strippedUpperMask) << 6n;
|
|
133
|
-
const middieBittiesMasked = (numericUuid & strippedMiddieBittiesMask) << 2n;
|
|
134
|
-
const lowerMasked = numericUuid & lowerMask;
|
|
135
|
-
const uuidU128 = upperMasked | versionMask | middieBittiesMasked | variantMask | lowerMasked;
|
|
136
|
-
// Pad to 32 characters, inserting leading zeroes if needed
|
|
137
|
-
const uuidString = uuidU128.toString(16).padStart(32, "0");
|
|
138
|
-
return `${uuidString.substring(0, 8)}-${uuidString.substring(8, 12)}-${uuidString.substring(12, 16)}-${uuidString.substring(16, 20)}-${uuidString.substring(20, 32)}`;
|
|
139
|
-
}
|
|
140
|
-
export function offsetNumericUuid(numericUuid, offset) {
|
|
141
|
-
// eslint-disable-next-line @typescript-eslint/restrict-plus-operands
|
|
142
|
-
return (numericUuid + BigInt(offset));
|
|
143
|
-
}
|
|
144
|
-
export function subtractNumericUuids(a, b) {
|
|
145
|
-
return (a - b);
|
|
146
|
-
}
|
|
147
|
-
export function addNumericUuids(a, b) {
|
|
148
|
-
// eslint-disable-next-line @typescript-eslint/restrict-plus-operands
|
|
149
|
-
return (a + b);
|
|
150
|
-
}
|
|
151
|
-
//# sourceMappingURL=utilities.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"utilities.js","sourceRoot":"","sources":["../../src/id-compressor/utilities.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/* eslint-disable no-bitwise */\nimport { assert } from \"@fluidframework/core-utils\";\nimport { SessionId, StableId } from \"@fluidframework/runtime-definitions\";\nimport { v4 } from \"uuid\";\nimport { LocalCompressedId, NumericUuid } from \"./identifiers\";\n\nconst hexadecimalCharCodes = Array.from(\"09afAF\").map((c) => c.charCodeAt(0)) as [\n\tzero: number,\n\tnine: number,\n\ta: number,\n\tf: number,\n\tA: number,\n\tF: number,\n];\n\nfunction isHexadecimalCharacter(charCode: number): boolean {\n\treturn (\n\t\t(charCode >= hexadecimalCharCodes[0] && charCode <= hexadecimalCharCodes[1]) ||\n\t\t(charCode >= hexadecimalCharCodes[2] && charCode <= hexadecimalCharCodes[3]) ||\n\t\t(charCode >= hexadecimalCharCodes[4] && charCode <= hexadecimalCharCodes[5])\n\t);\n}\n\n/**\n * Generate a random session ID\n */\nexport function createSessionId(): SessionId {\n\treturn assertIsStableId(v4()) as SessionId;\n}\n\n/**\n * Asserts that the given string is a stable ID.\n * @internal\n */\nexport function assertIsStableId(stableId: string): StableId {\n\tassert(isStableId(stableId), 0x4a3 /* Expected a StableId */);\n\treturn stableId;\n}\n\n/**\n * Asserts that the given string is a stable ID.\n */\nexport function assertIsSessionId(stableId: string): SessionId {\n\tassertIsStableId(stableId);\n\treturn stableId as SessionId;\n}\n\n/**\n * Generate a random stable ID\n * @internal\n */\nexport function generateStableId(): StableId {\n\treturn assertIsStableId(v4());\n}\n\n/**\n * Returns true iff the given string is a valid Version 4, variant 2 UUID\n * 'xxxxxxxx-xxxx-4xxx-vxxx-xxxxxxxxxxxx'\n * @internal\n */\nexport function isStableId(str: string): str is StableId {\n\tif (str.length !== 36) {\n\t\treturn false;\n\t}\n\n\tfor (let i = 0; i < str.length; i++) {\n\t\tswitch (i) {\n\t\t\tcase 8:\n\t\t\tcase 13:\n\t\t\tcase 18:\n\t\t\tcase 23:\n\t\t\t\tif (str.charAt(i) !== \"-\") {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase 14:\n\t\t\t\tif (str.charAt(i) !== \"4\") {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase 19: {\n\t\t\t\tconst char = str.charAt(i);\n\t\t\t\tif (char !== \"8\" && char !== \"9\" && char !== \"a\" && char !== \"b\") {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tdefault:\n\t\t\t\tif (!isHexadecimalCharacter(str.charCodeAt(i))) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn true;\n}\n\n/**\n * A numeric comparator used for sorting in ascending order.\n *\n * Handles +/-0 like Map: -0 is equal to +0.\n */\nexport function compareFiniteNumbers<T extends number>(a: T, b: T): number {\n\treturn a - b;\n}\n\n/**\n * Compares strings lexically to form a strict partial ordering.\n */\nexport function compareStrings<T extends string>(a: T, b: T): number {\n\treturn a > b ? 1 : a === b ? 0 : -1;\n}\n\n/**\n * Compares bigints to form a strict partial ordering.\n */\nexport function compareBigints<T extends bigint>(a: T, b: T): number {\n\treturn a > b ? 1 : a === b ? 0 : -1;\n}\n\nexport function genCountFromLocalId(localId: LocalCompressedId): number {\n\treturn -localId;\n}\n\nexport function localIdFromGenCount(genCount: number): LocalCompressedId {\n\treturn -genCount as LocalCompressedId;\n}\n\n// xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx\nconst versionMask = 0x4n << (19n * 4n); // Version 4\nconst variantMask = 0x8n << (15n * 4n); // Variant RFC4122 (1 0 x x)\nconst upperMask = 0xffffffffffffn << (20n * 4n);\n// Upper mask when version/variant bits are removed\nconst strippedUpperMask = upperMask >> 6n;\nconst middieBittiesMask = 0xfffn << (16n * 4n);\n// Middie mask when version/variant bits are removed\nconst strippedMiddieBittiesMask = middieBittiesMask >> 2n;\n// Note: leading character should be 3 to mask at 0011\n// The more-significant half of the N nibble is used to denote the variant (10xx)\nconst lowerMask = 0x3fffffffffffffffn;\n\nexport function numericUuidFromStableId(stableId: StableId): NumericUuid {\n\tconst uuidU128 = BigInt(`0x${stableId.replace(/-/g, \"\")}`);\n\tconst upperMasked = uuidU128 & upperMask;\n\tconst middieBittiesMasked = uuidU128 & middieBittiesMask;\n\tconst lowerMasked = uuidU128 & lowerMask;\n\n\tconst upperMaskedPlaced = upperMasked >> 6n;\n\tconst middieBittiesMaskedPlaced = middieBittiesMasked >> 2n;\n\n\tconst id = upperMaskedPlaced | middieBittiesMaskedPlaced | lowerMasked;\n\treturn id as NumericUuid;\n}\n\nexport function stableIdFromNumericUuid(numericUuid: NumericUuid): StableId {\n\t// bitwise reverse transform\n\tconst upperMasked = (numericUuid & strippedUpperMask) << 6n;\n\tconst middieBittiesMasked = (numericUuid & strippedMiddieBittiesMask) << 2n;\n\tconst lowerMasked = numericUuid & lowerMask;\n\tconst uuidU128 = upperMasked | versionMask | middieBittiesMasked | variantMask | lowerMasked;\n\t// Pad to 32 characters, inserting leading zeroes if needed\n\tconst uuidString = uuidU128.toString(16).padStart(32, \"0\");\n\treturn `${uuidString.substring(0, 8)}-${uuidString.substring(8, 12)}-${uuidString.substring(\n\t\t12,\n\t\t16,\n\t)}-${uuidString.substring(16, 20)}-${uuidString.substring(20, 32)}` as StableId;\n}\n\nexport function offsetNumericUuid(numericUuid: NumericUuid, offset: number): NumericUuid {\n\t// eslint-disable-next-line @typescript-eslint/restrict-plus-operands\n\treturn (numericUuid + BigInt(offset)) as NumericUuid;\n}\n\nexport function subtractNumericUuids(a: NumericUuid, b: NumericUuid): NumericUuid {\n\treturn (a - b) as NumericUuid;\n}\n\nexport function addNumericUuids(a: NumericUuid, b: NumericUuid): NumericUuid {\n\t// eslint-disable-next-line @typescript-eslint/restrict-plus-operands\n\treturn (a + b) as NumericUuid;\n}\n"]}
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
# **Distributed ID Allocator**
|
|
2
|
-
|
|
3
|
-
A library which generates small number representations of arbitrary non-colliding Version 4 UUIDs ("stable IDs") across multiple sessions in a network. This scheme enables a distributed application to utilize the global uniqueness guarantees of UUIDs while maintaining the performance advantages of small integers.
|
|
4
|
-
|
|
5
|
-
## **Overview**
|
|
6
|
-
|
|
7
|
-
The distributed ID allocation scheme allows clients to use, store, and reference small numbers that map to UUIDs rather than the UUIDs themselves. The primary benefits are improved memory efficiency and reduced storage size, as well as improved runtime performance when used as keys in collections.
|
|
8
|
-
|
|
9
|
-
The scheme requires a total order for ID allocation, so the allocator is designed to work within a service that provides centralized total order broadcast.
|
|
10
|
-
|
|
11
|
-
## **Sessions**
|
|
12
|
-
|
|
13
|
-
A session can be thought of as a unique identifier for a single allocator. Even if an allocator is taken offline, serialized to disk, and rehydrated back, it's considered the same session if it has the same session ID.
|
|
14
|
-
|
|
15
|
-
## **Document**
|
|
16
|
-
|
|
17
|
-
The set of IDs generated by all Sessions contributing to the same distributed collection (e.g. an individual collaborative document). Uniqueness of allocated IDs is limited to the document context (unless in their UUID form), and thus IDs in their compressed form are not portable between documents.
|
|
18
|
-
|
|
19
|
-
## **Generation API**
|
|
20
|
-
|
|
21
|
-
New IDs are generated via a synchronous API on the allocator. The API returns a small number representation of the UUID with the following guarantees:
|
|
22
|
-
|
|
23
|
-
- The ID can be synchronously converted into a full UUID at any time. This is required if global uniqueness (across documents) is needed.
|
|
24
|
-
- Prior to the service being notified of the ID's creation, it is unique within the scope of the session (i.e. the new ID will not collide with other IDs from the same allocator, but it can collide with IDs from a different allocator in the same network).
|
|
25
|
-
- After the service has been notified of the ID's creation and has determined a total ordering between all clients creating IDs, the ID will have a "final" form that is a small number representation that is unique across the [document](#document).
|
|
26
|
-
|
|
27
|
-
## **ID Spaces**
|
|
28
|
-
|
|
29
|
-
The allocation scheme separates the small-number IDs into two "spaces":
|
|
30
|
-
|
|
31
|
-
1. Session space: IDs are unique within the session scope, but are not guaranteed to be [document](#document) unique without the accompanying context of their session ID.
|
|
32
|
-
2. Op space: IDs are in their most final form, as unique as possible within the entire system. IDs that have been ordered by the central service ("finalized") are represented in their final form, while any other IDs that have not yet been finalized are left in their "session space" form.
|
|
33
|
-
|
|
34
|
-
Each of these spaces is represented by a discrete type. This allows for the direct encoding of an ID's uniqueness guarantees without contextual ambiguity. An ID can be "normalized" from one space to the other with a sychronous call.
|
|
35
|
-
|
|
36
|
-
## **Usage Guidelines**
|
|
37
|
-
|
|
38
|
-
When delivering Allocated IDs to application authors for use in place of V4 UUIDs, follow these guidelines:
|
|
39
|
-
|
|
40
|
-
- Expose only session space IDs to application authors. This means that application developers don't need to manage multiple ID spaces or worry about converting IDs between session space and op space. This simplifies the data management process and reduces the chances of errors or inconsistencies.
|
|
41
|
-
|
|
42
|
-
- **Note:** Session space IDs are only unique within the originating session (for most applications this will mean within each individual client's app instance, as it is rare to hold handles to more than one allocator). This constrains usage to scopes where IDs are unique; for instance, application developers should never persist these IDs and should instead be directed to convert them to stable IDs first.
|
|
43
|
-
|
|
44
|
-
- Use op space IDs for serialized forms, such as sending information over the wire or storing it in a file. Op space IDs are always generated in their _final_ form when possible, which imparts a performance benefit by reducing normalization work when a client receives a network operation or rehydrates an allocator.
|
|
45
|
-
- When serializing op space IDs, annotate the entire context (e.g., file or network operation) with the session ID. This is necessary because not all IDs in op space are in their final form. Any non-finalized IDs will still be in their session space form, unique only within that specific session. Annotating the entire context with the session ID ensures that recipients of the serialized data can correctly interpret and process the non-finalized IDs.
|
|
46
|
-
|
|
47
|
-
## **Efficiency Properties**
|
|
48
|
-
|
|
49
|
-
### **UUID Generation**
|
|
50
|
-
|
|
51
|
-
The allocator generates UUIDs in non-random ways to reduce entropy, optimizing storage of data. A session begins with a random UUID, and subsequent IDs are allocated sequentially. UUIDs generated with this strategy are less likely to collide than fully random UUIDs, and this fact can be leveraged to compact the on-disk and in-memory representations of the allocator.
|
|
52
|
-
|
|
53
|
-
UUID generation is O(1).
|
|
54
|
-
|
|
55
|
-
### **Decompression/recompression**
|
|
56
|
-
|
|
57
|
-
Converting an allocated ID into its UUID form (decompression) and the reverse (recompression) are both O(log<sub>n</sub>) in the number of IDs created by the originating session.
|
|
58
|
-
|
|
59
|
-
### **Clustering**
|
|
60
|
-
|
|
61
|
-
The sequential allocation approach allows the system to implement a clustering scheme.
|
|
62
|
-
|
|
63
|
-
As allocators across the network create IDs, they reserve blocks of positive ID space (clusters) for that allocator. The positive integer space is sharded across different clients, and session space IDs are mapped into these clusters.
|
|
64
|
-
|
|
65
|
-
Clusters are efficient to store, requiring only two integers: the base positive integer in the cluster and the count of reserved IDs in that cluster.
|
|
66
|
-
|
|
67
|
-
### **Normalization**
|
|
68
|
-
|
|
69
|
-
Normalization is O(log<sub>n</sub>) in the number of IDs created by the originating session, as it requires a simple binary search on the clusters owned by that session.
|