@itwin/core-bentley 4.0.0-dev.7 → 4.0.0-dev.70
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 +29 -12
- package/lib/cjs/AccessToken.d.ts +10 -10
- package/lib/cjs/AccessToken.d.ts.map +1 -1
- package/lib/cjs/AccessToken.js +9 -9
- package/lib/cjs/Assert.d.ts +25 -25
- package/lib/cjs/Assert.js +45 -45
- package/lib/cjs/Assert.js.map +1 -1
- package/lib/cjs/BeEvent.d.ts +81 -81
- package/lib/cjs/BeEvent.d.ts.map +1 -1
- package/lib/cjs/BeEvent.js +156 -156
- package/lib/cjs/BeSQLite.d.ts +172 -170
- package/lib/cjs/BeSQLite.d.ts.map +1 -1
- package/lib/cjs/BeSQLite.js +185 -183
- package/lib/cjs/BeSQLite.js.map +1 -1
- package/lib/cjs/BentleyError.d.ts +378 -378
- package/lib/cjs/BentleyError.d.ts.map +1 -1
- package/lib/cjs/BentleyError.js +703 -702
- package/lib/cjs/BentleyError.js.map +1 -1
- package/lib/cjs/BentleyLoggerCategory.d.ts +11 -11
- package/lib/cjs/BentleyLoggerCategory.js +19 -19
- package/lib/cjs/ByteStream.d.ts +110 -110
- package/lib/cjs/ByteStream.js +159 -159
- package/lib/cjs/ClassUtils.d.ts +14 -14
- package/lib/cjs/ClassUtils.js +27 -27
- package/lib/cjs/Compare.d.ts +47 -47
- package/lib/cjs/Compare.d.ts.map +1 -1
- package/lib/cjs/Compare.js +75 -75
- package/lib/cjs/CompressedId64Set.d.ts +134 -134
- package/lib/cjs/CompressedId64Set.d.ts.map +1 -1
- package/lib/cjs/CompressedId64Set.js +428 -428
- package/lib/cjs/CompressedId64Set.js.map +1 -1
- package/lib/cjs/Dictionary.d.ts +125 -125
- package/lib/cjs/Dictionary.js +203 -203
- package/lib/cjs/Disposable.d.ts +80 -80
- package/lib/cjs/Disposable.d.ts.map +1 -1
- package/lib/cjs/Disposable.js +120 -120
- package/lib/cjs/Id.d.ts +285 -285
- package/lib/cjs/Id.d.ts.map +1 -1
- package/lib/cjs/Id.js +643 -643
- package/lib/cjs/IndexMap.d.ts +65 -65
- package/lib/cjs/IndexMap.js +91 -91
- package/lib/cjs/JsonSchema.d.ts +77 -77
- package/lib/cjs/JsonSchema.d.ts.map +1 -1
- package/lib/cjs/JsonSchema.js +9 -9
- package/lib/cjs/JsonUtils.d.ts +78 -78
- package/lib/cjs/JsonUtils.js +151 -151
- package/lib/cjs/LRUMap.d.ts +129 -129
- package/lib/cjs/LRUMap.js +333 -333
- package/lib/cjs/LRUMap.js.map +1 -1
- package/lib/cjs/Logger.d.ts +143 -143
- package/lib/cjs/Logger.d.ts.map +1 -1
- package/lib/cjs/Logger.js +256 -258
- package/lib/cjs/Logger.js.map +1 -1
- package/lib/cjs/ObservableSet.d.ts +23 -23
- package/lib/cjs/ObservableSet.js +51 -51
- package/lib/cjs/OneAtATimeAction.d.ts +31 -31
- package/lib/cjs/OneAtATimeAction.js +94 -94
- package/lib/cjs/OneAtATimeAction.js.map +1 -1
- package/lib/cjs/OrderedId64Iterable.d.ts +74 -74
- package/lib/cjs/OrderedId64Iterable.d.ts.map +1 -1
- package/lib/cjs/OrderedId64Iterable.js +235 -235
- package/lib/cjs/OrderedSet.d.ts +40 -40
- package/lib/cjs/OrderedSet.js +64 -64
- package/lib/cjs/PriorityQueue.d.ts +70 -70
- package/lib/cjs/PriorityQueue.d.ts.map +1 -1
- package/lib/cjs/PriorityQueue.js +140 -140
- package/lib/cjs/ProcessDetector.d.ts +59 -59
- package/lib/cjs/ProcessDetector.js +71 -71
- package/lib/cjs/SortedArray.d.ts +236 -232
- package/lib/cjs/SortedArray.d.ts.map +1 -1
- package/lib/cjs/SortedArray.js +315 -303
- package/lib/cjs/SortedArray.js.map +1 -1
- package/lib/cjs/StatusCategory.d.ts +30 -30
- package/lib/cjs/StatusCategory.d.ts.map +1 -1
- package/lib/cjs/StatusCategory.js +460 -460
- package/lib/cjs/StatusCategory.js.map +1 -1
- package/lib/cjs/StringUtils.d.ts +22 -22
- package/lib/cjs/StringUtils.js +148 -148
- package/lib/cjs/Time.d.ts +122 -122
- package/lib/cjs/Time.js +152 -152
- package/lib/cjs/Time.js.map +1 -1
- package/lib/cjs/Tracing.d.ts +43 -40
- package/lib/cjs/Tracing.d.ts.map +1 -1
- package/lib/cjs/Tracing.js +134 -130
- package/lib/cjs/Tracing.js.map +1 -1
- package/lib/cjs/TupleKeyedMap.d.ts +36 -36
- package/lib/cjs/TupleKeyedMap.js +102 -102
- package/lib/cjs/TypedArrayBuilder.d.ts +155 -155
- package/lib/cjs/TypedArrayBuilder.d.ts.map +1 -1
- package/lib/cjs/TypedArrayBuilder.js +206 -208
- package/lib/cjs/TypedArrayBuilder.js.map +1 -1
- package/lib/cjs/UnexpectedErrors.d.ts +43 -43
- package/lib/cjs/UnexpectedErrors.d.ts.map +1 -1
- package/lib/cjs/UnexpectedErrors.js +68 -68
- package/lib/cjs/UnexpectedErrors.js.map +1 -1
- package/lib/cjs/UtilityTypes.d.ts +112 -96
- package/lib/cjs/UtilityTypes.d.ts.map +1 -1
- package/lib/cjs/UtilityTypes.js +40 -40
- package/lib/cjs/UtilityTypes.js.map +1 -1
- package/lib/cjs/YieldManager.d.ts +18 -18
- package/lib/cjs/YieldManager.js +34 -34
- package/lib/cjs/core-bentley.d.ts +74 -74
- package/lib/cjs/core-bentley.js +94 -90
- package/lib/cjs/core-bentley.js.map +1 -1
- package/lib/cjs/partitionArray.d.ts +21 -21
- package/lib/cjs/partitionArray.js +43 -43
- package/lib/esm/AccessToken.d.ts +10 -10
- package/lib/esm/AccessToken.d.ts.map +1 -1
- package/lib/esm/AccessToken.js +8 -8
- package/lib/esm/Assert.d.ts +25 -25
- package/lib/esm/Assert.js +41 -41
- package/lib/esm/Assert.js.map +1 -1
- package/lib/esm/BeEvent.d.ts +81 -81
- package/lib/esm/BeEvent.d.ts.map +1 -1
- package/lib/esm/BeEvent.js +150 -150
- package/lib/esm/BeSQLite.d.ts +172 -170
- package/lib/esm/BeSQLite.d.ts.map +1 -1
- package/lib/esm/BeSQLite.js +182 -180
- package/lib/esm/BeSQLite.js.map +1 -1
- package/lib/esm/BentleyError.d.ts +378 -378
- package/lib/esm/BentleyError.d.ts.map +1 -1
- package/lib/esm/BentleyError.js +699 -698
- package/lib/esm/BentleyError.js.map +1 -1
- package/lib/esm/BentleyLoggerCategory.d.ts +11 -11
- package/lib/esm/BentleyLoggerCategory.js +16 -16
- package/lib/esm/ByteStream.d.ts +110 -110
- package/lib/esm/ByteStream.js +155 -155
- package/lib/esm/ClassUtils.d.ts +14 -14
- package/lib/esm/ClassUtils.js +22 -22
- package/lib/esm/Compare.d.ts +47 -47
- package/lib/esm/Compare.d.ts.map +1 -1
- package/lib/esm/Compare.js +63 -63
- package/lib/esm/CompressedId64Set.d.ts +134 -134
- package/lib/esm/CompressedId64Set.d.ts.map +1 -1
- package/lib/esm/CompressedId64Set.js +423 -423
- package/lib/esm/CompressedId64Set.js.map +1 -1
- package/lib/esm/Dictionary.d.ts +125 -125
- package/lib/esm/Dictionary.js +199 -199
- package/lib/esm/Disposable.d.ts +80 -80
- package/lib/esm/Disposable.d.ts.map +1 -1
- package/lib/esm/Disposable.js +112 -112
- package/lib/esm/Id.d.ts +285 -285
- package/lib/esm/Id.d.ts.map +1 -1
- package/lib/esm/Id.js +639 -639
- package/lib/esm/IndexMap.d.ts +65 -65
- package/lib/esm/IndexMap.js +86 -86
- package/lib/esm/JsonSchema.d.ts +77 -77
- package/lib/esm/JsonSchema.d.ts.map +1 -1
- package/lib/esm/JsonSchema.js +8 -8
- package/lib/esm/JsonUtils.d.ts +78 -78
- package/lib/esm/JsonUtils.js +148 -148
- package/lib/esm/LRUMap.d.ts +129 -129
- package/lib/esm/LRUMap.js +326 -326
- package/lib/esm/LRUMap.js.map +1 -1
- package/lib/esm/Logger.d.ts +143 -143
- package/lib/esm/Logger.d.ts.map +1 -1
- package/lib/esm/Logger.js +253 -253
- package/lib/esm/Logger.js.map +1 -1
- package/lib/esm/ObservableSet.d.ts +23 -23
- package/lib/esm/ObservableSet.js +47 -47
- package/lib/esm/OneAtATimeAction.d.ts +31 -31
- package/lib/esm/OneAtATimeAction.js +89 -89
- package/lib/esm/OneAtATimeAction.js.map +1 -1
- package/lib/esm/OrderedId64Iterable.d.ts +74 -74
- package/lib/esm/OrderedId64Iterable.d.ts.map +1 -1
- package/lib/esm/OrderedId64Iterable.js +232 -232
- package/lib/esm/OrderedSet.d.ts +40 -40
- package/lib/esm/OrderedSet.js +59 -59
- package/lib/esm/PriorityQueue.d.ts +70 -70
- package/lib/esm/PriorityQueue.d.ts.map +1 -1
- package/lib/esm/PriorityQueue.js +136 -136
- package/lib/esm/ProcessDetector.d.ts +59 -59
- package/lib/esm/ProcessDetector.js +67 -67
- package/lib/esm/SortedArray.d.ts +236 -232
- package/lib/esm/SortedArray.d.ts.map +1 -1
- package/lib/esm/SortedArray.js +308 -296
- package/lib/esm/SortedArray.js.map +1 -1
- package/lib/esm/StatusCategory.d.ts +30 -30
- package/lib/esm/StatusCategory.d.ts.map +1 -1
- package/lib/esm/StatusCategory.js +455 -454
- package/lib/esm/StatusCategory.js.map +1 -1
- package/lib/esm/StringUtils.d.ts +22 -22
- package/lib/esm/StringUtils.js +142 -142
- package/lib/esm/Time.d.ts +122 -122
- package/lib/esm/Time.js +146 -146
- package/lib/esm/Time.js.map +1 -1
- package/lib/esm/Tracing.d.ts +43 -40
- package/lib/esm/Tracing.d.ts.map +1 -1
- package/lib/esm/Tracing.js +130 -126
- package/lib/esm/Tracing.js.map +1 -1
- package/lib/esm/TupleKeyedMap.d.ts +36 -36
- package/lib/esm/TupleKeyedMap.js +98 -98
- package/lib/esm/TypedArrayBuilder.d.ts +155 -155
- package/lib/esm/TypedArrayBuilder.d.ts.map +1 -1
- package/lib/esm/TypedArrayBuilder.js +198 -200
- package/lib/esm/TypedArrayBuilder.js.map +1 -1
- package/lib/esm/UnexpectedErrors.d.ts +43 -43
- package/lib/esm/UnexpectedErrors.d.ts.map +1 -1
- package/lib/esm/UnexpectedErrors.js +65 -64
- package/lib/esm/UnexpectedErrors.js.map +1 -1
- package/lib/esm/UtilityTypes.d.ts +112 -96
- package/lib/esm/UtilityTypes.d.ts.map +1 -1
- package/lib/esm/UtilityTypes.js +34 -34
- package/lib/esm/UtilityTypes.js.map +1 -1
- package/lib/esm/YieldManager.d.ts +18 -18
- package/lib/esm/YieldManager.js +30 -30
- package/lib/esm/core-bentley.d.ts +74 -74
- package/lib/esm/core-bentley.js +78 -78
- package/lib/esm/partitionArray.d.ts +21 -21
- package/lib/esm/partitionArray.js +39 -39
- package/package.json +8 -8
|
@@ -1,429 +1,429 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/*---------------------------------------------------------------------------------------------
|
|
3
|
-
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
4
|
-
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
5
|
-
*--------------------------------------------------------------------------------------------*/
|
|
6
|
-
/** @packageDocumentation
|
|
7
|
-
* @module Ids
|
|
8
|
-
*/
|
|
9
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.MutableCompressedId64Set = exports.OrderedId64Array = exports.CompressedId64Set = void 0;
|
|
11
|
-
const Assert_1 = require("./Assert");
|
|
12
|
-
const Id_1 = require("./Id");
|
|
13
|
-
const OrderedId64Iterable_1 = require("./OrderedId64Iterable");
|
|
14
|
-
const SortedArray_1 = require("./SortedArray");
|
|
15
|
-
/** A compact string representation of an [[Id64Set]]. Such a representation is useful when serializing potentially very large
|
|
16
|
-
* sets of Ids.
|
|
17
|
-
* @see [[CompressedId64Set.iterable]] to efficiently iterate the Ids represented by a compact string.
|
|
18
|
-
* @see [[CompressedId64Set.compressSet]] and [[CompressedId64Set.compressArray]] to produce a compact string from a collection of Ids.
|
|
19
|
-
* @see [[CompressedId64Set.decompressSet]] and [[CompressedId64Set.decompressArray]] to produce a collection of Ids from a compact string.
|
|
20
|
-
* @see [[OrderedId64Iterable]] for a generic representation of an ordered set of Ids (compressed or otherwise).
|
|
21
|
-
* @see [[MutableCompressedId64Set]] for a mutable version.
|
|
22
|
-
* @public
|
|
23
|
-
*/
|
|
24
|
-
var CompressedId64Set;
|
|
25
|
-
(function (CompressedId64Set) {
|
|
26
|
-
function isHexDigit(ch) {
|
|
27
|
-
// ascii values:
|
|
28
|
-
// '0' = 48
|
|
29
|
-
// '9' = 57
|
|
30
|
-
// 'a' = 65
|
|
31
|
-
// 'f' = 70
|
|
32
|
-
return (ch >= 48 && ch <= 57) || (ch >= 65 && ch <= 70);
|
|
33
|
-
}
|
|
34
|
-
function compactRange(increment, length) {
|
|
35
|
-
(0, Assert_1.assert)(length > 0);
|
|
36
|
-
const inc = `+${increment.toString()}`;
|
|
37
|
-
if (length <= 1)
|
|
38
|
-
return inc;
|
|
39
|
-
const len = length.toString(16).toUpperCase();
|
|
40
|
-
return `${inc}*${len}`;
|
|
41
|
-
}
|
|
42
|
-
/** Given a set of [[Id64String]]s, produce a compact string representation. Useful when serializing potentially large sets of Ids.
|
|
43
|
-
* @note Invalid Ids are ignored.
|
|
44
|
-
* @see [[CompressedId64Set.sortAndCompress]] to compress any unordered collection of Ids.
|
|
45
|
-
* @see [[CompressedId64Set.compressArray]] to perform the same operation on an [[Id64Array]].
|
|
46
|
-
* @see [[CompressedId64Set.decompressSet]] to perform the inverse operation.
|
|
47
|
-
*/
|
|
48
|
-
function compressSet(ids) {
|
|
49
|
-
return sortAndCompress(ids);
|
|
50
|
-
}
|
|
51
|
-
CompressedId64Set.compressSet = compressSet;
|
|
52
|
-
/** Create a sorted array from `ids`, then return a compact string representation of those Ids.
|
|
53
|
-
* @see [[compressIds]] if `ids` is known to already be sorted.
|
|
54
|
-
*/
|
|
55
|
-
function sortAndCompress(ids) {
|
|
56
|
-
// `string` is an Iterable<string>. In that case assume caller passed a single Id64String.
|
|
57
|
-
const arr = typeof ids === "string" ? [ids] : Array.from(ids);
|
|
58
|
-
OrderedId64Iterable_1.OrderedId64Iterable.sortArray(arr);
|
|
59
|
-
return compressArray(arr);
|
|
60
|
-
}
|
|
61
|
-
CompressedId64Set.sortAndCompress = sortAndCompress;
|
|
62
|
-
/** Give a **numerically-ordered** array of [[Id64String]]s, produce a compact string representation. Useful when serializing potentially large sets of Ids.
|
|
63
|
-
* Duplicate Ids are included only once in the string representation.
|
|
64
|
-
* @throws Error if two consecutive Ids `x` and `y` exist such that the numerical value of `x` is greater than that of `y` - i.e., the array is not properly sorted.
|
|
65
|
-
* @note The array must be sorted according to the 64-bit numerical value of each Id.
|
|
66
|
-
* @note Invalid Ids are ignored.
|
|
67
|
-
* @see [[CompressedId64Set.decompressArray]] to perform the inverse operation.
|
|
68
|
-
* @see [[OrderedId64Iterable.sortArray]] to ensure the Ids are properly sorted.
|
|
69
|
-
* @see [[CompressedId64Set.sortAndCompress]] to compress any unordered collection of Ids.
|
|
70
|
-
*/
|
|
71
|
-
function compressArray(ids) {
|
|
72
|
-
return compressIds(ids);
|
|
73
|
-
}
|
|
74
|
-
CompressedId64Set.compressArray = compressArray;
|
|
75
|
-
/** Give a **numerically-ordered** collection of [[Id64String]]s, produce a compact string representation. Useful when serializing potentially large sets of Ids.
|
|
76
|
-
* Duplicate Ids are included only once in the string representation.
|
|
77
|
-
* @throws Error if two consecutive Ids `x` and `y` exist such that the numerical value of `x` is greater than that of `y` - i.e., the collection is not properly sorted.
|
|
78
|
-
* @note The collection must be sorted according to the 64-bit numerical value of each Id.
|
|
79
|
-
* @note Invalid Ids are ignored.
|
|
80
|
-
* @see [[CompressedId64Set.iterable]] to perform the inverse operation.
|
|
81
|
-
* @see [[OrderedId64Iterable.sortArray]] or [[OrderedId64Iterable.compare]] to ensure the Ids are properly sorted.
|
|
82
|
-
* @see [[CompressedId64Set.sortAndCompress]] to compress any unordered collection of Ids.
|
|
83
|
-
*/
|
|
84
|
-
function compressIds(ids) {
|
|
85
|
-
if ("string" === typeof ids)
|
|
86
|
-
return ids;
|
|
87
|
-
let str = "";
|
|
88
|
-
const prevId = new Uint64();
|
|
89
|
-
const rangeIncrement = new Uint64();
|
|
90
|
-
let rangeLen = 0;
|
|
91
|
-
const curId = new Uint64();
|
|
92
|
-
const curIncrement = new Uint64();
|
|
93
|
-
for (const id of ids) {
|
|
94
|
-
if (!Id_1.Id64.isValidId64(id))
|
|
95
|
-
continue; // ignore garbage and invalid Ids ("0")
|
|
96
|
-
curId.setFromId(id);
|
|
97
|
-
curIncrement.setFromDifference(curId, prevId);
|
|
98
|
-
const cmp = prevId.compare(curId);
|
|
99
|
-
if (0 === cmp)
|
|
100
|
-
continue; // ignore duplicates
|
|
101
|
-
else if (cmp > 0)
|
|
102
|
-
throw new Error("CompressedId64Set.compressArray requires a sorted array as input");
|
|
103
|
-
prevId.copyFrom(curId);
|
|
104
|
-
if (0 === rangeLen) {
|
|
105
|
-
rangeIncrement.copyFrom(curIncrement);
|
|
106
|
-
rangeLen = 1;
|
|
107
|
-
}
|
|
108
|
-
else if (curIncrement.equals(rangeIncrement)) {
|
|
109
|
-
++rangeLen;
|
|
110
|
-
}
|
|
111
|
-
else {
|
|
112
|
-
str += compactRange(rangeIncrement, rangeLen);
|
|
113
|
-
rangeIncrement.copyFrom(curIncrement);
|
|
114
|
-
rangeLen = 1;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
if (0 < rangeLen)
|
|
118
|
-
str += compactRange(rangeIncrement, rangeLen);
|
|
119
|
-
return str;
|
|
120
|
-
}
|
|
121
|
-
CompressedId64Set.compressIds = compressIds;
|
|
122
|
-
/** This exists strictly for the purposes of compressed sets of 64-bit Ids, to avoid the overhead of BigInt for handling 64-bit integers. */
|
|
123
|
-
class Uint64 {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
(
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
}
|
|
138
|
-
compare(rhs) {
|
|
139
|
-
const diff = this.upper - rhs.upper;
|
|
140
|
-
return 0 === diff ? this.lower - rhs.lower : diff;
|
|
141
|
-
}
|
|
142
|
-
equals(rhs) { return 0 === this.compare(rhs); }
|
|
143
|
-
isLessThan(rhs) { return this.compare(rhs) < 0; }
|
|
144
|
-
isGreaterThan(rhs) { return this.compare(rhs) > 0; }
|
|
145
|
-
get isZero() { return 0 === this.lower && 0 === this.upper; }
|
|
146
|
-
setFromDifference(lhs, rhs) {
|
|
147
|
-
(0, Assert_1.assert)(!rhs.isGreaterThan(lhs));
|
|
148
|
-
this.lower = lhs.lower - rhs.lower;
|
|
149
|
-
this.upper = lhs.upper - rhs.upper;
|
|
150
|
-
if (this.lower < 0) {
|
|
151
|
-
this.lower += Uint64._base;
|
|
152
|
-
this.upper -= 1;
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
add(rhs) {
|
|
156
|
-
let lower = rhs.lower;
|
|
157
|
-
let upper = rhs.upper;
|
|
158
|
-
if (lower + this.lower >= Uint64._base) {
|
|
159
|
-
lower -= Uint64._base;
|
|
160
|
-
upper += 1;
|
|
161
|
-
}
|
|
162
|
-
this.lower += lower;
|
|
163
|
-
this.upper += upper;
|
|
164
|
-
this.assertConstraints();
|
|
165
|
-
}
|
|
166
|
-
setFromId(id) {
|
|
167
|
-
Id_1.Id64.getUint32Pair(id, this);
|
|
168
|
-
}
|
|
169
|
-
copyFrom(other) {
|
|
170
|
-
this.lower = other.lower;
|
|
171
|
-
this.upper = other.upper;
|
|
172
|
-
}
|
|
173
|
-
toString() {
|
|
174
|
-
if (0 === this.upper)
|
|
175
|
-
return this.lower.toString(16).toUpperCase();
|
|
176
|
-
const upper = this.upper.toString(16);
|
|
177
|
-
const lower = this.lower.toString(16).padStart(8, "0");
|
|
178
|
-
(0, Assert_1.assert)(lower.length === 8);
|
|
179
|
-
return `${upper}${lower}`.toUpperCase();
|
|
180
|
-
}
|
|
181
|
-
toId64String() {
|
|
182
|
-
return Id_1.Id64.fromUint32Pair(this.lower, this.upper);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
Uint64._base = 0x100000000;
|
|
186
|
-
/** Supplies an iterator over the [[Id64String]]s in a [[CompressedId64Set]].
|
|
187
|
-
* The Ids are iterated in ascending order based on their unsigned 64-bit integer values.
|
|
188
|
-
*/
|
|
189
|
-
function* iterator(ids) {
|
|
190
|
-
if (0 === ids.length)
|
|
191
|
-
return; // empty set.
|
|
192
|
-
if ("+" !== ids[0])
|
|
193
|
-
throw new Error("Invalid CompressedId64Set");
|
|
194
|
-
let curIndex = 1; // skip the leading '+'
|
|
195
|
-
const curId = new Uint64();
|
|
196
|
-
function parseUint32() {
|
|
197
|
-
let value = 0;
|
|
198
|
-
let nChars = 0;
|
|
199
|
-
while (curIndex < ids.length && nChars < 8) {
|
|
200
|
-
++nChars;
|
|
201
|
-
const ch = ids.charCodeAt(curIndex);
|
|
202
|
-
if (!isHexDigit(ch))
|
|
203
|
-
break; // not a hex digit in [0..9] or [A..F]
|
|
204
|
-
value <<= 4;
|
|
205
|
-
value |= (ch >= 65 ? ch - 65 + 10 : ch - 48); // ch - 'A' + 10 or ch - '0'
|
|
206
|
-
value = value >>> 0; // restore unsignedness because silly javascript.
|
|
207
|
-
++curIndex;
|
|
208
|
-
}
|
|
209
|
-
return value;
|
|
210
|
-
}
|
|
211
|
-
function parseUint64(uint64) {
|
|
212
|
-
let lower = 0;
|
|
213
|
-
let upper = 0;
|
|
214
|
-
// Read up to the first 8 digits.
|
|
215
|
-
const startIndex = curIndex;
|
|
216
|
-
const first = parseUint32();
|
|
217
|
-
const nFirstDigits = curIndex - startIndex;
|
|
218
|
-
(0, Assert_1.assert)(nFirstDigits <= 8);
|
|
219
|
-
if (8 === nFirstDigits && curIndex + 1 < ids.length && isHexDigit(ids.charCodeAt(curIndex + 1))) {
|
|
220
|
-
// We've got up to 8 more digits remaining
|
|
221
|
-
const secondIndex = curIndex;
|
|
222
|
-
const second = parseUint32();
|
|
223
|
-
// Transfer excess digits from upper to lower.
|
|
224
|
-
const nSecondDigits = curIndex - secondIndex;
|
|
225
|
-
(0, Assert_1.assert)(nSecondDigits > 0 && nSecondDigits <= 8);
|
|
226
|
-
const nDigitsToTransfer = 8 - nSecondDigits;
|
|
227
|
-
upper = first >>> (4 * nDigitsToTransfer);
|
|
228
|
-
const transfer = first - ((upper << (4 * nDigitsToTransfer)) >>> 0);
|
|
229
|
-
lower = (second | ((transfer << (4 * nSecondDigits)) >>> 0)) >>> 0;
|
|
230
|
-
}
|
|
231
|
-
else {
|
|
232
|
-
lower = first;
|
|
233
|
-
}
|
|
234
|
-
uint64.lower = lower;
|
|
235
|
-
uint64.upper = upper;
|
|
236
|
-
}
|
|
237
|
-
const increment = new Uint64();
|
|
238
|
-
while (curIndex < ids.length) {
|
|
239
|
-
let multiplier = 1;
|
|
240
|
-
parseUint64(increment);
|
|
241
|
-
if (increment.isZero)
|
|
242
|
-
throw new Error("Invalid CompressedId64Set");
|
|
243
|
-
if (curIndex < ids.length) {
|
|
244
|
-
switch (ids[curIndex++]) {
|
|
245
|
-
case "*":
|
|
246
|
-
multiplier = parseUint32();
|
|
247
|
-
if (0 === multiplier)
|
|
248
|
-
throw new Error("Invalid CompressedId64Set");
|
|
249
|
-
if (curIndex !== ids.length && ids[curIndex++] !== "+")
|
|
250
|
-
return;
|
|
251
|
-
break;
|
|
252
|
-
case "+":
|
|
253
|
-
break;
|
|
254
|
-
default:
|
|
255
|
-
throw new Error("Invalid CompressedId64Set");
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
for (let i = 0; i < multiplier; i++) {
|
|
259
|
-
curId.add(increment);
|
|
260
|
-
yield curId.toId64String();
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
CompressedId64Set.iterator = iterator;
|
|
265
|
-
/** Supplies an iterable over the [[Id64String]]s in a [[CompressedId64Set]].
|
|
266
|
-
* The Ids are iterated in ascending order based on their unsigned 64-bit integer values.
|
|
267
|
-
*/
|
|
268
|
-
function iterable(ids) {
|
|
269
|
-
return {
|
|
270
|
-
[Symbol.iterator]: () => iterator(ids),
|
|
271
|
-
};
|
|
272
|
-
}
|
|
273
|
-
CompressedId64Set.iterable = iterable;
|
|
274
|
-
/** Decompress the compact string representation of an [[Id64Set]] into an [[Id64Set]].
|
|
275
|
-
* @param compressedIds The compact string representation.
|
|
276
|
-
* @param out If supplied, the Ids will be inserted into this set rather than allocating and returning a new set.
|
|
277
|
-
* @returns The set containing the decompressed Ids.
|
|
278
|
-
* @throws Error if `compressedIds` is not a well-formed [[CompressedId64Set]].
|
|
279
|
-
* @see [[CompressedId64Set.compressSet]] to perform the inverse operation.
|
|
280
|
-
* @see [[CompressedId64Set.decompressArray]] to decompress as an [[Id64Array]] instead.
|
|
281
|
-
* @see [[CompressedId64Set.iterable]] to efficiently iterate the Ids.
|
|
282
|
-
*/
|
|
283
|
-
function decompressSet(compressedIds, out) {
|
|
284
|
-
const set = out
|
|
285
|
-
for (const id of iterable(compressedIds))
|
|
286
|
-
set.add(id);
|
|
287
|
-
return set;
|
|
288
|
-
}
|
|
289
|
-
CompressedId64Set.decompressSet = decompressSet;
|
|
290
|
-
/** Decompress the compact string representation of an [[Id64Set]] into an [[Id64Array]].
|
|
291
|
-
* @param compressedIds The compact string representation.
|
|
292
|
-
* @param out If supplied, the Ids will be appended to this array rather than allocating and returning a new array.
|
|
293
|
-
* @returns The array containing the decompressed Ids.
|
|
294
|
-
* @throws Error if `compressedIds` is not a well-formed [[CompressedId64Set]].
|
|
295
|
-
* @note The Ids are decompressed and appended to the array in ascending order based on their 64-bit numerical values.
|
|
296
|
-
* @see [[CompressedId64Set.compressArray]] to perform the inverse operation.
|
|
297
|
-
* @see [[CompressedId64Set.decompressSet]] to decompress as an [[Id64Set]] instead.
|
|
298
|
-
* @see [[CompressedId64Set.iterable]] to efficiently iterate the Ids.
|
|
299
|
-
*/
|
|
300
|
-
function decompressArray(compressedIds, out) {
|
|
301
|
-
const arr = out
|
|
302
|
-
for (const id of iterable(compressedIds))
|
|
303
|
-
arr.push(id);
|
|
304
|
-
return arr;
|
|
305
|
-
}
|
|
306
|
-
CompressedId64Set.decompressArray = decompressArray;
|
|
307
|
-
})(CompressedId64Set = exports.CompressedId64Set || (exports.CompressedId64Set = {}));
|
|
308
|
-
/** A [[SortedArray]] of unique [[Id64String]]s sorted in ascending order by the 64-bit unsigned integer values of the Ids.
|
|
309
|
-
* @see [[CompressedId64Set]] for an immutable compact string representation.
|
|
310
|
-
* @public
|
|
311
|
-
*/
|
|
312
|
-
class OrderedId64Array extends SortedArray_1.SortedArray {
|
|
313
|
-
/** Construct a new, empty array. */
|
|
314
|
-
constructor() {
|
|
315
|
-
super((lhs, rhs) => OrderedId64Iterable_1.OrderedId64Iterable.compare(lhs, rhs));
|
|
316
|
-
}
|
|
317
|
-
/** An iterable that iterates over the Ids in sorted order. */
|
|
318
|
-
get ids() { return this._array; }
|
|
319
|
-
/** The underlying array of Ids. */
|
|
320
|
-
get array() { return this._array; }
|
|
321
|
-
}
|
|
322
|
-
exports.OrderedId64Array = OrderedId64Array;
|
|
323
|
-
/** A mutable set of valid [[Id64String]]s sorted in ascending order by the 64-bit unsigned integer value of the Ids.
|
|
324
|
-
* Internally the set of Ids is maintained as a [[CompressedId64Set]] string representation.
|
|
325
|
-
* Insertions and removals are buffered until the string representation needs to be recomputed. The string representation is recomputed by every public method except [[add]] and [[delete]] -
|
|
326
|
-
* therefore, if multiple removals and/or insertions are required, it is most efficient to perform them all before invoking other methods.
|
|
327
|
-
* @public
|
|
328
|
-
*/
|
|
329
|
-
class MutableCompressedId64Set {
|
|
330
|
-
/** Construct a new set, optionally initialized to contain the Ids represented by `ids`. */
|
|
331
|
-
constructor(ids) {
|
|
332
|
-
this._inserted = new OrderedId64Array();
|
|
333
|
-
this._deleted = new OrderedId64Array();
|
|
334
|
-
this._ids = ids
|
|
335
|
-
}
|
|
336
|
-
/** Obtain the compact string representation of the contents of this set. If any insertions or removals are pending, they will be applied and the string recomputed. */
|
|
337
|
-
get ids() {
|
|
338
|
-
this.updateIds();
|
|
339
|
-
return this._ids;
|
|
340
|
-
}
|
|
341
|
-
/** Add the specified Id to the set.
|
|
342
|
-
* @throws Error if `id` is not a valid [[Id64String]].
|
|
343
|
-
*/
|
|
344
|
-
add(id) {
|
|
345
|
-
if (!Id_1.Id64.isValidId64(id))
|
|
346
|
-
throw new Error("MutableCompressedId64Set.add: invalid Id");
|
|
347
|
-
this._deleted.remove(id);
|
|
348
|
-
this._inserted.insert(id);
|
|
349
|
-
}
|
|
350
|
-
/** Remove the specified Id from the set.
|
|
351
|
-
* @throws Error if `id` is not a valid [[Id64String]].
|
|
352
|
-
*/
|
|
353
|
-
delete(id) {
|
|
354
|
-
if (!Id_1.Id64.isValidId64(id))
|
|
355
|
-
throw new Error("MutableCompressedId64Set.delete: invalid Id");
|
|
356
|
-
this._inserted.remove(id);
|
|
357
|
-
this._deleted.insert(id);
|
|
358
|
-
}
|
|
359
|
-
/** Remove all Ids from the set. */
|
|
360
|
-
clear() {
|
|
361
|
-
this._ids = "";
|
|
362
|
-
this._inserted.clear();
|
|
363
|
-
this._deleted.clear();
|
|
364
|
-
}
|
|
365
|
-
/** Remove all Ids from the set, then add the specified Ids. */
|
|
366
|
-
reset(ids) {
|
|
367
|
-
this.clear();
|
|
368
|
-
this._ids = ids
|
|
369
|
-
}
|
|
370
|
-
/** Obtain an iterator over the Ids in this set. The Ids are returned in ascending order based on their unsigned 64-bit integer values. */
|
|
371
|
-
[Symbol.iterator]() {
|
|
372
|
-
return CompressedId64Set.iterator(this.ids);
|
|
373
|
-
}
|
|
374
|
-
/** Compute a compact string representation of the union of this and another set of Ids - i.e., those Ids present in either this and/or the other set. */
|
|
375
|
-
computeUnion(ids) {
|
|
376
|
-
if (this.isEmpty)
|
|
377
|
-
return CompressedId64Set.compressIds(ids);
|
|
378
|
-
else if (OrderedId64Iterable_1.OrderedId64Iterable.isEmptySet(ids) || this.equals(ids))
|
|
379
|
-
return this.ids;
|
|
380
|
-
return CompressedId64Set.compressIds(OrderedId64Iterable_1.OrderedId64Iterable.union(this, ids));
|
|
381
|
-
}
|
|
382
|
-
/** Compute a compact string representation of the intersection of this and another set of Ids - i.e., those Ids present in both this and the other set. */
|
|
383
|
-
computeIntersection(ids) {
|
|
384
|
-
if (this.equals(ids))
|
|
385
|
-
return this.ids;
|
|
386
|
-
else if (this.isEmpty || OrderedId64Iterable_1.OrderedId64Iterable.isEmptySet(ids))
|
|
387
|
-
return "";
|
|
388
|
-
return CompressedId64Set.compressIds(OrderedId64Iterable_1.OrderedId64Iterable.intersection(this, ids));
|
|
389
|
-
}
|
|
390
|
-
/** Compute a compact string representation of the difference between this and another set - i.e., those Ids present in this but not in the other set. */
|
|
391
|
-
computeDifference(ids) {
|
|
392
|
-
if (this.isEmpty || this.equals(ids))
|
|
393
|
-
return "";
|
|
394
|
-
return CompressedId64Set.compressIds(OrderedId64Iterable_1.OrderedId64Iterable.difference(this, ids));
|
|
395
|
-
}
|
|
396
|
-
/** Return true if this set contains no Ids. */
|
|
397
|
-
get isEmpty() {
|
|
398
|
-
return OrderedId64Iterable_1.OrderedId64Iterable.isEmptySet(this.ids);
|
|
399
|
-
}
|
|
400
|
-
/** Return true if the set of Ids represented by `other` is identical to those in this set.
|
|
401
|
-
* @note This considers only the **distinct** Ids in `other` - duplicates are ignored.
|
|
402
|
-
*/
|
|
403
|
-
equals(other) {
|
|
404
|
-
if (other instanceof MutableCompressedId64Set) {
|
|
405
|
-
if (other === this)
|
|
406
|
-
return true;
|
|
407
|
-
if (typeof other !== "string")
|
|
408
|
-
other = other.ids;
|
|
409
|
-
}
|
|
410
|
-
if (typeof other === "string")
|
|
411
|
-
return other === this.ids;
|
|
412
|
-
this.updateIds();
|
|
413
|
-
return OrderedId64Iterable_1.OrderedId64Iterable.areEqualSets(this, other);
|
|
414
|
-
}
|
|
415
|
-
get _isDirty() {
|
|
416
|
-
return !this._inserted.isEmpty || !this._deleted.isEmpty;
|
|
417
|
-
}
|
|
418
|
-
updateIds() {
|
|
419
|
-
if (!this._isDirty)
|
|
420
|
-
return;
|
|
421
|
-
const difference = OrderedId64Iterable_1.OrderedId64Iterable.difference(CompressedId64Set.iterable(this._ids), this._deleted.ids);
|
|
422
|
-
const union = { [Symbol.iterator]: () => OrderedId64Iterable_1.OrderedId64Iterable.unionIterator(difference, this._inserted.ids) };
|
|
423
|
-
this._ids = CompressedId64Set.compressIds(union);
|
|
424
|
-
this._inserted.clear();
|
|
425
|
-
this._deleted.clear();
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
exports.MutableCompressedId64Set = MutableCompressedId64Set;
|
|
1
|
+
"use strict";
|
|
2
|
+
/*---------------------------------------------------------------------------------------------
|
|
3
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
4
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
5
|
+
*--------------------------------------------------------------------------------------------*/
|
|
6
|
+
/** @packageDocumentation
|
|
7
|
+
* @module Ids
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.MutableCompressedId64Set = exports.OrderedId64Array = exports.CompressedId64Set = void 0;
|
|
11
|
+
const Assert_1 = require("./Assert");
|
|
12
|
+
const Id_1 = require("./Id");
|
|
13
|
+
const OrderedId64Iterable_1 = require("./OrderedId64Iterable");
|
|
14
|
+
const SortedArray_1 = require("./SortedArray");
|
|
15
|
+
/** A compact string representation of an [[Id64Set]]. Such a representation is useful when serializing potentially very large
|
|
16
|
+
* sets of Ids.
|
|
17
|
+
* @see [[CompressedId64Set.iterable]] to efficiently iterate the Ids represented by a compact string.
|
|
18
|
+
* @see [[CompressedId64Set.compressSet]] and [[CompressedId64Set.compressArray]] to produce a compact string from a collection of Ids.
|
|
19
|
+
* @see [[CompressedId64Set.decompressSet]] and [[CompressedId64Set.decompressArray]] to produce a collection of Ids from a compact string.
|
|
20
|
+
* @see [[OrderedId64Iterable]] for a generic representation of an ordered set of Ids (compressed or otherwise).
|
|
21
|
+
* @see [[MutableCompressedId64Set]] for a mutable version.
|
|
22
|
+
* @public
|
|
23
|
+
*/
|
|
24
|
+
var CompressedId64Set;
|
|
25
|
+
(function (CompressedId64Set) {
|
|
26
|
+
function isHexDigit(ch) {
|
|
27
|
+
// ascii values:
|
|
28
|
+
// '0' = 48
|
|
29
|
+
// '9' = 57
|
|
30
|
+
// 'a' = 65
|
|
31
|
+
// 'f' = 70
|
|
32
|
+
return (ch >= 48 && ch <= 57) || (ch >= 65 && ch <= 70);
|
|
33
|
+
}
|
|
34
|
+
function compactRange(increment, length) {
|
|
35
|
+
(0, Assert_1.assert)(length > 0);
|
|
36
|
+
const inc = `+${increment.toString()}`;
|
|
37
|
+
if (length <= 1)
|
|
38
|
+
return inc;
|
|
39
|
+
const len = length.toString(16).toUpperCase();
|
|
40
|
+
return `${inc}*${len}`;
|
|
41
|
+
}
|
|
42
|
+
/** Given a set of [[Id64String]]s, produce a compact string representation. Useful when serializing potentially large sets of Ids.
|
|
43
|
+
* @note Invalid Ids are ignored.
|
|
44
|
+
* @see [[CompressedId64Set.sortAndCompress]] to compress any unordered collection of Ids.
|
|
45
|
+
* @see [[CompressedId64Set.compressArray]] to perform the same operation on an [[Id64Array]].
|
|
46
|
+
* @see [[CompressedId64Set.decompressSet]] to perform the inverse operation.
|
|
47
|
+
*/
|
|
48
|
+
function compressSet(ids) {
|
|
49
|
+
return sortAndCompress(ids);
|
|
50
|
+
}
|
|
51
|
+
CompressedId64Set.compressSet = compressSet;
|
|
52
|
+
/** Create a sorted array from `ids`, then return a compact string representation of those Ids.
|
|
53
|
+
* @see [[compressIds]] if `ids` is known to already be sorted.
|
|
54
|
+
*/
|
|
55
|
+
function sortAndCompress(ids) {
|
|
56
|
+
// `string` is an Iterable<string>. In that case assume caller passed a single Id64String.
|
|
57
|
+
const arr = typeof ids === "string" ? [ids] : Array.from(ids);
|
|
58
|
+
OrderedId64Iterable_1.OrderedId64Iterable.sortArray(arr);
|
|
59
|
+
return compressArray(arr);
|
|
60
|
+
}
|
|
61
|
+
CompressedId64Set.sortAndCompress = sortAndCompress;
|
|
62
|
+
/** Give a **numerically-ordered** array of [[Id64String]]s, produce a compact string representation. Useful when serializing potentially large sets of Ids.
|
|
63
|
+
* Duplicate Ids are included only once in the string representation.
|
|
64
|
+
* @throws Error if two consecutive Ids `x` and `y` exist such that the numerical value of `x` is greater than that of `y` - i.e., the array is not properly sorted.
|
|
65
|
+
* @note The array must be sorted according to the 64-bit numerical value of each Id.
|
|
66
|
+
* @note Invalid Ids are ignored.
|
|
67
|
+
* @see [[CompressedId64Set.decompressArray]] to perform the inverse operation.
|
|
68
|
+
* @see [[OrderedId64Iterable.sortArray]] to ensure the Ids are properly sorted.
|
|
69
|
+
* @see [[CompressedId64Set.sortAndCompress]] to compress any unordered collection of Ids.
|
|
70
|
+
*/
|
|
71
|
+
function compressArray(ids) {
|
|
72
|
+
return compressIds(ids);
|
|
73
|
+
}
|
|
74
|
+
CompressedId64Set.compressArray = compressArray;
|
|
75
|
+
/** Give a **numerically-ordered** collection of [[Id64String]]s, produce a compact string representation. Useful when serializing potentially large sets of Ids.
|
|
76
|
+
* Duplicate Ids are included only once in the string representation.
|
|
77
|
+
* @throws Error if two consecutive Ids `x` and `y` exist such that the numerical value of `x` is greater than that of `y` - i.e., the collection is not properly sorted.
|
|
78
|
+
* @note The collection must be sorted according to the 64-bit numerical value of each Id.
|
|
79
|
+
* @note Invalid Ids are ignored.
|
|
80
|
+
* @see [[CompressedId64Set.iterable]] to perform the inverse operation.
|
|
81
|
+
* @see [[OrderedId64Iterable.sortArray]] or [[OrderedId64Iterable.compare]] to ensure the Ids are properly sorted.
|
|
82
|
+
* @see [[CompressedId64Set.sortAndCompress]] to compress any unordered collection of Ids.
|
|
83
|
+
*/
|
|
84
|
+
function compressIds(ids) {
|
|
85
|
+
if ("string" === typeof ids)
|
|
86
|
+
return ids;
|
|
87
|
+
let str = "";
|
|
88
|
+
const prevId = new Uint64();
|
|
89
|
+
const rangeIncrement = new Uint64();
|
|
90
|
+
let rangeLen = 0;
|
|
91
|
+
const curId = new Uint64();
|
|
92
|
+
const curIncrement = new Uint64();
|
|
93
|
+
for (const id of ids) {
|
|
94
|
+
if (!Id_1.Id64.isValidId64(id))
|
|
95
|
+
continue; // ignore garbage and invalid Ids ("0")
|
|
96
|
+
curId.setFromId(id);
|
|
97
|
+
curIncrement.setFromDifference(curId, prevId);
|
|
98
|
+
const cmp = prevId.compare(curId);
|
|
99
|
+
if (0 === cmp)
|
|
100
|
+
continue; // ignore duplicates
|
|
101
|
+
else if (cmp > 0)
|
|
102
|
+
throw new Error("CompressedId64Set.compressArray requires a sorted array as input");
|
|
103
|
+
prevId.copyFrom(curId);
|
|
104
|
+
if (0 === rangeLen) {
|
|
105
|
+
rangeIncrement.copyFrom(curIncrement);
|
|
106
|
+
rangeLen = 1;
|
|
107
|
+
}
|
|
108
|
+
else if (curIncrement.equals(rangeIncrement)) {
|
|
109
|
+
++rangeLen;
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
str += compactRange(rangeIncrement, rangeLen);
|
|
113
|
+
rangeIncrement.copyFrom(curIncrement);
|
|
114
|
+
rangeLen = 1;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
if (0 < rangeLen)
|
|
118
|
+
str += compactRange(rangeIncrement, rangeLen);
|
|
119
|
+
return str;
|
|
120
|
+
}
|
|
121
|
+
CompressedId64Set.compressIds = compressIds;
|
|
122
|
+
/** This exists strictly for the purposes of compressed sets of 64-bit Ids, to avoid the overhead of BigInt for handling 64-bit integers. */
|
|
123
|
+
class Uint64 {
|
|
124
|
+
static assertUint32(num) {
|
|
125
|
+
(0, Assert_1.assert)(num >= 0);
|
|
126
|
+
(0, Assert_1.assert)(num < Uint64._base);
|
|
127
|
+
(0, Assert_1.assert)(Math.floor(num) === num);
|
|
128
|
+
}
|
|
129
|
+
assertConstraints() {
|
|
130
|
+
Uint64.assertUint32(this.lower);
|
|
131
|
+
Uint64.assertUint32(this.upper);
|
|
132
|
+
}
|
|
133
|
+
constructor(lower = 0, upper = 0) {
|
|
134
|
+
this.lower = lower;
|
|
135
|
+
this.upper = upper;
|
|
136
|
+
this.assertConstraints();
|
|
137
|
+
}
|
|
138
|
+
compare(rhs) {
|
|
139
|
+
const diff = this.upper - rhs.upper;
|
|
140
|
+
return 0 === diff ? this.lower - rhs.lower : diff;
|
|
141
|
+
}
|
|
142
|
+
equals(rhs) { return 0 === this.compare(rhs); }
|
|
143
|
+
isLessThan(rhs) { return this.compare(rhs) < 0; }
|
|
144
|
+
isGreaterThan(rhs) { return this.compare(rhs) > 0; }
|
|
145
|
+
get isZero() { return 0 === this.lower && 0 === this.upper; }
|
|
146
|
+
setFromDifference(lhs, rhs) {
|
|
147
|
+
(0, Assert_1.assert)(!rhs.isGreaterThan(lhs));
|
|
148
|
+
this.lower = lhs.lower - rhs.lower;
|
|
149
|
+
this.upper = lhs.upper - rhs.upper;
|
|
150
|
+
if (this.lower < 0) {
|
|
151
|
+
this.lower += Uint64._base;
|
|
152
|
+
this.upper -= 1;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
add(rhs) {
|
|
156
|
+
let lower = rhs.lower;
|
|
157
|
+
let upper = rhs.upper;
|
|
158
|
+
if (lower + this.lower >= Uint64._base) {
|
|
159
|
+
lower -= Uint64._base;
|
|
160
|
+
upper += 1;
|
|
161
|
+
}
|
|
162
|
+
this.lower += lower;
|
|
163
|
+
this.upper += upper;
|
|
164
|
+
this.assertConstraints();
|
|
165
|
+
}
|
|
166
|
+
setFromId(id) {
|
|
167
|
+
Id_1.Id64.getUint32Pair(id, this);
|
|
168
|
+
}
|
|
169
|
+
copyFrom(other) {
|
|
170
|
+
this.lower = other.lower;
|
|
171
|
+
this.upper = other.upper;
|
|
172
|
+
}
|
|
173
|
+
toString() {
|
|
174
|
+
if (0 === this.upper)
|
|
175
|
+
return this.lower.toString(16).toUpperCase();
|
|
176
|
+
const upper = this.upper.toString(16);
|
|
177
|
+
const lower = this.lower.toString(16).padStart(8, "0");
|
|
178
|
+
(0, Assert_1.assert)(lower.length === 8);
|
|
179
|
+
return `${upper}${lower}`.toUpperCase();
|
|
180
|
+
}
|
|
181
|
+
toId64String() {
|
|
182
|
+
return Id_1.Id64.fromUint32Pair(this.lower, this.upper);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
Uint64._base = 0x100000000;
|
|
186
|
+
/** Supplies an iterator over the [[Id64String]]s in a [[CompressedId64Set]].
|
|
187
|
+
* The Ids are iterated in ascending order based on their unsigned 64-bit integer values.
|
|
188
|
+
*/
|
|
189
|
+
function* iterator(ids) {
|
|
190
|
+
if (0 === ids.length)
|
|
191
|
+
return; // empty set.
|
|
192
|
+
if ("+" !== ids[0])
|
|
193
|
+
throw new Error("Invalid CompressedId64Set");
|
|
194
|
+
let curIndex = 1; // skip the leading '+'
|
|
195
|
+
const curId = new Uint64();
|
|
196
|
+
function parseUint32() {
|
|
197
|
+
let value = 0;
|
|
198
|
+
let nChars = 0;
|
|
199
|
+
while (curIndex < ids.length && nChars < 8) {
|
|
200
|
+
++nChars;
|
|
201
|
+
const ch = ids.charCodeAt(curIndex);
|
|
202
|
+
if (!isHexDigit(ch))
|
|
203
|
+
break; // not a hex digit in [0..9] or [A..F]
|
|
204
|
+
value <<= 4;
|
|
205
|
+
value |= (ch >= 65 ? ch - 65 + 10 : ch - 48); // ch - 'A' + 10 or ch - '0'
|
|
206
|
+
value = value >>> 0; // restore unsignedness because silly javascript.
|
|
207
|
+
++curIndex;
|
|
208
|
+
}
|
|
209
|
+
return value;
|
|
210
|
+
}
|
|
211
|
+
function parseUint64(uint64) {
|
|
212
|
+
let lower = 0;
|
|
213
|
+
let upper = 0;
|
|
214
|
+
// Read up to the first 8 digits.
|
|
215
|
+
const startIndex = curIndex;
|
|
216
|
+
const first = parseUint32();
|
|
217
|
+
const nFirstDigits = curIndex - startIndex;
|
|
218
|
+
(0, Assert_1.assert)(nFirstDigits <= 8);
|
|
219
|
+
if (8 === nFirstDigits && curIndex + 1 < ids.length && isHexDigit(ids.charCodeAt(curIndex + 1))) {
|
|
220
|
+
// We've got up to 8 more digits remaining
|
|
221
|
+
const secondIndex = curIndex;
|
|
222
|
+
const second = parseUint32();
|
|
223
|
+
// Transfer excess digits from upper to lower.
|
|
224
|
+
const nSecondDigits = curIndex - secondIndex;
|
|
225
|
+
(0, Assert_1.assert)(nSecondDigits > 0 && nSecondDigits <= 8);
|
|
226
|
+
const nDigitsToTransfer = 8 - nSecondDigits;
|
|
227
|
+
upper = first >>> (4 * nDigitsToTransfer);
|
|
228
|
+
const transfer = first - ((upper << (4 * nDigitsToTransfer)) >>> 0);
|
|
229
|
+
lower = (second | ((transfer << (4 * nSecondDigits)) >>> 0)) >>> 0;
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
lower = first;
|
|
233
|
+
}
|
|
234
|
+
uint64.lower = lower;
|
|
235
|
+
uint64.upper = upper;
|
|
236
|
+
}
|
|
237
|
+
const increment = new Uint64();
|
|
238
|
+
while (curIndex < ids.length) {
|
|
239
|
+
let multiplier = 1;
|
|
240
|
+
parseUint64(increment);
|
|
241
|
+
if (increment.isZero)
|
|
242
|
+
throw new Error("Invalid CompressedId64Set");
|
|
243
|
+
if (curIndex < ids.length) {
|
|
244
|
+
switch (ids[curIndex++]) {
|
|
245
|
+
case "*":
|
|
246
|
+
multiplier = parseUint32();
|
|
247
|
+
if (0 === multiplier)
|
|
248
|
+
throw new Error("Invalid CompressedId64Set");
|
|
249
|
+
if (curIndex !== ids.length && ids[curIndex++] !== "+")
|
|
250
|
+
return;
|
|
251
|
+
break;
|
|
252
|
+
case "+":
|
|
253
|
+
break;
|
|
254
|
+
default:
|
|
255
|
+
throw new Error("Invalid CompressedId64Set");
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
for (let i = 0; i < multiplier; i++) {
|
|
259
|
+
curId.add(increment);
|
|
260
|
+
yield curId.toId64String();
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
CompressedId64Set.iterator = iterator;
|
|
265
|
+
/** Supplies an iterable over the [[Id64String]]s in a [[CompressedId64Set]].
|
|
266
|
+
* The Ids are iterated in ascending order based on their unsigned 64-bit integer values.
|
|
267
|
+
*/
|
|
268
|
+
function iterable(ids) {
|
|
269
|
+
return {
|
|
270
|
+
[Symbol.iterator]: () => iterator(ids),
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
CompressedId64Set.iterable = iterable;
|
|
274
|
+
/** Decompress the compact string representation of an [[Id64Set]] into an [[Id64Set]].
|
|
275
|
+
* @param compressedIds The compact string representation.
|
|
276
|
+
* @param out If supplied, the Ids will be inserted into this set rather than allocating and returning a new set.
|
|
277
|
+
* @returns The set containing the decompressed Ids.
|
|
278
|
+
* @throws Error if `compressedIds` is not a well-formed [[CompressedId64Set]].
|
|
279
|
+
* @see [[CompressedId64Set.compressSet]] to perform the inverse operation.
|
|
280
|
+
* @see [[CompressedId64Set.decompressArray]] to decompress as an [[Id64Array]] instead.
|
|
281
|
+
* @see [[CompressedId64Set.iterable]] to efficiently iterate the Ids.
|
|
282
|
+
*/
|
|
283
|
+
function decompressSet(compressedIds, out) {
|
|
284
|
+
const set = out ?? new Set();
|
|
285
|
+
for (const id of iterable(compressedIds))
|
|
286
|
+
set.add(id);
|
|
287
|
+
return set;
|
|
288
|
+
}
|
|
289
|
+
CompressedId64Set.decompressSet = decompressSet;
|
|
290
|
+
/** Decompress the compact string representation of an [[Id64Set]] into an [[Id64Array]].
|
|
291
|
+
* @param compressedIds The compact string representation.
|
|
292
|
+
* @param out If supplied, the Ids will be appended to this array rather than allocating and returning a new array.
|
|
293
|
+
* @returns The array containing the decompressed Ids.
|
|
294
|
+
* @throws Error if `compressedIds` is not a well-formed [[CompressedId64Set]].
|
|
295
|
+
* @note The Ids are decompressed and appended to the array in ascending order based on their 64-bit numerical values.
|
|
296
|
+
* @see [[CompressedId64Set.compressArray]] to perform the inverse operation.
|
|
297
|
+
* @see [[CompressedId64Set.decompressSet]] to decompress as an [[Id64Set]] instead.
|
|
298
|
+
* @see [[CompressedId64Set.iterable]] to efficiently iterate the Ids.
|
|
299
|
+
*/
|
|
300
|
+
function decompressArray(compressedIds, out) {
|
|
301
|
+
const arr = out ?? [];
|
|
302
|
+
for (const id of iterable(compressedIds))
|
|
303
|
+
arr.push(id);
|
|
304
|
+
return arr;
|
|
305
|
+
}
|
|
306
|
+
CompressedId64Set.decompressArray = decompressArray;
|
|
307
|
+
})(CompressedId64Set = exports.CompressedId64Set || (exports.CompressedId64Set = {}));
|
|
308
|
+
/** A [[SortedArray]] of unique [[Id64String]]s sorted in ascending order by the 64-bit unsigned integer values of the Ids.
|
|
309
|
+
* @see [[CompressedId64Set]] for an immutable compact string representation.
|
|
310
|
+
* @public
|
|
311
|
+
*/
|
|
312
|
+
class OrderedId64Array extends SortedArray_1.SortedArray {
|
|
313
|
+
/** Construct a new, empty array. */
|
|
314
|
+
constructor() {
|
|
315
|
+
super((lhs, rhs) => OrderedId64Iterable_1.OrderedId64Iterable.compare(lhs, rhs));
|
|
316
|
+
}
|
|
317
|
+
/** An iterable that iterates over the Ids in sorted order. */
|
|
318
|
+
get ids() { return this._array; }
|
|
319
|
+
/** The underlying array of Ids. */
|
|
320
|
+
get array() { return this._array; }
|
|
321
|
+
}
|
|
322
|
+
exports.OrderedId64Array = OrderedId64Array;
|
|
323
|
+
/** A mutable set of valid [[Id64String]]s sorted in ascending order by the 64-bit unsigned integer value of the Ids.
|
|
324
|
+
* Internally the set of Ids is maintained as a [[CompressedId64Set]] string representation.
|
|
325
|
+
* Insertions and removals are buffered until the string representation needs to be recomputed. The string representation is recomputed by every public method except [[add]] and [[delete]] -
|
|
326
|
+
* therefore, if multiple removals and/or insertions are required, it is most efficient to perform them all before invoking other methods.
|
|
327
|
+
* @public
|
|
328
|
+
*/
|
|
329
|
+
class MutableCompressedId64Set {
|
|
330
|
+
/** Construct a new set, optionally initialized to contain the Ids represented by `ids`. */
|
|
331
|
+
constructor(ids) {
|
|
332
|
+
this._inserted = new OrderedId64Array();
|
|
333
|
+
this._deleted = new OrderedId64Array();
|
|
334
|
+
this._ids = ids ?? "";
|
|
335
|
+
}
|
|
336
|
+
/** Obtain the compact string representation of the contents of this set. If any insertions or removals are pending, they will be applied and the string recomputed. */
|
|
337
|
+
get ids() {
|
|
338
|
+
this.updateIds();
|
|
339
|
+
return this._ids;
|
|
340
|
+
}
|
|
341
|
+
/** Add the specified Id to the set.
|
|
342
|
+
* @throws Error if `id` is not a valid [[Id64String]].
|
|
343
|
+
*/
|
|
344
|
+
add(id) {
|
|
345
|
+
if (!Id_1.Id64.isValidId64(id))
|
|
346
|
+
throw new Error("MutableCompressedId64Set.add: invalid Id");
|
|
347
|
+
this._deleted.remove(id);
|
|
348
|
+
this._inserted.insert(id);
|
|
349
|
+
}
|
|
350
|
+
/** Remove the specified Id from the set.
|
|
351
|
+
* @throws Error if `id` is not a valid [[Id64String]].
|
|
352
|
+
*/
|
|
353
|
+
delete(id) {
|
|
354
|
+
if (!Id_1.Id64.isValidId64(id))
|
|
355
|
+
throw new Error("MutableCompressedId64Set.delete: invalid Id");
|
|
356
|
+
this._inserted.remove(id);
|
|
357
|
+
this._deleted.insert(id);
|
|
358
|
+
}
|
|
359
|
+
/** Remove all Ids from the set. */
|
|
360
|
+
clear() {
|
|
361
|
+
this._ids = "";
|
|
362
|
+
this._inserted.clear();
|
|
363
|
+
this._deleted.clear();
|
|
364
|
+
}
|
|
365
|
+
/** Remove all Ids from the set, then add the specified Ids. */
|
|
366
|
+
reset(ids) {
|
|
367
|
+
this.clear();
|
|
368
|
+
this._ids = ids ?? "";
|
|
369
|
+
}
|
|
370
|
+
/** Obtain an iterator over the Ids in this set. The Ids are returned in ascending order based on their unsigned 64-bit integer values. */
|
|
371
|
+
[Symbol.iterator]() {
|
|
372
|
+
return CompressedId64Set.iterator(this.ids);
|
|
373
|
+
}
|
|
374
|
+
/** Compute a compact string representation of the union of this and another set of Ids - i.e., those Ids present in either this and/or the other set. */
|
|
375
|
+
computeUnion(ids) {
|
|
376
|
+
if (this.isEmpty)
|
|
377
|
+
return CompressedId64Set.compressIds(ids);
|
|
378
|
+
else if (OrderedId64Iterable_1.OrderedId64Iterable.isEmptySet(ids) || this.equals(ids))
|
|
379
|
+
return this.ids;
|
|
380
|
+
return CompressedId64Set.compressIds(OrderedId64Iterable_1.OrderedId64Iterable.union(this, ids));
|
|
381
|
+
}
|
|
382
|
+
/** Compute a compact string representation of the intersection of this and another set of Ids - i.e., those Ids present in both this and the other set. */
|
|
383
|
+
computeIntersection(ids) {
|
|
384
|
+
if (this.equals(ids))
|
|
385
|
+
return this.ids;
|
|
386
|
+
else if (this.isEmpty || OrderedId64Iterable_1.OrderedId64Iterable.isEmptySet(ids))
|
|
387
|
+
return "";
|
|
388
|
+
return CompressedId64Set.compressIds(OrderedId64Iterable_1.OrderedId64Iterable.intersection(this, ids));
|
|
389
|
+
}
|
|
390
|
+
/** Compute a compact string representation of the difference between this and another set - i.e., those Ids present in this but not in the other set. */
|
|
391
|
+
computeDifference(ids) {
|
|
392
|
+
if (this.isEmpty || this.equals(ids))
|
|
393
|
+
return "";
|
|
394
|
+
return CompressedId64Set.compressIds(OrderedId64Iterable_1.OrderedId64Iterable.difference(this, ids));
|
|
395
|
+
}
|
|
396
|
+
/** Return true if this set contains no Ids. */
|
|
397
|
+
get isEmpty() {
|
|
398
|
+
return OrderedId64Iterable_1.OrderedId64Iterable.isEmptySet(this.ids);
|
|
399
|
+
}
|
|
400
|
+
/** Return true if the set of Ids represented by `other` is identical to those in this set.
|
|
401
|
+
* @note This considers only the **distinct** Ids in `other` - duplicates are ignored.
|
|
402
|
+
*/
|
|
403
|
+
equals(other) {
|
|
404
|
+
if (other instanceof MutableCompressedId64Set) {
|
|
405
|
+
if (other === this)
|
|
406
|
+
return true;
|
|
407
|
+
if (typeof other !== "string")
|
|
408
|
+
other = other.ids;
|
|
409
|
+
}
|
|
410
|
+
if (typeof other === "string")
|
|
411
|
+
return other === this.ids;
|
|
412
|
+
this.updateIds();
|
|
413
|
+
return OrderedId64Iterable_1.OrderedId64Iterable.areEqualSets(this, other);
|
|
414
|
+
}
|
|
415
|
+
get _isDirty() {
|
|
416
|
+
return !this._inserted.isEmpty || !this._deleted.isEmpty;
|
|
417
|
+
}
|
|
418
|
+
updateIds() {
|
|
419
|
+
if (!this._isDirty)
|
|
420
|
+
return;
|
|
421
|
+
const difference = OrderedId64Iterable_1.OrderedId64Iterable.difference(CompressedId64Set.iterable(this._ids), this._deleted.ids);
|
|
422
|
+
const union = { [Symbol.iterator]: () => OrderedId64Iterable_1.OrderedId64Iterable.unionIterator(difference, this._inserted.ids) };
|
|
423
|
+
this._ids = CompressedId64Set.compressIds(union);
|
|
424
|
+
this._inserted.clear();
|
|
425
|
+
this._deleted.clear();
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
exports.MutableCompressedId64Set = MutableCompressedId64Set;
|
|
429
429
|
//# sourceMappingURL=CompressedId64Set.js.map
|