@isopodlabs/utilities 1.5.8 → 1.6.0

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.
Files changed (3) hide show
  1. package/dist/bits.d.ts +94 -56
  2. package/dist/bits.js +651 -381
  3. package/package.json +1 -1
package/dist/bits.js CHANGED
@@ -1,30 +1,70 @@
1
1
  "use strict";
2
+ //-----------------------------------------------------------------------------
3
+ // Bit twiddling functions
4
+ //-----------------------------------------------------------------------------
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DenseBits = exports.ImmutableDenseBits = exports.SparseBits = exports.ImmutableSparseBits = void 0;
6
+ exports.SparseBits2 = exports.ImmutableSparseBits2 = exports.SparseBits = exports.ImmutableSparseBits = exports.DenseBits = exports.ImmutableDenseBits = void 0;
4
7
  exports.lowestSet32 = lowestSet32;
5
8
  exports.highestSet32 = highestSet32;
9
+ exports.highestSet1024 = highestSet1024;
6
10
  exports.countSet32 = countSet32;
11
+ exports.nthSet32 = nthSet32;
7
12
  exports.highestSet = highestSet;
8
13
  exports.lowestSet = lowestSet;
9
14
  exports.countSet = countSet;
15
+ exports.nthSet = nthSet;
10
16
  exports.highestClear = highestClear;
11
17
  exports.lowestClear = lowestClear;
12
18
  exports.countClear = countClear;
13
- const algorithm_1 = require("./algorithm");
14
- //-----------------------------------------------------------------------------
15
- // Bit twiddling functions
16
- //-----------------------------------------------------------------------------
19
+ exports.clearLowest = clearLowest;
20
+ // Returns the index (0-31) of the lowest set bit, or 32 if none
17
21
  function lowestSet32(x) {
18
22
  return x === 0 ? 32 : 31 - Math.clz32(x & -x);
19
23
  }
24
+ // Returns the index (1-32) of the highest set bit, or 0 if none
20
25
  function highestSet32(x) {
21
26
  return x ? 32 - Math.clz32(x) : 0;
22
27
  }
28
+ function highestSet1024(x) {
29
+ let b = Math.floor(Math.log2(x));
30
+ return 1n << BigInt(b) <= x ? b + 1 : b;
31
+ }
32
+ // Returns the number of set bits
23
33
  function countSet32(x) {
24
34
  x = x - ((x >> 1) & 0x55555555);
25
35
  x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
26
36
  return ((x + (x >> 4) & 0xF0F0F0F) * 0x1010101) >> 24;
27
37
  }
38
+ // Returns the index (0-31) of the nth set bit, or 32 if none
39
+ function nthSet32(x, i) {
40
+ let b2 = x - ((x >> 1) & 0x55555555);
41
+ let b4 = (b2 & 0x33333333) + ((b2 >> 2) & 0x33333333);
42
+ let b8 = (b4 + (b4 >> 4) & 0xF0F0F0F);
43
+ let b16 = (b8 + (b8 >> 8)) & 0xff;
44
+ let n = 0;
45
+ if (i >= b16) {
46
+ i -= b16;
47
+ n += 16;
48
+ }
49
+ b8 = (b8 >> n) & 0xff;
50
+ if (i >= b8) {
51
+ i -= b8;
52
+ n += 8;
53
+ }
54
+ b4 = (b4 >> n) & 0x0f;
55
+ if (i >= b4) {
56
+ i -= b4;
57
+ n += 4;
58
+ }
59
+ b2 = (b2 >> n) & 0x03;
60
+ if (i >= b2) {
61
+ i -= b2;
62
+ n += 2;
63
+ }
64
+ if (i >= ((x >> n) & 1))
65
+ ++n;
66
+ return n;
67
+ }
28
68
  /*
29
69
  const testersShift: bigint[] = []; //32 << i
30
70
  const testers: bigint[] = []; //1 << (32 << i)
@@ -85,42 +125,59 @@ export function bitcountCached(x: bigint): number {
85
125
  return Number(x & 0xFFFFFFFFn);
86
126
  }
87
127
  */
88
- function highestSet(x) {
89
- if (x < 0)
90
- x = ~x;
91
- if (x < 0x100000000)
92
- return highestSet32(Number(x));
93
- // For numbers within safe float range, use log2
94
- if (x <= Number.MAX_VALUE) {
95
- const b = Math.floor(Math.log2(Number(x)));
96
- return (1n << BigInt(b)) <= x ? b + 1 : b;
97
- }
98
- // For arbitrarily large bigints, use bit-shifting method
99
- let y = BigInt(x);
128
+ /*
129
+ function highestSetBig32(x: bigint): number {
100
130
  let s = 0;
101
131
  let k = 0;
102
- for (let t = y >> 32n; t; t >>= BigInt(s)) {
132
+
133
+ for (let t = x >> 32n; t; t >>= BigInt(s)) {
103
134
  s = 32 << k++;
104
- y = t;
135
+ x = t;
136
+ }
137
+
138
+ if (k) {
139
+ while (--k) {
140
+ const b = x >> BigInt(16 << k);
141
+ if (b) {
142
+ s += 16 << k;
143
+ x = b;
144
+ }
145
+ }
146
+ }
147
+ return (s + 32) - Math.clz32(Number(x));
148
+ }
149
+ */
150
+ function highestSetBig1024(x) {
151
+ let s = 0;
152
+ let k = 0;
153
+ for (let t = x >> 1024n; t; t >>= BigInt(s)) {
154
+ s = 1024 << k++;
155
+ x = t;
105
156
  }
106
157
  if (k) {
107
- // determine length by bisection
108
- k--;
109
- while (k--) {
110
- const b = y >> BigInt(32 << k);
158
+ while (--k) {
159
+ const b = x >> BigInt(512 << k);
111
160
  if (b) {
112
- s += 32 << k;
113
- y = b;
161
+ s += 512 << k;
162
+ x = b;
114
163
  }
115
164
  }
116
165
  }
117
- return (s + 32) - Math.clz32(Number(y));
166
+ return highestSet1024(Number(x)) + s;
167
+ }
168
+ function highestSet(x) {
169
+ if (x < 0)
170
+ x = ~x;
171
+ return x < 0x100000000 ? highestSet32(Number(x))
172
+ : x <= Number.MAX_VALUE ? highestSet1024(Number(x))
173
+ : highestSetBig1024(BigInt(x));
118
174
  }
119
175
  function lowestSet(x) {
120
- if (x < 0x100000000)
121
- return lowestSet32(Number(x));
122
- const xb = BigInt(x < 0 ? ~x : x);
123
- return highestSet(xb & -xb) - 1;
176
+ if (typeof x === 'number') {
177
+ x = x < 0 ? (~x & (x + 1)) : x & -x;
178
+ return (x < 0x100000000 ? highestSet32(x) : highestSet1024(x)) - 1;
179
+ }
180
+ return highestSetBig1024(x < 0 ? (~x & (x + 1n)) : x & -x) - 1;
124
181
  }
125
182
  function countSet(x) {
126
183
  if (x < 0)
@@ -133,9 +190,9 @@ function countSet(x) {
133
190
  t >>= BigInt(1 << k++);
134
191
  const n = 1 << k;
135
192
  const limit = 1n << BigInt(n);
136
- let i = 1;
137
- for (; i < k; i <<= 1) {
138
- const bi = BigInt(i);
193
+ let s = 1;
194
+ for (; s < k; s <<= 1) {
195
+ const bi = BigInt(s);
139
196
  const mask = limit / ((1n << bi) + 1n);
140
197
  x = (x & mask) + ((x >> bi) & mask);
141
198
  }
@@ -143,475 +200,688 @@ function countSet(x) {
143
200
  //const mask = limit / ((1n << bi) - 1n);
144
201
  //x = (x * mask) >> BigInt(n - i);
145
202
  //we can skip the masking when the total can fit
146
- for (; i < n; i <<= 1)
147
- x += x >> BigInt(i);
148
- return Number(x & 0xffffffffn);
203
+ for (; s < n; s <<= 1)
204
+ x += x >> BigInt(s);
205
+ return Number(x & ((1n << BigInt(k)) - 1n));
149
206
  }
207
+ function nthSet(x, i) {
208
+ if (x < 0)
209
+ x = ~x;
210
+ if (x < 0x100000000)
211
+ return nthSet32(Number(x), i);
212
+ x = BigInt(x);
213
+ let k = 5;
214
+ for (let t = x >> 32n; t;)
215
+ t >>= BigInt(1 << k++);
216
+ const limit = 1n << BigInt(1 << k);
217
+ const counts = [];
218
+ counts.push(x);
219
+ let s = 1;
220
+ for (; s < k; s <<= 1) {
221
+ const bi = BigInt(s);
222
+ const mask = limit / ((1n << bi) + 1n);
223
+ x = (x & mask) + ((x >> bi) & mask);
224
+ counts.push(x);
225
+ }
226
+ while (counts.length < k) {
227
+ x += x >> BigInt(s);
228
+ counts.push(x);
229
+ s <<= 1;
230
+ }
231
+ let n = 0;
232
+ for (let j = k; j--;) {
233
+ const s = 1 << j;
234
+ const b = Number((counts[j] >> BigInt(n)) & 0xffffffffn) & (s * 2 - 1);
235
+ if (i >= b) {
236
+ i -= b;
237
+ n += s;
238
+ }
239
+ }
240
+ return n;
241
+ }
242
+ // Returns the index of the highest clear bit
150
243
  function highestClear(x) {
151
244
  return highestSet(~x);
152
245
  }
246
+ // Returns the index of the lowest clear bit
153
247
  function lowestClear(x) {
154
248
  return lowestSet(~x);
155
249
  }
250
+ // Returns the number of clear bits
156
251
  function countClear(x) {
157
252
  return countSet(~x);
158
253
  }
254
+ function clearLowest(x) {
255
+ return typeof x === 'bigint' ? x & (x - 1n) : x & (x - 1);
256
+ }
159
257
  //-----------------------------------------------------------------------------
160
- // SparseBits - a sparse bitset implementation, where each entry in the 'bits' array represents 32 bits
161
- // The 'undef' member indicates whether undefined entries are treated as 0 or 0xffffffff
258
+ // DenseBits - a dense bitset implementation using bigint
162
259
  //-----------------------------------------------------------------------------
163
- class ImmutableSparseBits {
164
- bits = []; //each entry represents 32 bits
165
- undef;
166
- static *whereGenerator(bits, undef, set, from = -1) {
167
- ++from;
168
- if (undef ? !set : set) {
169
- const keys = Object.keys(bits).map(k => +k);
170
- if (keys.length === 0)
171
- return;
172
- const i = from >> 5;
173
- let k = (0, algorithm_1.lowerBound)(keys, i);
174
- let v = bits[keys[k]] ^ undef;
175
- if (keys[k] === i)
176
- v &= -(1 << (from & 0x1f));
177
- for (;;) {
178
- const i = keys[k];
179
- while (v) {
180
- yield (i << 5) + lowestSet32(v);
181
- v = v & (v - 1);
182
- }
183
- ++k;
184
- if (k === keys.length)
185
- return;
186
- v = bits[keys[k]] ^ undef;
187
- }
188
- }
189
- else {
190
- let i = from >> 5;
191
- let v = ((bits[i] ?? undef) ^ ~undef) & -(1 << (from & 0x1f));
192
- for (;;) {
193
- while (v) {
194
- yield (i << 5) + lowestSet32(v);
195
- v = v & (v - 1);
196
- }
197
- ++i;
198
- v = ((bits[i] ?? undef) ^ ~undef);
199
- }
200
- }
201
- }
202
- constructor(initial = false) {
203
- this.undef = initial ? -1 : 0;
204
- }
205
- create(init) {
206
- return new this.constructor(init);
260
+ class ImmutableDenseBits {
261
+ bits;
262
+ constructor(bits = 0n) {
263
+ this.bits = bits;
207
264
  }
208
- copyUndefined(other) {
209
- for (const i in other.bits) {
210
- if (this.bits[i] === undefined)
211
- this.bits[i] = other.bits[i];
212
- }
213
- return this;
265
+ create(bits) {
266
+ return new this.constructor(bits);
214
267
  }
215
- flipUndefined(other) {
216
- for (const i in other.bits) {
217
- if (this.bits[i] === undefined)
218
- this.bits[i] = ~other.bits[i];
219
- }
220
- return this;
268
+ get length() {
269
+ return highestSet(this.bits);
221
270
  }
222
- static fromEntries(entries, initial = false) {
223
- const r = new this(initial);
224
- if (Array.isArray(entries)) {
225
- for (const [k, v] of entries)
226
- r.bits[k] = v;
227
- }
228
- else {
229
- for (const [k, v] of Object.entries(entries))
230
- r.bits[+k] = v;
231
- }
232
- return r;
271
+ test(a) {
272
+ return !!(this.bits & (1n << BigInt(a)));
233
273
  }
234
- keys() {
235
- return Object.keys(this.bits).map(k => +k);
274
+ countSet() {
275
+ return countSet(this.bits);
236
276
  }
237
- entries() {
238
- //return this.bits;
239
- return Object.entries(this.bits).map(([k, v]) => [+k, v]);
277
+ nthSet(a) {
278
+ return nthSet(this.bits, a);
240
279
  }
241
280
  complement() {
242
- const result = this.create(this.undef === 0);
243
- for (const i in this.bits)
244
- result.bits[i] = ~this.bits[i];
245
- return result;
281
+ return this.create(~this.bits);
246
282
  }
247
283
  intersect(other) {
248
- const result = this.create(!!(this.undef & other.undef));
249
- for (const i in this.bits)
250
- result.bits[i] = this.bits[i] & other.bits[i];
251
- return this.undef ? result.copyUndefined(other) : result;
284
+ return this.create(this.bits & other.bits);
252
285
  }
253
286
  union(other) {
254
- const result = this.create(!!(this.undef | other.undef));
255
- for (const i in other.bits)
256
- result.bits[i] = this.bits[i] | other.bits[i];
257
- return this.undef ? result : result.copyUndefined(other);
287
+ return this.create(this.bits | other.bits);
258
288
  }
259
289
  xor(other) {
260
- const result = this.create(!!(this.undef ^ other.undef));
261
- for (const i in this.bits)
262
- result.bits[i] = this.bits[i] ^ other.bits[i];
263
- return this.undef ? result.flipUndefined(other) : result.copyUndefined(other);
264
- }
265
- clean() {
266
- for (const i in this.bits) {
267
- if (this.bits[i] === this.undef)
268
- delete this.bits[i];
269
- }
270
- return this;
290
+ return this.create(this.bits ^ other.bits);
271
291
  }
272
292
  contains(other) {
273
- if (other.undef && !this.undef)
274
- return false;
275
- for (const i in other.bits) {
276
- if (other.bits[i] & ~(this.bits[i] ?? this.undef))
277
- return false;
278
- }
279
- return true;
280
- }
281
- test(a) {
282
- return !!((this.bits[a >> 5] ?? this.undef) & (1 << (a & 0x1f)));
283
- }
284
- countSet() {
285
- let count = 0;
286
- for (const i in this.bits)
287
- count += countSet32(this.bits[i]);
288
- return count;
293
+ return (this.bits & other.bits) === other.bits;
289
294
  }
290
295
  next(a, set = true) {
291
- ++a;
292
- const xor = this.undef;
293
- if (xor)
294
- set = !set;
295
- if (set) {
296
- const keys = Object.keys(this.bits).map(k => +k);
297
- if (keys.length === 0)
298
- return -1;
299
- const ai = a >> 5;
300
- let i = (0, algorithm_1.lowerBound)(keys, ai);
301
- let v = this.bits[keys[i]] ^ xor;
302
- if (keys[i] === ai)
303
- v &= -(1 << (a & 0x1f));
304
- while (!v) {
305
- ++i;
306
- if (i === keys.length)
307
- return -1;
308
- v = this.bits[keys[i]] ^ xor;
309
- }
310
- return (keys[i] << 5) + lowestSet32(v);
311
- }
312
- else {
313
- let i = a >> 5;
314
- if (this.bits[i] === undefined)
315
- return a;
316
- let v = (this.bits[i] ^ xor) | ((1 << (a & 0x1f)) - 1);
317
- while (!v) {
318
- ++i;
319
- if (this.bits[i] === undefined)
320
- break;
321
- v = this.bits[i] ^ xor;
322
- }
323
- return (i << 5) + lowestSet32(~v);
324
- }
325
- }
326
- toDense() {
327
- let bits = 0n;
328
- if (this.undef) {
329
- for (const i in this.bits)
330
- bits |= BigInt(~this.bits[i]) << BigInt(+i * 32);
331
- bits = ~bits;
332
- }
333
- else {
334
- for (const i in this.bits)
335
- bits |= BigInt(this.bits[i]) << BigInt(+i * 32);
336
- }
337
- return new DenseBits(bits);
296
+ let s = this.bits >> BigInt(a + 1);
297
+ s = set ? s & -s : (s + 1n) & ~s;
298
+ return s ? a + highestSet(s) : -1;
338
299
  }
339
- where(set, from = -1) {
300
+ where(set, from = -1, to) {
301
+ let bits = this.bits >> BigInt(from + 1);
302
+ if (to !== undefined)
303
+ bits &= (1n << BigInt(to - from - 1)) - 1n;
340
304
  return {
341
- [Symbol.iterator]: () => ImmutableSparseBits.whereGenerator(this.bits, this.undef, set, from)
305
+ *[Symbol.iterator]() {
306
+ while (bits) {
307
+ const i = highestSet(set ? bits & -bits : (bits + 1n) & ~bits);
308
+ from += i;
309
+ yield from;
310
+ bits >>= BigInt(i);
311
+ }
312
+ }
342
313
  };
343
314
  }
344
315
  ranges() {
345
- const bits = this.bits;
346
- const undef = this.undef;
316
+ let bits = this.bits;
347
317
  return {
348
318
  *[Symbol.iterator]() {
349
- let start = -1, end = 0;
350
- for (const i in bits) {
351
- let b = bits[i] ^ undef;
352
- const c0 = +i * 32;
353
- while ((start < 0 ? b : ~b) !== 0) {
354
- if (start === -1) {
355
- start = c0 + lowestSet32(b);
356
- if (undef)
357
- yield [end, start];
358
- end = -1;
359
- b = b | (b - 1);
360
- }
361
- else {
362
- end = c0 + lowestSet32(~b);
363
- if (!undef)
364
- yield [start, end];
365
- start = -1;
366
- b = b & (b + 1);
367
- }
368
- }
369
- if (start >= 0 && bits[+i + 1] === undefined) {
370
- if (!undef)
371
- yield [start, c0 + 32];
372
- start = -1;
373
- }
319
+ let offset = 0;
320
+ while (bits) {
321
+ const i = highestSet(bits & -bits);
322
+ bits >>= BigInt(i);
323
+ const j = highestSet(~bits & (bits + 1n));
324
+ bits >>= BigInt(j);
325
+ yield [offset + i - 1, offset + i + j - 1];
326
+ offset += i + j;
374
327
  }
375
- if (undef)
376
- yield [end, Infinity];
377
328
  }
378
329
  };
379
330
  }
380
331
  *[Symbol.iterator]() {
381
- yield* ImmutableSparseBits.whereGenerator(this.bits, this.undef, true, -1);
382
- //for (let i = this.next(-1); i !== -1; i = this.next(i))
383
- // yield i;
332
+ yield* this.where(true);
333
+ }
334
+ toSparse() {
335
+ const sparse = {};
336
+ for (let bits = this.bits, i = 0; bits; bits >>= 32n, i++) {
337
+ const v = Number(bits & 0xffffffffn);
338
+ if (v)
339
+ sparse[i] = v;
340
+ }
341
+ return SparseBits2.fromEntries(sparse, false);
342
+ }
343
+ slice(from, to) {
344
+ return to === undefined
345
+ ? this.create(this.bits >> BigInt(from))
346
+ : this.create(this.bits >> BigInt(from) & ((1n << BigInt(to - from)) - 1n));
384
347
  }
385
348
  }
386
- exports.ImmutableSparseBits = ImmutableSparseBits;
387
- class SparseBits extends ImmutableSparseBits {
388
- setMask(i, m) {
389
- if (this.bits[i] !== undefined)
390
- this.bits[i] |= m;
391
- else if (!this.undef)
392
- this.bits[i] = m;
393
- }
394
- clearMask(i, m) {
395
- if (this.bits[i] !== undefined)
396
- this.bits[i] &= ~m;
397
- else if (this.undef)
398
- this.bits[i] = ~m;
349
+ exports.ImmutableDenseBits = ImmutableDenseBits;
350
+ ;
351
+ class DenseBits extends ImmutableDenseBits {
352
+ setMask(m) {
353
+ this.bits |= m;
354
+ }
355
+ clearMask(m) {
356
+ this.bits &= ~m;
357
+ }
358
+ set(a) {
359
+ this.setMask(1n << BigInt(a));
360
+ }
361
+ clear(a) {
362
+ this.clearMask(1n << BigInt(a));
363
+ }
364
+ setRange(a, b) {
365
+ this.setMask((1n << BigInt(b)) - (1n << BigInt(a)));
366
+ return this;
367
+ }
368
+ clearRange(a, b) {
369
+ this.clearMask((1n << BigInt(b)) - (1n << BigInt(a)));
370
+ return this;
399
371
  }
400
372
  selfComplement() {
401
- this.undef = ~this.undef;
402
- for (const i in this.bits)
403
- this.bits[i] = ~this.bits[i];
373
+ this.bits = ~this.bits;
404
374
  return this;
405
375
  }
406
376
  selfIntersect(other) {
407
- for (const i in this.bits)
408
- this.bits[i] &= other.bits[i];
409
- if (this.undef)
410
- this.copyUndefined(other);
411
- this.undef &= other.undef;
377
+ this.bits &= other.bits;
412
378
  return this;
413
379
  }
414
380
  selfUnion(other) {
415
- for (const i in other.bits)
416
- this.bits[i] |= other.bits[i];
417
- if (!this.undef)
418
- this.copyUndefined(other);
419
- this.undef |= other.undef;
381
+ this.bits |= other.bits;
420
382
  return this;
421
383
  }
422
384
  selfXor(other) {
423
- for (const i in this.bits)
424
- this.bits[i] ^= other.bits[i];
425
- if (this.undef)
426
- this.flipUndefined(other);
427
- else
428
- this.copyUndefined(other);
429
- this.undef &= other.undef;
385
+ this.bits ^= other.bits;
430
386
  return this;
431
387
  }
432
- set(a) {
433
- this.setMask(a >> 5, 1 << (a & 0x1f));
388
+ }
389
+ exports.DenseBits = DenseBits;
390
+ ;
391
+ //-----------------------------------------------------------------------------
392
+ // SparseBits - a sparse bitset implementation, where each entry in the 'bits' array represents 32 bits
393
+ //-----------------------------------------------------------------------------
394
+ function sparseFromEntries(entries) {
395
+ const dest = [];
396
+ if (Array.isArray(entries)) {
397
+ for (const [k, v] of entries)
398
+ dest[k] = v;
434
399
  }
435
- clear(a) {
436
- this.clearMask(a >> 5, 1 << (a & 0x1f));
400
+ else {
401
+ for (const [k, v] of Object.entries(entries))
402
+ dest[+k] = v;
437
403
  }
438
- test(a) {
439
- const i = a >> 5;
440
- return !!((this.bits[i] ?? this.undef) & (1 << (a & 0x1f)));
404
+ return dest;
405
+ }
406
+ function sparseCopyUndefined(bits, other, xor = 0) {
407
+ for (const i in other) {
408
+ if (bits[i] === undefined)
409
+ bits[i] = other[i] ^ xor;
441
410
  }
442
- setRange(a, b) {
443
- let i = a >> 5, j = b >> 5;
444
- if (i === j) {
445
- this.setMask(i, (1 << (b & 0x1f)) - (1 << (a & 0x1f)));
411
+ return bits;
412
+ }
413
+ function sparseClean(bits, undef = 0) {
414
+ for (const i in bits) {
415
+ if (bits[i] === undef)
416
+ delete bits[i];
417
+ }
418
+ }
419
+ function sparseTest(bits, a, undef = 0) {
420
+ return !!((bits[a >> 5] ?? undef) & (1 << (a & 0x1f)));
421
+ }
422
+ function sparseSetMask(bits, i, m, undef = 0) {
423
+ if (bits[i] !== undefined)
424
+ bits[i] |= m;
425
+ else if (!undef)
426
+ bits[i] = m;
427
+ }
428
+ function sparseClearMask(bits, i, m, undef = 0) {
429
+ if (bits[i] !== undefined)
430
+ bits[i] &= ~m;
431
+ else if (undef)
432
+ bits[i] = ~m;
433
+ }
434
+ function sparseSetRange(bits, a, b, undef = 0) {
435
+ let i = a >> 5, j = b >> 5;
436
+ if (i === j) {
437
+ sparseSetMask(bits, i, (1 << (b & 0x1f)) - (1 << (a & 0x1f)), undef);
438
+ }
439
+ else {
440
+ sparseSetMask(bits, i++, -(1 << (a & 0x1f)), undef);
441
+ if (undef) {
442
+ while (i < j)
443
+ delete bits[i++];
444
+ }
445
+ else {
446
+ while (i < j)
447
+ bits[i++] = -1;
448
+ }
449
+ sparseSetMask(bits, i, (1 << (b & 0x1f)) - 1, undef);
450
+ }
451
+ }
452
+ function sparseClearRange(bits, a, b, undef = 0) {
453
+ let i = a >> 5, j = b >> 5;
454
+ if (i === j) {
455
+ sparseClearMask(bits, i, (1 << (b & 0x1f)) - (1 << (a & 0x1f)), undef);
456
+ }
457
+ else {
458
+ sparseClearMask(bits, i++, -(1 << (a & 0x1f)), undef);
459
+ if (!undef) {
460
+ while (i < j)
461
+ delete bits[i++];
446
462
  }
447
463
  else {
448
- this.setMask(i++, -(1 << (a & 0x1f)));
449
- if (this.undef) {
450
- while (i < j)
451
- delete this.bits[i++];
464
+ while (i < j)
465
+ bits[i++] = 0;
466
+ }
467
+ sparseClearMask(bits, i, (1 << (b & 0x1f)) - 1, undef);
468
+ }
469
+ }
470
+ function sparseCountSet(bits) {
471
+ let count = 0;
472
+ for (const i in bits)
473
+ count += countSet32(bits[i]);
474
+ return count;
475
+ }
476
+ function sparseNthSet(bits, a, undef = 0) {
477
+ if (undef === 0) {
478
+ for (const i in bits) {
479
+ const v = bits[i];
480
+ const n = countSet32(v);
481
+ if (a < n)
482
+ return (+i << 5) + nthSet32(v, a);
483
+ a -= n;
484
+ }
485
+ }
486
+ else {
487
+ let prev = 0;
488
+ for (const i in bits) {
489
+ const m = (+i - prev) << 5;
490
+ if (a < m)
491
+ return (prev << 5) + a;
492
+ a -= m;
493
+ const v = bits[i];
494
+ const n = countSet32(v);
495
+ if (a < n)
496
+ return (+i << 5) + nthSet32(v, a);
497
+ a -= n;
498
+ prev = +i + 1;
499
+ }
500
+ }
501
+ return -1;
502
+ }
503
+ function sparseComplement(bits) {
504
+ return bits.map(b => ~b);
505
+ }
506
+ function sparseIntersect(bits, other, undef = 0) {
507
+ return bits.map((b, i) => b & (other[i] ?? undef));
508
+ }
509
+ function sparseUnion(bits, other, undef = 0) {
510
+ return bits.map((b, i) => b | (other[i] ?? undef));
511
+ }
512
+ function sparseXor(bits, other, undef = 0) {
513
+ return bits.map((b, i) => b ^ (other[i] ?? undef));
514
+ }
515
+ function sparseSelfComplement(bits) {
516
+ for (const i in bits)
517
+ bits[i] = ~bits[i];
518
+ return bits;
519
+ }
520
+ function sparseSelfIntersect(bits, other) {
521
+ for (const i in bits)
522
+ bits[i] &= other[i];
523
+ return bits;
524
+ }
525
+ function sparseSelfUnion(bits, other) {
526
+ for (const i in bits)
527
+ bits[i] |= other[i];
528
+ return bits;
529
+ }
530
+ function sparseSelfXor(bits, other) {
531
+ for (const i in bits)
532
+ bits[i] ^= other[i];
533
+ return bits;
534
+ }
535
+ function sparseContains(bits, other, undef = 0) {
536
+ for (const i in other) {
537
+ if (other[i] & ~(bits[i] ?? undef))
538
+ return false;
539
+ }
540
+ return true;
541
+ }
542
+ function sparseNext(bits, from, set = true, undef = 0) {
543
+ ++from;
544
+ if (undef ? !set : set) {
545
+ const ai = from >> 5;
546
+ for (const i in bits) {
547
+ if (+i >= ai) {
548
+ const v = bits[i] ^ undef;
549
+ if (v)
550
+ return (+i << 5) + lowestSet32(v);
452
551
  }
453
- else {
454
- while (i < j)
455
- this.bits[i++] = -1;
552
+ }
553
+ return -1;
554
+ }
555
+ else {
556
+ let i = from >> 5;
557
+ if (bits[i] === undefined)
558
+ return from;
559
+ let v = (bits[i] ^ undef) | ((1 << (from & 0x1f)) - 1);
560
+ while (!v) {
561
+ ++i;
562
+ if (bits[i] === undefined)
563
+ break;
564
+ v = bits[i] ^ undef;
565
+ }
566
+ return (i << 5) + lowestSet32(~v);
567
+ }
568
+ }
569
+ function* sparseWhere(bits, set, from = -1, to, undef = 0) {
570
+ ++from;
571
+ const from32 = from >> 5;
572
+ const to32 = to === undefined ? Infinity : to >> 5;
573
+ const fromM = 1 << (from & 0x1f);
574
+ const toM = to === undefined ? 0 : 1 << (to & 0x1f);
575
+ if (undef ? !set : set) {
576
+ for (const k in bits) {
577
+ const i = +k;
578
+ if (i >= to32)
579
+ break;
580
+ if (i >= from32) {
581
+ let v = bits[i] ^ undef;
582
+ if (i === from32)
583
+ v &= -fromM;
584
+ if (i === to32)
585
+ v &= (toM - 1);
586
+ while (v) {
587
+ yield (i << 5) + lowestSet32(v);
588
+ v = v & (v - 1);
589
+ }
456
590
  }
457
- this.setMask(i, (1 << (b & 0x1f)) - 1);
458
591
  }
459
- return this;
460
592
  }
461
- clearRange(a, b) {
462
- let i = a >> 5, j = b >> 5;
463
- if (i === j) {
464
- this.clearMask(i, (1 << (b & 0x1f)) - (1 << (a & 0x1f)));
593
+ else {
594
+ if (to32 > from32) {
595
+ for (let v = ((bits[from32] ?? undef) ^ ~undef) & -fromM; v; v = v & (v - 1))
596
+ yield (from32 << 5) + lowestSet32(v);
597
+ for (let i = from32 + 1; i < to32; i++) {
598
+ for (let v = ((bits[i] ?? undef) ^ ~undef); v; v = v & (v - 1))
599
+ yield (i << 5) + lowestSet32(v);
600
+ }
601
+ for (let v = ((bits[to32] ?? undef) ^ ~undef) & (toM - 1); v; v = v & (v - 1))
602
+ yield (to32 << 5) + lowestSet32(v);
465
603
  }
466
- else {
467
- this.clearMask(i++, -(1 << (a & 0x1f)));
468
- if (!this.undef) {
469
- while (i < j)
470
- delete this.bits[i++];
604
+ else if (to32 === from32) {
605
+ for (let v = ((bits[from32] ?? undef) ^ ~undef) & (toM - fromM); v; v = v & (v - 1))
606
+ yield (from32 << 5) + lowestSet32(v);
607
+ }
608
+ }
609
+ }
610
+ function* sparseRanges(bits, undef = 0) {
611
+ let start = -1, end = 0;
612
+ for (const i in bits) {
613
+ let b = bits[i] ^ undef;
614
+ const c0 = +i * 32;
615
+ while ((start < 0 ? b : ~b) !== 0) {
616
+ if (start === -1) {
617
+ start = c0 + lowestSet32(b);
618
+ if (undef)
619
+ yield [end, start];
620
+ end = -1;
621
+ b = b | (b - 1);
471
622
  }
472
623
  else {
473
- while (i < j)
474
- this.bits[i++] = 0;
624
+ end = c0 + lowestSet32(~b);
625
+ if (!undef)
626
+ yield [start, end];
627
+ start = -1;
628
+ b = b & (b + 1);
475
629
  }
476
- this.clearMask(i, (1 << (b & 0x1f)) - 1);
477
630
  }
478
- return this;
631
+ if (start >= 0 && bits[+i + 1] === undefined) {
632
+ if (!undef)
633
+ yield [start, c0 + 32];
634
+ start = -1;
635
+ }
479
636
  }
637
+ if (undef)
638
+ yield [end, Infinity];
480
639
  }
481
- exports.SparseBits = SparseBits;
482
- ;
483
- //-----------------------------------------------------------------------------
484
- // DenseBits - a dense bitset implementation using bigint
485
- //-----------------------------------------------------------------------------
486
- class ImmutableDenseBits {
640
+ function sparseSlice(bits, from, to) {
641
+ const from32 = from >> 5;
642
+ const to32 = to === undefined ? Infinity : to >> 5;
643
+ const fromBit = from & 0x1f;
644
+ const toBit = to === undefined ? 0 : to & 0x1f;
645
+ const result = [];
646
+ for (const i in bits) {
647
+ const idx = +i;
648
+ if (idx < from32 || idx > to32)
649
+ continue;
650
+ let b = bits[i];
651
+ // Mask start bits
652
+ if (idx === from32)
653
+ b &= -(1 << fromBit);
654
+ // Mask end bits
655
+ if (idx === to32 && to !== undefined)
656
+ b &= (1 << toBit) - 1;
657
+ if (b !== 0)
658
+ result[i] = b;
659
+ }
660
+ return result;
661
+ }
662
+ class ImmutableSparseBits {
487
663
  bits;
488
- constructor(bits = 0n) {
664
+ constructor(bits = []) {
489
665
  this.bits = bits;
490
666
  }
491
- create(bits) {
667
+ create(bits = []) {
492
668
  return new this.constructor(bits);
493
669
  }
670
+ static fromEntries(entries, ...args) {
671
+ const r = new this(...args);
672
+ r.bits = sparseFromEntries(entries);
673
+ return r;
674
+ }
675
+ keys() {
676
+ return Object.keys(this.bits).map(k => +k);
677
+ }
678
+ entries() {
679
+ return Object.entries(this.bits).map(([k, v]) => [+k, v]);
680
+ }
681
+ test(a) {
682
+ return sparseTest(this.bits, a);
683
+ }
684
+ countSet() {
685
+ return sparseCountSet(this.bits);
686
+ }
687
+ nthSet(a) {
688
+ return sparseNthSet(this.bits, a);
689
+ }
494
690
  complement() {
495
- return this.create(~this.bits);
691
+ return new ImmutableSparseBits2(sparseComplement(this.bits), true);
496
692
  }
497
693
  intersect(other) {
498
- return this.create(this.bits & other.bits);
694
+ return this.create(sparseIntersect(this.bits, other.bits));
499
695
  }
500
696
  union(other) {
501
- return this.create(this.bits | other.bits);
697
+ return this.create(sparseCopyUndefined(sparseUnion(this.bits, other.bits), other.bits));
502
698
  }
503
699
  xor(other) {
504
- return this.create(this.bits ^ other.bits);
505
- }
506
- test(a) {
507
- return !!(this.bits & (1n << BigInt(a)));
700
+ return this.create(sparseCopyUndefined(sparseXor(this.bits, other.bits), other.bits));
508
701
  }
509
702
  contains(other) {
510
- return (this.bits & other.bits) === other.bits;
703
+ return sparseContains(this.bits, other.bits);
511
704
  }
512
- next(a, set = true) {
513
- let s = this.bits >> BigInt(a + 1);
514
- s = set ? s & -s : (s + 1n) & ~s;
515
- return s ? a + highestSet(s) : -1;
516
- }
517
- countSet() {
518
- return countSet(this.bits);
519
- }
520
- get length() {
521
- return highestSet(this.bits);
705
+ next(from, set = true) {
706
+ return sparseNext(this.bits, from, set);
522
707
  }
523
- where(set, from = -1) {
524
- let bits = this.bits >> BigInt(from + 1);
525
- return {
526
- *[Symbol.iterator]() {
527
- while (bits) {
528
- const i = highestSet(set ? bits & -bits : (bits + 1n) & ~bits);
529
- from += i;
530
- yield from;
531
- bits >>= BigInt(i);
532
- }
533
- }
534
- };
535
- /*
536
- const self = this;
708
+ where(set, from = -1, to) {
537
709
  return {
538
- *[Symbol.iterator](): Generator<number> {
539
- for (let i = self.next(-1, set); i !== -1; i = self.next(i, set))
540
- yield i;
541
- }
710
+ [Symbol.iterator]: () => sparseWhere(this.bits, set, from, to)
542
711
  };
543
- */
544
712
  }
545
713
  ranges() {
546
- let bits = this.bits;
547
714
  return {
548
- *[Symbol.iterator]() {
549
- let offset = 0;
550
- while (bits) {
551
- const i = highestSet(bits & -bits);
552
- bits >>= BigInt(i);
553
- const j = highestSet(~bits & (bits + 1n));
554
- bits >>= BigInt(j);
555
- yield [offset + i - 1, offset + i + j - 1];
556
- offset += i + j;
557
- }
558
- }
715
+ [Symbol.iterator]: () => sparseRanges(this.bits)
559
716
  };
560
717
  }
561
718
  *[Symbol.iterator]() {
562
- yield* this.where(true);
563
- //for (let i = this.next(-1); i !== -1; i = this.next(i))
564
- // yield i;
719
+ yield* sparseWhere(this.bits, true, -1);
565
720
  }
566
- toSparse() {
567
- const sparse = {};
568
- for (let bits = this.bits, i = 0; bits; bits >>= 32n, i++) {
569
- const v = Number(bits & 0xffffffffn);
570
- if (v)
571
- sparse[i] = v;
572
- }
573
- return SparseBits.fromEntries(sparse, false);
721
+ clean() {
722
+ sparseClean(this.bits);
723
+ return this;
724
+ }
725
+ toDense() {
726
+ let bits = 0n;
727
+ for (const i in this.bits)
728
+ bits |= BigInt(this.bits[i]) << BigInt(+i * 32);
729
+ return new DenseBits(bits);
730
+ }
731
+ slice(from, to) {
732
+ return this.create(sparseSlice(this.bits, from, to));
574
733
  }
575
734
  }
576
- exports.ImmutableDenseBits = ImmutableDenseBits;
577
- ;
578
- class DenseBits extends ImmutableDenseBits {
579
- setMask(m) {
580
- this.bits |= m;
735
+ exports.ImmutableSparseBits = ImmutableSparseBits;
736
+ class SparseBits extends ImmutableSparseBits {
737
+ set(a) {
738
+ sparseSetMask(this.bits, a >> 5, 1 << (a & 0x1f));
581
739
  }
582
- clearMask(m) {
583
- this.bits &= ~m;
740
+ clear(a) {
741
+ sparseClearMask(this.bits, a >> 5, 1 << (a & 0x1f));
584
742
  }
585
- selfComplement() {
586
- this.bits = ~this.bits;
743
+ setRange(a, b) {
744
+ sparseSetRange(this.bits, a, b);
745
+ return this;
746
+ }
747
+ clearRange(a, b) {
748
+ sparseClearRange(this.bits, a, b);
587
749
  return this;
588
750
  }
589
751
  selfIntersect(other) {
590
- this.bits &= other.bits;
752
+ sparseSelfIntersect(this.bits, other.bits);
591
753
  return this;
592
754
  }
593
755
  selfUnion(other) {
594
- this.bits |= other.bits;
756
+ sparseCopyUndefined(sparseSelfUnion(this.bits, other.bits), other.bits);
595
757
  return this;
596
758
  }
597
759
  selfXor(other) {
598
- this.bits ^= other.bits;
760
+ sparseCopyUndefined(sparseSelfXor(this.bits, other.bits), other.bits);
761
+ return this;
762
+ }
763
+ }
764
+ exports.SparseBits = SparseBits;
765
+ ;
766
+ //-----------------------------------------------------------------------------
767
+ // SparseBits2 as above, with an 'undef' member indicating whether undefined entries are treated as 0 or 0xffffffff
768
+ //-----------------------------------------------------------------------------
769
+ class ImmutableSparseBits2 extends ImmutableSparseBits {
770
+ undef;
771
+ constructor(bits = [], initial = false) {
772
+ super(bits);
773
+ this.undef = initial ? -1 : 0;
774
+ }
775
+ create(bits = [], init) {
776
+ return new this.constructor(bits, init);
777
+ }
778
+ test(a) {
779
+ return sparseTest(this.bits, a, this.undef);
780
+ }
781
+ nthSet(a) {
782
+ return sparseNthSet(this.bits, a, this.undef);
783
+ }
784
+ complement() {
785
+ return this.create(sparseComplement(this.bits), this.undef === 0);
786
+ }
787
+ intersect(other) {
788
+ if (this.undef)
789
+ return this.create(sparseCopyUndefined(sparseIntersect(this.bits, other.bits, other.undef), other.bits), !!other.undef);
790
+ return this.create(sparseIntersect(this.bits, other.bits), false);
791
+ }
792
+ union(other) {
793
+ if (this.undef)
794
+ return this.create(sparseUnion(this.bits, other.bits), true);
795
+ return this.create(sparseCopyUndefined(sparseUnion(this.bits, other.bits), other.bits), !!other.undef);
796
+ }
797
+ xor(other) {
798
+ return this.create(sparseCopyUndefined(sparseXor(this.bits, other.bits), other.bits, this.undef), !!(this.undef ^ other.undef));
799
+ }
800
+ contains(other) {
801
+ if (other.undef && !this.undef)
802
+ return false;
803
+ return sparseContains(this.bits, other.bits, this.undef);
804
+ }
805
+ next(from, set = true) {
806
+ return sparseNext(this.bits, from, set, this.undef);
807
+ }
808
+ where(set, from = -1, to) {
809
+ return {
810
+ [Symbol.iterator]: () => sparseWhere(this.bits, set, from, to, this.undef)
811
+ };
812
+ }
813
+ ranges() {
814
+ return {
815
+ [Symbol.iterator]: () => sparseRanges(this.bits, this.undef)
816
+ };
817
+ }
818
+ *[Symbol.iterator]() {
819
+ yield* sparseWhere(this.bits, true, -1, undefined, this.undef);
820
+ }
821
+ clean() {
822
+ sparseClean(this.bits, this.undef);
599
823
  return this;
600
824
  }
825
+ toDense() {
826
+ let bits = 0n;
827
+ if (this.undef) {
828
+ for (const i in this.bits)
829
+ bits |= BigInt(~this.bits[i]) << BigInt(+i * 32);
830
+ bits = ~bits;
831
+ }
832
+ else {
833
+ for (const i in this.bits)
834
+ bits |= BigInt(this.bits[i]) << BigInt(+i * 32);
835
+ }
836
+ return new DenseBits(bits);
837
+ }
838
+ slice(from, to) {
839
+ return this.create(sparseSlice(this.bits, from, to), !!this.undef);
840
+ }
841
+ }
842
+ exports.ImmutableSparseBits2 = ImmutableSparseBits2;
843
+ class SparseBits2 extends ImmutableSparseBits2 {
601
844
  set(a) {
602
- this.setMask(1n << BigInt(a));
845
+ sparseSetMask(this.bits, a >> 5, 1 << (a & 0x1f), this.undef);
603
846
  }
604
847
  clear(a) {
605
- this.clearMask(1n << BigInt(a));
848
+ sparseClearMask(this.bits, a >> 5, 1 << (a & 0x1f), this.undef);
606
849
  }
607
850
  setRange(a, b) {
608
- this.setMask((1n << BigInt(b)) - (1n << BigInt(a)));
851
+ sparseSetRange(this.bits, a, b, this.undef);
609
852
  return this;
610
853
  }
611
854
  clearRange(a, b) {
612
- this.clearMask((1n << BigInt(b)) - (1n << BigInt(a)));
855
+ sparseClearRange(this.bits, a, b, this.undef);
856
+ return this;
857
+ }
858
+ selfComplement() {
859
+ this.undef = ~this.undef;
860
+ sparseSelfComplement(this.bits);
861
+ return this;
862
+ }
863
+ selfIntersect(other) {
864
+ sparseSelfIntersect(this.bits, other.bits);
865
+ if (this.undef) {
866
+ sparseCopyUndefined(this.bits, other.bits);
867
+ this.undef = other.undef;
868
+ }
869
+ return this;
870
+ }
871
+ selfUnion(other) {
872
+ sparseSelfUnion(this.bits, other.bits);
873
+ if (!this.undef) {
874
+ sparseCopyUndefined(this.bits, other.bits);
875
+ this.undef = other.undef;
876
+ }
877
+ return this;
878
+ }
879
+ selfXor(other) {
880
+ sparseSelfXor(this.bits, other.bits);
881
+ sparseCopyUndefined(this.bits, other.bits, this.undef);
882
+ this.undef ^= other.undef;
613
883
  return this;
614
884
  }
615
885
  }
616
- exports.DenseBits = DenseBits;
886
+ exports.SparseBits2 = SparseBits2;
617
887
  ;