@cloudbitmaps/roaring 0.23.0 → 0.24.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.
package/dist/index.js CHANGED
@@ -16,7 +16,7 @@ import {
16
16
  MAX_LEASE_MS,
17
17
  NotFoundError,
18
18
  UnsupportedError as UnsupportedError2,
19
- ValidationError as ValidationError5,
19
+ ValidationError as ValidationError6,
20
20
  errorKind,
21
21
  WriteConflictError,
22
22
  checkBudget,
@@ -120,8 +120,10 @@ function refuseReservedNamespace(namespace) {
120
120
  }
121
121
 
122
122
  // src/roaring-codec.ts
123
- import roaring from "roaring";
124
- import { IntegrityError as IntegrityError2, ValidationError as ValidationError2, decodeSerialized } from "@cloudbitmaps/core";
123
+ import { ValidationError as ValidationError3, decodeSerialized } from "@cloudbitmaps/core";
124
+
125
+ // src/ts-roaring/bitmap.ts
126
+ import { IntegrityError as IntegrityError3, ValidationError as ValidationError2 } from "@cloudbitmaps/core";
125
127
 
126
128
  // src/portable/layout.ts
127
129
  import { IntegrityError } from "@cloudbitmaps/core";
@@ -139,45 +141,10 @@ function overrun(bytes, offset, length, what) {
139
141
  `portable roaring: ${what} needs bytes [${offset}, ${offset + length}) of a ${bytes.byteLength}-byte buffer`
140
142
  );
141
143
  }
142
- function checkPortableLayout(bytes) {
143
- return walk(bytes, null);
144
- }
145
- var SINGLE_HEADER_BYTES = 16;
146
- var SINGLE_RUN_HEADER_BYTES = 9;
147
- function* containerPayloads(bytes) {
148
- if (bytes.byteLength === 0) return;
149
- const { view, count, runFlagsAt, descriptiveAt, bodiesAt } = header(bytes);
150
- let pos = bodiesAt;
151
- let previousKey = -1;
152
- for (let i = 0; i < count; i++) {
153
- const key = view.getUint16(descriptiveAt + i * 4, true);
154
- if (key <= previousKey) {
155
- throw new IntegrityError(
156
- `portable roaring: container keys are not strictly ascending (${previousKey} then ${key} at index ${i})`
157
- );
158
- }
159
- previousKey = key;
160
- const cardinality = view.getUint16(descriptiveAt + i * 4 + 2, true) + 1;
161
- const isRun = runFlagsAt >= 0 && (bytes[runFlagsAt + (i >>> 3)] & 1 << (i & 7)) !== 0;
162
- const kind = isRun ? RUN : cardinality > ARRAY_MAX_CARDINALITY ? BITMAP : ARRAY;
163
- const size = checkContainer(bytes, view, pos, kind, cardinality, i);
164
- const headerBytes = isRun ? SINGLE_RUN_HEADER_BYTES : SINGLE_HEADER_BYTES;
165
- const payload = new Uint8Array(headerBytes + size);
166
- const out = new DataView(payload.buffer);
167
- if (isRun) {
168
- out.setUint32(0, SERIAL_COOKIE, true);
169
- payload[4] = 1;
170
- out.setUint16(7, cardinality - 1, true);
171
- } else {
172
- out.setUint32(0, SERIAL_COOKIE_NO_RUNCONTAINER, true);
173
- out.setUint32(4, 1, true);
174
- out.setUint16(10, cardinality - 1, true);
175
- out.setUint32(12, SINGLE_HEADER_BYTES, true);
176
- }
177
- payload.set(bytes.subarray(pos, pos + size), headerBytes);
178
- pos += size;
179
- yield { chunkKey: key, payload, cardinality };
180
- }
144
+ function parsePortableLayout(bytes) {
145
+ const containers = [];
146
+ walk(bytes, containers);
147
+ return containers;
181
148
  }
182
149
  function header(bytes) {
183
150
  const length = bytes.byteLength;
@@ -328,159 +295,1579 @@ function popcount(view, at) {
328
295
  return bits;
329
296
  }
330
297
 
331
- // src/roaring-codec.ts
332
- var { RoaringBitmap32, SerializationFormat, DeserializationFormat } = roaring;
333
- var SafeBitmap = class _SafeBitmap {
334
- bitmap;
335
- constructor(bitmap) {
336
- this.bitmap = bitmap;
298
+ // src/ts-roaring/containers.ts
299
+ var ARRAY2 = 0;
300
+ var BITSET = 1;
301
+ var RUN2 = 2;
302
+ var WORDS = 2048;
303
+ var BITSET_BYTES = 8192;
304
+ var GALLOP_SKEW = 16;
305
+ var LITTLE_ENDIAN = new Uint8Array(Uint16Array.of(1).buffer)[0] === 1;
306
+ var Container = class {
307
+ constructor(kind, data, off, len, card, shared) {
308
+ this.kind = kind;
309
+ this.data = data;
310
+ this.off = off;
311
+ this.len = len;
312
+ this.card = card;
313
+ this.shared = shared;
314
+ }
315
+ kind;
316
+ data;
317
+ off;
318
+ len;
319
+ card;
320
+ shared;
321
+ };
322
+ function lows16(c) {
323
+ return c.data;
324
+ }
325
+ function words32(c) {
326
+ return c.data;
327
+ }
328
+ function arrayContainer(values, card) {
329
+ return new Container(ARRAY2, values, 0, card, card, false);
330
+ }
331
+ function bitsetContainer(words, card) {
332
+ return new Container(BITSET, words, 0, 0, card, false);
333
+ }
334
+ function runContainer(pairs, runs, card) {
335
+ return new Container(RUN2, pairs, 0, runs, card, false);
336
+ }
337
+ var valueScratch = new Uint16Array(8192);
338
+ var pairScratch = new Uint16Array(8192);
339
+ var SCRATCH_KEEP = 65536;
340
+ function values16(n) {
341
+ if (valueScratch.length >= n) return valueScratch;
342
+ if (n > SCRATCH_KEEP) return new Uint16Array(n);
343
+ valueScratch = new Uint16Array(Math.max(n, Math.min(2 * valueScratch.length, SCRATCH_KEEP)));
344
+ return valueScratch;
345
+ }
346
+ function pairs16(n) {
347
+ if (pairScratch.length >= n) return pairScratch;
348
+ if (n > SCRATCH_KEEP) return new Uint16Array(n);
349
+ pairScratch = new Uint16Array(Math.max(n, Math.min(2 * pairScratch.length, SCRATCH_KEEP)));
350
+ return pairScratch;
351
+ }
352
+ function arrayOfScratch(scratch, n) {
353
+ return n === 0 ? null : arrayContainer(scratch.slice(0, n), n);
354
+ }
355
+ function popcount32(word) {
356
+ let w = word - (word >>> 1 & 1431655765);
357
+ w = (w & 858993459) + (w >>> 2 & 858993459);
358
+ return Math.imul(w + (w >>> 4) & 252645135, 16843009) >>> 24;
359
+ }
360
+ function popcountWords(d) {
361
+ let total = 0;
362
+ let ones = 0;
363
+ let twos = 0;
364
+ let fours = 0;
365
+ let eights = 0;
366
+ for (let i = 0; i < WORDS; i += 16) {
367
+ let u;
368
+ let twosA;
369
+ let twosB;
370
+ let foursA;
371
+ let foursB;
372
+ let x = d[i];
373
+ let y = d[i + 1];
374
+ u = ones ^ x;
375
+ twosA = ones & x | u & y;
376
+ ones = u ^ y;
377
+ x = d[i + 2];
378
+ y = d[i + 3];
379
+ u = ones ^ x;
380
+ twosB = ones & x | u & y;
381
+ ones = u ^ y;
382
+ u = twos ^ twosA;
383
+ foursA = twos & twosA | u & twosB;
384
+ twos = u ^ twosB;
385
+ x = d[i + 4];
386
+ y = d[i + 5];
387
+ u = ones ^ x;
388
+ twosA = ones & x | u & y;
389
+ ones = u ^ y;
390
+ x = d[i + 6];
391
+ y = d[i + 7];
392
+ u = ones ^ x;
393
+ twosB = ones & x | u & y;
394
+ ones = u ^ y;
395
+ u = twos ^ twosA;
396
+ foursB = twos & twosA | u & twosB;
397
+ twos = u ^ twosB;
398
+ u = fours ^ foursA;
399
+ const eightsA = fours & foursA | u & foursB;
400
+ fours = u ^ foursB;
401
+ x = d[i + 8];
402
+ y = d[i + 9];
403
+ u = ones ^ x;
404
+ twosA = ones & x | u & y;
405
+ ones = u ^ y;
406
+ x = d[i + 10];
407
+ y = d[i + 11];
408
+ u = ones ^ x;
409
+ twosB = ones & x | u & y;
410
+ ones = u ^ y;
411
+ u = twos ^ twosA;
412
+ foursA = twos & twosA | u & twosB;
413
+ twos = u ^ twosB;
414
+ x = d[i + 12];
415
+ y = d[i + 13];
416
+ u = ones ^ x;
417
+ twosA = ones & x | u & y;
418
+ ones = u ^ y;
419
+ x = d[i + 14];
420
+ y = d[i + 15];
421
+ u = ones ^ x;
422
+ twosB = ones & x | u & y;
423
+ ones = u ^ y;
424
+ u = twos ^ twosA;
425
+ foursB = twos & twosA | u & twosB;
426
+ twos = u ^ twosB;
427
+ u = fours ^ foursA;
428
+ const eightsB = fours & foursA | u & foursB;
429
+ fours = u ^ foursB;
430
+ u = eights ^ eightsA;
431
+ const sixteens = eights & eightsA | u & eightsB;
432
+ eights = u ^ eightsB;
433
+ total += popcount32(sixteens);
434
+ }
435
+ return 16 * total + 8 * popcount32(eights) + 4 * popcount32(fours) + 2 * popcount32(twos) + popcount32(ones);
436
+ }
437
+ function setRange(words, start, end) {
438
+ const first = start >>> 5;
439
+ const last = end >>> 5;
440
+ const head = 4294967295 << (start & 31) >>> 0;
441
+ const tail = 4294967295 >>> 31 - (end & 31);
442
+ if (first === last) {
443
+ words[first] = words[first] | head & tail;
444
+ return;
445
+ }
446
+ words[first] = words[first] | head;
447
+ for (let i = first + 1; i < last; i++) words[i] = 4294967295;
448
+ words[last] = words[last] | tail;
449
+ }
450
+ function clearRange(words, start, end) {
451
+ const first = start >>> 5;
452
+ const last = end >>> 5;
453
+ const head = 4294967295 << (start & 31) >>> 0;
454
+ const tail = 4294967295 >>> 31 - (end & 31);
455
+ if (first === last) {
456
+ words[first] = words[first] & ~(head & tail);
457
+ return;
458
+ }
459
+ words[first] = words[first] & ~head;
460
+ for (let i = first + 1; i < last; i++) words[i] = 0;
461
+ words[last] = words[last] & ~tail;
462
+ }
463
+ function fromSortedIds(ids, from, to) {
464
+ const n = to - from;
465
+ if (n <= ARRAY_MAX_CARDINALITY) {
466
+ const lows = new Uint16Array(n);
467
+ let count = 0;
468
+ let previous = -1;
469
+ for (let i = from; i < to; i++) {
470
+ const low = ids[i] & 65535;
471
+ if (low !== previous) lows[count++] = low;
472
+ previous = low;
473
+ }
474
+ return arrayContainer(count === n ? lows : lows.slice(0, count), count);
475
+ }
476
+ const words = new Uint32Array(WORDS);
477
+ for (let i = from; i < to; i++) {
478
+ const v = ids[i] & 65535;
479
+ words[v >>> 5] = words[v >>> 5] | 1 << (v & 31);
480
+ }
481
+ return fromWordsCard(words, popcountWords(words));
482
+ }
483
+ function fromWordsCard(words, card) {
484
+ if (card === 0) return null;
485
+ if (card > ARRAY_MAX_CARDINALITY) return bitsetContainer(words, card);
486
+ const out = new Uint16Array(card);
487
+ wordsToLows(words, out);
488
+ return arrayContainer(out, card);
489
+ }
490
+ function wordsToLows(words, out) {
491
+ let k = 0;
492
+ for (let i = 0; i < WORDS; i++) {
493
+ let w = words[i];
494
+ const base = i * 32 + 31;
495
+ while (w !== 0) {
496
+ const lowest = w & -w;
497
+ out[k++] = base - Math.clz32(lowest);
498
+ w ^= lowest;
499
+ }
500
+ }
501
+ return k;
502
+ }
503
+ function writeLows(c, out) {
504
+ if (c.kind === ARRAY2) {
505
+ out.set(lows16(c).subarray(c.off, c.off + c.len));
506
+ } else if (c.kind === BITSET) {
507
+ wordsToLows(words32(c), out);
508
+ } else {
509
+ const u16 = lows16(c);
510
+ let k = 0;
511
+ for (let r = 0; r < c.len; r++) {
512
+ const start = u16[c.off + 2 * r];
513
+ const end = start + u16[c.off + 2 * r + 1];
514
+ for (let v = start; v <= end; v++) out[k++] = v;
515
+ }
516
+ }
517
+ }
518
+ function appendIds(c, out, at, base) {
519
+ if (c.kind === ARRAY2) {
520
+ const u162 = lows16(c);
521
+ const end = c.off + c.len;
522
+ if (base === 0) {
523
+ out.set(u162.subarray(c.off, end), at);
524
+ return at + c.len;
525
+ }
526
+ for (let i = c.off; i < end; i++) out[at++] = base + u162[i];
527
+ return at;
528
+ }
529
+ if (c.kind === BITSET) {
530
+ const words = words32(c);
531
+ for (let i = 0; i < WORDS; i++) {
532
+ let w = words[i];
533
+ const top = base + i * 32 + 31;
534
+ while (w !== 0) {
535
+ const lowest = w & -w;
536
+ out[at++] = top - Math.clz32(lowest);
537
+ w ^= lowest;
538
+ }
539
+ }
540
+ return at;
541
+ }
542
+ const u16 = lows16(c);
543
+ for (let r = 0; r < c.len; r++) {
544
+ const start = u16[c.off + 2 * r];
545
+ const last = start + u16[c.off + 2 * r + 1];
546
+ if (last - start < LONG_RUN) {
547
+ for (let v = base + start; v <= base + last; v++) out[at++] = v;
548
+ continue;
549
+ }
550
+ const from = at;
551
+ out.set(iota().subarray(start, last + 1), at);
552
+ at += last - start + 1;
553
+ if (base !== 0) for (let i = from; i < at; i++) out[i] = out[i] + base;
554
+ }
555
+ return at;
556
+ }
557
+ var LONG_RUN = 48;
558
+ var iotaTable;
559
+ function iota() {
560
+ if (iotaTable === void 0) {
561
+ iotaTable = new Uint16Array(65536);
562
+ for (let i = 0; i < 65536; i++) iotaTable[i] = i;
563
+ }
564
+ return iotaTable;
565
+ }
566
+ function toWords(c) {
567
+ if (c.kind === BITSET) return words32(c);
568
+ const words = new Uint32Array(WORDS);
569
+ const u16 = lows16(c);
570
+ if (c.kind === ARRAY2) {
571
+ for (let i = c.off; i < c.off + c.len; i++) {
572
+ const v = u16[i];
573
+ words[v >>> 5] = words[v >>> 5] | 1 << (v & 31);
574
+ }
575
+ } else {
576
+ for (let r = 0; r < c.len; r++) {
577
+ const start = u16[c.off + 2 * r];
578
+ setRange(words, start, start + u16[c.off + 2 * r + 1]);
579
+ }
580
+ }
581
+ return words;
582
+ }
583
+ function demote(c) {
584
+ if (c.kind !== RUN2) return c;
585
+ if (c.card > ARRAY_MAX_CARDINALITY) return bitsetContainer(toWords(c), c.card);
586
+ const out = new Uint16Array(c.card);
587
+ writeLows(c, out);
588
+ return arrayContainer(out, c.card);
589
+ }
590
+ function cloneContainer(c) {
591
+ if (c.kind === BITSET) return bitsetContainer(words32(c).slice(), c.card);
592
+ const copy = lows16(c).slice(c.off, c.off + (c.kind === ARRAY2 ? c.len : 2 * c.len));
593
+ return new Container(c.kind, copy, 0, c.len, c.card, false);
594
+ }
595
+ function writableWords(c) {
596
+ return c.shared ? words32(c).slice() : words32(c);
597
+ }
598
+ function lowerBound(data, off, len, low, stride) {
599
+ let lo = 0;
600
+ let hi = len;
601
+ while (lo < hi) {
602
+ const mid = lo + hi >>> 1;
603
+ if (data[off + mid * stride] < low) lo = mid + 1;
604
+ else hi = mid;
605
+ }
606
+ return lo;
607
+ }
608
+ function gallop(data, off, from, end, target) {
609
+ let step = 1;
610
+ let lo = from;
611
+ let hi = from;
612
+ while (hi < end && data[off + hi] < target) {
613
+ lo = hi + 1;
614
+ hi += step;
615
+ step *= 2;
616
+ }
617
+ if (hi > end) hi = end;
618
+ while (lo < hi) {
619
+ const mid = lo + hi >>> 1;
620
+ if (data[off + mid] < target) lo = mid + 1;
621
+ else hi = mid;
622
+ }
623
+ return lo;
624
+ }
625
+ function containerHas(c, low) {
626
+ if (c.kind === BITSET)
627
+ return (c.data[low >>> 5] >>> (low & 31) & 1) === 1;
628
+ const u16 = c.data;
629
+ if (c.kind === ARRAY2) {
630
+ const at = lowerBound(u16, c.off, c.len, low, 1);
631
+ return at < c.len && u16[c.off + at] === low;
632
+ }
633
+ const after = lowerBound(u16, c.off, c.len, low + 1, 2);
634
+ if (after === 0) return false;
635
+ const r = c.off + 2 * (after - 1);
636
+ return low <= u16[r] + u16[r + 1];
637
+ }
638
+ function containerAdd(c, low) {
639
+ if (containerHas(c, low)) return c;
640
+ const plain = demote(c);
641
+ if (plain.kind === BITSET) {
642
+ const words = writableWords(plain);
643
+ words[low >>> 5] = words[low >>> 5] | 1 << (low & 31);
644
+ return bitsetContainer(words, plain.card + 1);
645
+ }
646
+ if (plain.card === ARRAY_MAX_CARDINALITY) {
647
+ const words = toWords(plain);
648
+ words[low >>> 5] = words[low >>> 5] | 1 << (low & 31);
649
+ return bitsetContainer(words, plain.card + 1);
650
+ }
651
+ const old = lows16(plain);
652
+ const at = lowerBound(old, plain.off, plain.len, low, 1);
653
+ let u16 = old;
654
+ if (!plain.shared && plain.off === 0 && old.length > plain.len) {
655
+ u16.copyWithin(at + 1, at, plain.len);
656
+ } else {
657
+ u16 = new Uint16Array(Math.min(ARRAY_MAX_CARDINALITY, Math.max(8, plain.len * 2)));
658
+ u16.set(old.subarray(plain.off, plain.off + at));
659
+ u16.set(old.subarray(plain.off + at, plain.off + plain.len), at + 1);
660
+ }
661
+ u16[at] = low;
662
+ return arrayContainer(u16, plain.card + 1);
663
+ }
664
+ function containerRemove(c, low) {
665
+ if (!containerHas(c, low)) return c;
666
+ if (c.card === 1) return null;
667
+ const plain = demote(c);
668
+ if (plain.kind === BITSET) {
669
+ const words = writableWords(plain);
670
+ words[low >>> 5] = words[low >>> 5] & ~(1 << (low & 31));
671
+ return fromWordsCard(words, plain.card - 1);
672
+ }
673
+ const old = lows16(plain);
674
+ const at = lowerBound(old, plain.off, plain.len, low, 1);
675
+ if (!plain.shared && plain.off === 0) {
676
+ old.copyWithin(at, at + 1, plain.len);
677
+ return arrayContainer(old, plain.card - 1);
678
+ }
679
+ const u16 = new Uint16Array(plain.len - 1);
680
+ u16.set(old.subarray(plain.off, plain.off + at));
681
+ u16.set(old.subarray(plain.off + at + 1, plain.off + plain.len), at);
682
+ return arrayContainer(u16, plain.card - 1);
683
+ }
684
+ function containerMax(c) {
685
+ if (c.kind === ARRAY2) return c.data[c.off + c.len - 1];
686
+ if (c.kind === RUN2) {
687
+ const u16 = c.data;
688
+ return u16[c.off + 2 * c.len - 2] + u16[c.off + 2 * c.len - 1];
689
+ }
690
+ const words = words32(c);
691
+ for (let i = WORDS - 1; i >= 0; i--) {
692
+ const w = words[i];
693
+ if (w !== 0) return i * 32 + 31 - Math.clz32(w);
694
+ }
695
+ throw new RangeError("a bitset container holds no bits");
696
+ }
697
+ function runCount(c, stop) {
698
+ if (c.kind === RUN2) return c.len;
699
+ let runs = 0;
700
+ if (c.kind === ARRAY2) {
701
+ const u16 = lows16(c);
702
+ let previous = -2;
703
+ for (let i = c.off; i < c.off + c.len; i++) {
704
+ const v = u16[i];
705
+ if (v !== previous + 1 && ++runs >= stop) return runs;
706
+ previous = v;
707
+ }
708
+ return runs;
709
+ }
710
+ const words = words32(c);
711
+ let carry = 0;
712
+ for (let i = 0; i < WORDS; i++) {
713
+ const w = words[i];
714
+ const starts = w & ~(w << 1 | carry);
715
+ if (starts !== 0) {
716
+ runs += popcount32(starts >>> 0);
717
+ if (runs >= stop) return runs;
718
+ }
719
+ carry = w >>> 31;
720
+ }
721
+ return runs;
722
+ }
723
+ function toRun(c, runs) {
724
+ const pairs = new Uint16Array(2 * runs);
725
+ let r = 0;
726
+ if (c.kind === ARRAY2) {
727
+ const u16 = lows16(c);
728
+ const end = c.off + c.len;
729
+ let i = c.off;
730
+ while (i < end) {
731
+ let j = i;
732
+ while (j + 1 < end && u16[j + 1] === u16[j] + 1) j++;
733
+ pairs[2 * r] = u16[i];
734
+ pairs[2 * r + 1] = j - i;
735
+ r++;
736
+ i = j + 1;
737
+ }
738
+ return runContainer(pairs, runs, c.card);
739
+ }
740
+ const words = words32(c);
741
+ let start = 0;
742
+ let carry = 0;
743
+ for (let i = 0; i < WORDS; i++) {
744
+ const w = words[i];
745
+ const next = i + 1 < WORDS ? words[i + 1] : 0;
746
+ let starts = (w & ~(w << 1 | carry)) >>> 0;
747
+ let ends = (w & ~(w >>> 1 | next << 31)) >>> 0;
748
+ carry = w >>> 31;
749
+ let both = starts | ends;
750
+ while (both !== 0) {
751
+ const bit = both & -both;
752
+ both ^= bit;
753
+ const at = i * 32 + 31 - Math.clz32(bit);
754
+ if ((starts & bit) !== 0) {
755
+ starts ^= bit;
756
+ start = at;
757
+ }
758
+ if ((ends & bit) !== 0) {
759
+ ends ^= bit;
760
+ pairs[2 * r] = start;
761
+ pairs[2 * r + 1] = at - start;
762
+ r++;
763
+ }
764
+ }
765
+ }
766
+ return runContainer(pairs, runs, c.card);
767
+ }
768
+ function optimize(c) {
769
+ const plain = c.card <= ARRAY_MAX_CARDINALITY ? 2 * c.card : BITSET_BYTES;
770
+ const runs = runCount(c, (plain - 2) / 4);
771
+ if (2 + 4 * runs < plain) return c.kind === RUN2 ? c : toRun(c, runs);
772
+ return demote(c);
773
+ }
774
+ function skewed(shorter, longer) {
775
+ return longer >= GALLOP_SKEW * shorter;
776
+ }
777
+ var PROBE_MIN = 32;
778
+ var probeWords = new Uint32Array(WORDS);
779
+ function andArrays(a, b) {
780
+ const small = a.len <= b.len ? a : b;
781
+ const big = small === a ? b : a;
782
+ const s = lows16(small);
783
+ const l = lows16(big);
784
+ const out = values16(small.len);
785
+ let n = 0;
786
+ if (small.len >= PROBE_MIN && !skewed(small.len, big.len)) {
787
+ const se = small.off + small.len;
788
+ const first = s[small.off];
789
+ const last = s[se - 1];
790
+ const le = big.off + big.len;
791
+ if (last < l[big.off] || first > l[le - 1]) return null;
792
+ const from = gallop(l, 0, big.off, le, first);
793
+ const to = gallop(l, 0, from, le, last + 1);
794
+ const words = probeWords;
795
+ for (let i2 = small.off; i2 < se; i2++) {
796
+ const v = s[i2];
797
+ words[v >>> 5] = words[v >>> 5] | 1 << (v & 31);
798
+ }
799
+ for (let j2 = from; j2 < to; j2++) {
800
+ const v = l[j2];
801
+ out[n] = v;
802
+ n += words[v >>> 5] >>> (v & 31) & 1;
803
+ }
804
+ for (let i2 = small.off; i2 < se; i2++) words[s[i2] >>> 5] = 0;
805
+ return arrayOfScratch(out, n);
806
+ }
807
+ if (skewed(small.len, big.len)) {
808
+ let at = 0;
809
+ const end = big.off + big.len;
810
+ for (let i2 = small.off; i2 < small.off + small.len; i2++) {
811
+ const v = s[i2];
812
+ at = gallop(l, 0, Math.max(at, big.off), end, v);
813
+ if (at === end) break;
814
+ if (l[at] === v) out[n++] = v;
815
+ }
816
+ return arrayOfScratch(out, n);
817
+ }
818
+ let i = small.off;
819
+ let j = big.off;
820
+ const ie = small.off + small.len;
821
+ const je = big.off + big.len;
822
+ while (i < ie && j < je) {
823
+ const x = s[i];
824
+ const y = l[j];
825
+ out[n] = x;
826
+ n += x === y ? 1 : 0;
827
+ i += x <= y ? 1 : 0;
828
+ j += x >= y ? 1 : 0;
829
+ }
830
+ return arrayOfScratch(out, n);
831
+ }
832
+ function filterByBits(a, b, keep) {
833
+ const u16 = lows16(a);
834
+ const words = words32(b);
835
+ const out = values16(a.len);
836
+ const flip = keep ? 0 : 1;
837
+ let n = 0;
838
+ for (let i = a.off; i < a.off + a.len; i++) {
839
+ const v = u16[i];
840
+ out[n] = v;
841
+ n += words[v >>> 5] >>> (v & 31) & 1 ^ flip;
842
+ }
843
+ return arrayOfScratch(out, n);
844
+ }
845
+ function filterByRuns(a, b, keep) {
846
+ const u16 = lows16(a);
847
+ const pairs = lows16(b);
848
+ const out = values16(a.len);
849
+ let n = 0;
850
+ if (keep && a.len >= b.len) {
851
+ const ae = a.off + a.len;
852
+ let i = a.off;
853
+ for (let r2 = 0; r2 < b.len && i < ae; r2++) {
854
+ const start = pairs[b.off + 2 * r2];
855
+ const end = start + pairs[b.off + 2 * r2 + 1];
856
+ while (i < ae && u16[i] < start) i++;
857
+ while (i < ae && u16[i] <= end) out[n++] = u16[i++];
858
+ }
859
+ return arrayOfScratch(out, n);
860
+ }
861
+ let r = 0;
862
+ for (let i = a.off; i < a.off + a.len; i++) {
863
+ const v = u16[i];
864
+ while (r < b.len && pairs[b.off + 2 * r] + pairs[b.off + 2 * r + 1] < v) {
865
+ r++;
866
+ }
867
+ const inside = r < b.len && pairs[b.off + 2 * r] <= v;
868
+ if (inside === keep) out[n++] = v;
869
+ }
870
+ return arrayOfScratch(out, n);
871
+ }
872
+ function andNotArrays(a, b) {
873
+ const x = lows16(a);
874
+ const y = lows16(b);
875
+ const out = values16(a.len);
876
+ let n = 0;
877
+ const je = b.off + b.len;
878
+ if (skewed(a.len, b.len)) {
879
+ let at = b.off;
880
+ for (let i2 = a.off; i2 < a.off + a.len; i2++) {
881
+ const v = x[i2];
882
+ at = gallop(y, 0, at, je, v);
883
+ if (at === je || y[at] !== v) out[n++] = v;
884
+ }
885
+ return arrayOfScratch(out, n);
886
+ }
887
+ if (b.len >= PROBE_MIN) {
888
+ const ae = a.off + a.len;
889
+ const first = x[a.off];
890
+ const last = x[ae - 1];
891
+ const from = gallop(y, 0, b.off, je, first);
892
+ const to = gallop(y, 0, from, je, last + 1);
893
+ const words = probeWords;
894
+ for (let j2 = from; j2 < to; j2++) {
895
+ const v = y[j2];
896
+ words[v >>> 5] = words[v >>> 5] | 1 << (v & 31);
897
+ }
898
+ for (let i2 = a.off; i2 < ae; i2++) {
899
+ const v = x[i2];
900
+ out[n] = v;
901
+ n += words[v >>> 5] >>> (v & 31) & 1 ^ 1;
902
+ }
903
+ for (let j2 = from; j2 < to; j2++) words[y[j2] >>> 5] = 0;
904
+ return arrayOfScratch(out, n);
905
+ }
906
+ let i = a.off;
907
+ let j = b.off;
908
+ const ie = a.off + a.len;
909
+ while (i < ie && j < je) {
910
+ const p = x[i];
911
+ const q = y[j];
912
+ out[n] = p;
913
+ n += p < q ? 1 : 0;
914
+ i += p <= q ? 1 : 0;
915
+ j += p >= q ? 1 : 0;
916
+ }
917
+ while (i < ie) out[n++] = x[i++];
918
+ return arrayOfScratch(out, n);
919
+ }
920
+ function orArrays(a, b) {
921
+ const x = lows16(a);
922
+ const y = lows16(b);
923
+ const ie = a.off + a.len;
924
+ const je = b.off + b.len;
925
+ if (a.len + b.len > ARRAY_MAX_CARDINALITY) {
926
+ const words = new Uint32Array(WORDS);
927
+ for (let i2 = a.off; i2 < ie; i2++) {
928
+ const v = x[i2];
929
+ words[v >>> 5] = words[v >>> 5] | 1 << (v & 31);
930
+ }
931
+ for (let j2 = b.off; j2 < je; j2++) {
932
+ const v = y[j2];
933
+ words[v >>> 5] = words[v >>> 5] | 1 << (v & 31);
934
+ }
935
+ return fromWordsCard(words, popcountWords(words));
936
+ }
937
+ const out = values16(a.len + b.len);
938
+ let n = 0;
939
+ let i = a.off;
940
+ let j = b.off;
941
+ while (i < ie && j < je) {
942
+ const p = x[i];
943
+ const q = y[j];
944
+ out[n++] = p < q ? p : q;
945
+ i += p <= q ? 1 : 0;
946
+ j += p >= q ? 1 : 0;
947
+ }
948
+ while (i < ie) out[n++] = x[i++];
949
+ while (j < je) out[n++] = y[j++];
950
+ return arrayOfScratch(out, n);
951
+ }
952
+ function orIntoBitset(dest, other, inPlace) {
953
+ const words = inPlace ? words32(dest) : words32(dest).slice();
954
+ if (other.kind === ARRAY2) {
955
+ const u16 = lows16(other);
956
+ let card = dest.card;
957
+ for (let i = other.off; i < other.off + other.len; i++) {
958
+ const v = u16[i];
959
+ const w = words[v >>> 5];
960
+ const bit = 1 << (v & 31);
961
+ if ((w & bit) === 0) {
962
+ words[v >>> 5] = w | bit;
963
+ card++;
964
+ }
965
+ }
966
+ return bitsetContainer(words, card);
967
+ }
968
+ if (other.kind === BITSET) {
969
+ const o = words32(other);
970
+ for (let i = 0; i < WORDS; i++) words[i] = words[i] | o[i];
971
+ } else {
972
+ const pairs = lows16(other);
973
+ for (let r = 0; r < other.len; r++) {
974
+ const start = pairs[other.off + 2 * r];
975
+ setRange(words, start, start + pairs[other.off + 2 * r + 1]);
976
+ }
977
+ }
978
+ return bitsetContainer(words, popcountWords(words));
979
+ }
980
+ function fromRunPairs(pairs, runs, card) {
981
+ if (card === 0) return null;
982
+ if (card <= ARRAY_MAX_CARDINALITY) {
983
+ const out = new Uint16Array(card);
984
+ let k = 0;
985
+ for (let r = 0; r < runs; r++) {
986
+ const start = pairs[2 * r];
987
+ const end = start + pairs[2 * r + 1];
988
+ for (let v = start; v <= end; v++) out[k++] = v;
989
+ }
990
+ return arrayContainer(out, card);
991
+ }
992
+ const words = new Uint32Array(WORDS);
993
+ for (let r = 0; r < runs; r++) {
994
+ const start = pairs[2 * r];
995
+ setRange(words, start, start + pairs[2 * r + 1]);
996
+ }
997
+ return bitsetContainer(words, card);
998
+ }
999
+ function andRuns(a, b) {
1000
+ const x = lows16(a);
1001
+ const y = lows16(b);
1002
+ const out = pairs16(2 * (a.len + b.len));
1003
+ let runs = 0;
1004
+ let card = 0;
1005
+ let i = 0;
1006
+ let j = 0;
1007
+ while (i < a.len && j < b.len) {
1008
+ const as = x[a.off + 2 * i];
1009
+ const ae = as + x[a.off + 2 * i + 1];
1010
+ const bs = y[b.off + 2 * j];
1011
+ const be = bs + y[b.off + 2 * j + 1];
1012
+ const lo = as > bs ? as : bs;
1013
+ const hi = ae < be ? ae : be;
1014
+ if (lo <= hi) {
1015
+ out[2 * runs] = lo;
1016
+ out[2 * runs + 1] = hi - lo;
1017
+ runs++;
1018
+ card += hi - lo + 1;
1019
+ }
1020
+ if (ae < be) i++;
1021
+ else j++;
1022
+ }
1023
+ return fromRunPairs(out, runs, card);
1024
+ }
1025
+ function orRuns(a, b) {
1026
+ const x = lows16(a);
1027
+ const y = lows16(b);
1028
+ const out = pairs16(2 * (a.len + b.len));
1029
+ let runs = 0;
1030
+ let card = 0;
1031
+ let i = 0;
1032
+ let j = 0;
1033
+ let start = -1;
1034
+ let end = -1;
1035
+ const flush = () => {
1036
+ if (start < 0) return;
1037
+ out[2 * runs] = start;
1038
+ out[2 * runs + 1] = end - start;
1039
+ runs++;
1040
+ card += end - start + 1;
1041
+ };
1042
+ while (i < a.len || j < b.len) {
1043
+ let s;
1044
+ let e;
1045
+ if (j >= b.len || i < a.len && x[a.off + 2 * i] <= y[b.off + 2 * j]) {
1046
+ s = x[a.off + 2 * i];
1047
+ e = s + x[a.off + 2 * i + 1];
1048
+ i++;
1049
+ } else {
1050
+ s = y[b.off + 2 * j];
1051
+ e = s + y[b.off + 2 * j + 1];
1052
+ j++;
1053
+ }
1054
+ if (start >= 0 && s <= end + 1) {
1055
+ if (e > end) end = e;
1056
+ } else {
1057
+ flush();
1058
+ start = s;
1059
+ end = e;
1060
+ }
1061
+ }
1062
+ flush();
1063
+ return fromRunPairs(out, runs, card);
1064
+ }
1065
+ function andNotRuns(a, b) {
1066
+ const x = lows16(a);
1067
+ const y = lows16(b);
1068
+ const out = pairs16(2 * (a.len + b.len + 1));
1069
+ let runs = 0;
1070
+ let card = 0;
1071
+ let j = 0;
1072
+ for (let i = 0; i < a.len; i++) {
1073
+ let s = x[a.off + 2 * i];
1074
+ const e = s + x[a.off + 2 * i + 1];
1075
+ while (j < b.len && y[b.off + 2 * j] + y[b.off + 2 * j + 1] < s) j++;
1076
+ let k = j;
1077
+ while (s <= e) {
1078
+ if (k >= b.len || y[b.off + 2 * k] > e) {
1079
+ out[2 * runs] = s;
1080
+ out[2 * runs + 1] = e - s;
1081
+ runs++;
1082
+ card += e - s + 1;
1083
+ break;
1084
+ }
1085
+ const bs = y[b.off + 2 * k];
1086
+ const be = bs + y[b.off + 2 * k + 1];
1087
+ if (bs > s) {
1088
+ out[2 * runs] = s;
1089
+ out[2 * runs + 1] = bs - 1 - s;
1090
+ runs++;
1091
+ card += bs - s;
1092
+ }
1093
+ s = be + 1;
1094
+ k++;
1095
+ }
1096
+ }
1097
+ return fromRunPairs(out, runs, card);
1098
+ }
1099
+ function bitsetInRuns(a, b) {
1100
+ const words = words32(a);
1101
+ const pairs = lows16(b);
1102
+ if (b.card <= ARRAY_MAX_CARDINALITY) {
1103
+ const out2 = values16(b.card);
1104
+ let n = 0;
1105
+ for (let r = 0; r < b.len; r++) {
1106
+ const start = pairs[b.off + 2 * r];
1107
+ const end = start + pairs[b.off + 2 * r + 1];
1108
+ const first = start >>> 5;
1109
+ const last = end >>> 5;
1110
+ const head = 4294967295 << (start & 31) >>> 0;
1111
+ const tail = 4294967295 >>> 31 - (end & 31);
1112
+ for (let i = first; i <= last; i++) {
1113
+ let w = words[i];
1114
+ if (i === first) w &= head;
1115
+ if (i === last) w &= tail;
1116
+ const top = i * 32 + 31;
1117
+ while (w !== 0) {
1118
+ const lowest = w & -w;
1119
+ out2[n++] = top - Math.clz32(lowest);
1120
+ w ^= lowest;
1121
+ }
1122
+ }
1123
+ }
1124
+ return arrayOfScratch(out2, n);
1125
+ }
1126
+ const out = new Uint32Array(WORDS);
1127
+ for (let r = 0; r < b.len; r++) {
1128
+ const start = pairs[b.off + 2 * r];
1129
+ const end = start + pairs[b.off + 2 * r + 1];
1130
+ const first = start >>> 5;
1131
+ const last = end >>> 5;
1132
+ const head = 4294967295 << (start & 31) >>> 0;
1133
+ const tail = 4294967295 >>> 31 - (end & 31);
1134
+ if (first === last) {
1135
+ out[first] = out[first] | words[first] & head & tail;
1136
+ } else {
1137
+ out[first] = out[first] | words[first] & head;
1138
+ for (let i = first + 1; i < last; i++) out[i] = words[i];
1139
+ out[last] = out[last] | words[last] & tail;
1140
+ }
1141
+ }
1142
+ return fromWordsCard(out, popcountWords(out));
1143
+ }
1144
+ function containerAnd(a, b, inPlace = false) {
1145
+ if (a.kind === BITSET && b.kind === BITSET) {
1146
+ const x = words32(a);
1147
+ const y = words32(b);
1148
+ const out = inPlace ? x : new Uint32Array(WORDS);
1149
+ for (let i = 0; i < WORDS; i++) out[i] = x[i] & y[i];
1150
+ return fromWordsCard(out, popcountWords(out));
1151
+ }
1152
+ if (a.kind > b.kind) return containerAnd(b, a);
1153
+ if (a.kind === ARRAY2) {
1154
+ if (b.kind === ARRAY2) return andArrays(a, b);
1155
+ return b.kind === BITSET ? filterByBits(a, b, true) : filterByRuns(a, b, true);
1156
+ }
1157
+ return b.kind === RUN2 && a.kind === RUN2 ? andRuns(a, b) : bitsetInRuns(a, b);
1158
+ }
1159
+ function containerOr(a, b, inPlace = false) {
1160
+ if (a.kind === BITSET) return orIntoBitset(a, b, inPlace);
1161
+ if (b.kind === BITSET) return orIntoBitset(b, a, false);
1162
+ if (a.kind === ARRAY2 && b.kind === ARRAY2) return orArrays(a, b);
1163
+ if (a.kind === RUN2 && b.kind === RUN2) return orRuns(a, b);
1164
+ const words = toWords(a.kind === RUN2 ? a : b);
1165
+ return orIntoBitsetWords(words, a.kind === RUN2 ? b : a);
1166
+ }
1167
+ function orIntoBitsetWords(words, array) {
1168
+ const u16 = lows16(array);
1169
+ for (let i = array.off; i < array.off + array.len; i++) {
1170
+ const v = u16[i];
1171
+ words[v >>> 5] = words[v >>> 5] | 1 << (v & 31);
1172
+ }
1173
+ return fromWordsCard(words, popcountWords(words));
1174
+ }
1175
+ function containerAndNot(a, b, inPlace = false) {
1176
+ if (a.kind === ARRAY2) {
1177
+ if (b.kind === ARRAY2) return andNotArrays(a, b);
1178
+ return b.kind === BITSET ? filterByBits(a, b, false) : filterByRuns(a, b, false);
1179
+ }
1180
+ if (a.kind === RUN2 && b.kind === RUN2) return andNotRuns(a, b);
1181
+ const words = a.kind === BITSET ? inPlace ? words32(a) : words32(a).slice() : toWords(a);
1182
+ if (b.kind === ARRAY2) {
1183
+ const u16 = lows16(b);
1184
+ for (let i = b.off; i < b.off + b.len; i++) {
1185
+ const v = u16[i];
1186
+ words[v >>> 5] = words[v >>> 5] & ~(1 << (v & 31));
1187
+ }
1188
+ } else if (b.kind === BITSET) {
1189
+ const y = words32(b);
1190
+ for (let i = 0; i < WORDS; i++) words[i] = words[i] & ~y[i];
1191
+ } else {
1192
+ const pairs = lows16(b);
1193
+ for (let r = 0; r < b.len; r++) {
1194
+ const start = pairs[b.off + 2 * r];
1195
+ clearRange(words, start, start + pairs[b.off + 2 * r + 1]);
1196
+ }
1197
+ }
1198
+ return fromWordsCard(words, popcountWords(words));
1199
+ }
1200
+
1201
+ // src/ts-roaring/iterator.ts
1202
+ var DONE = { done: true, value: void 0 };
1203
+ var BitmapIterator = class {
1204
+ #keys;
1205
+ #conts;
1206
+ /** The container being walked, as an index into `#conts`, and its kind, storage and offset. */
1207
+ #at = -1;
1208
+ #kind = ARRAY2;
1209
+ #u16 = new Uint16Array(0);
1210
+ #words = new Uint32Array(0);
1211
+ #off = 0;
1212
+ /** Added to every remainder: the container's key times 65,536. */
1213
+ #base = 0;
1214
+ /** An array: the next index and one past the last. A run container: the next run's index and the run count. A bitset: the word index. */
1215
+ #pos = 0;
1216
+ #end = 0;
1217
+ /** A run container: the next value and the last of the current run. A bitset: what is left of the current word. */
1218
+ #next = 0;
1219
+ #last = -1;
1220
+ constructor(keys, conts) {
1221
+ this.#keys = keys;
1222
+ this.#conts = conts;
1223
+ }
1224
+ [Symbol.iterator]() {
1225
+ return this;
1226
+ }
1227
+ next() {
1228
+ for (; ; ) {
1229
+ if (this.#kind === ARRAY2) {
1230
+ if (this.#pos < this.#end) {
1231
+ return { done: false, value: this.#base + this.#u16[this.#pos++] };
1232
+ }
1233
+ } else if (this.#kind === BITSET) {
1234
+ let w = this.#next;
1235
+ while (w === 0 && ++this.#pos < WORDS) w = this.#words[this.#pos];
1236
+ if (w !== 0) {
1237
+ const lowest = w & -w;
1238
+ this.#next = w ^ lowest;
1239
+ return {
1240
+ done: false,
1241
+ value: this.#base + this.#pos * 32 + 31 - Math.clz32(lowest)
1242
+ };
1243
+ }
1244
+ } else {
1245
+ if (this.#next <= this.#last) return { done: false, value: this.#base + this.#next++ };
1246
+ if (this.#pos < this.#end) {
1247
+ const r = this.#off + 2 * this.#pos++;
1248
+ this.#next = this.#u16[r];
1249
+ this.#last = this.#next + this.#u16[r + 1];
1250
+ continue;
1251
+ }
1252
+ }
1253
+ if (!this.#advance()) return DONE;
1254
+ }
1255
+ }
1256
+ /** Move to the next container; `false` when there is none. */
1257
+ #advance() {
1258
+ if (++this.#at >= this.#conts.length) {
1259
+ this.#at = this.#conts.length;
1260
+ this.#kind = ARRAY2;
1261
+ this.#pos = 0;
1262
+ this.#end = 0;
1263
+ return false;
1264
+ }
1265
+ const c = this.#conts[this.#at];
1266
+ this.#kind = c.kind;
1267
+ this.#base = this.#keys[this.#at] * 65536;
1268
+ this.#off = c.off;
1269
+ if (c.kind === ARRAY2) {
1270
+ this.#u16 = c.data;
1271
+ this.#pos = c.off;
1272
+ this.#end = c.off + c.len;
1273
+ } else if (c.kind === BITSET) {
1274
+ this.#words = c.data;
1275
+ this.#pos = 0;
1276
+ this.#next = this.#words[0];
1277
+ } else {
1278
+ this.#u16 = c.data;
1279
+ this.#pos = 0;
1280
+ this.#end = c.len;
1281
+ this.#next = 0;
1282
+ this.#last = -1;
1283
+ }
1284
+ return true;
1285
+ }
1286
+ };
1287
+
1288
+ // src/ts-roaring/wire.ts
1289
+ import { IntegrityError as IntegrityError2 } from "@cloudbitmaps/core";
1290
+ function bodySize(c) {
1291
+ if (c.kind === ARRAY2) return 2 * c.len;
1292
+ if (c.kind === BITSET) return BITSET_BYTES;
1293
+ return 2 + 4 * c.len;
1294
+ }
1295
+ function putU16s(out, at, src, from, count) {
1296
+ if (LITTLE_ENDIAN) {
1297
+ out.set(new Uint8Array(src.buffer, src.byteOffset + 2 * from, 2 * count), at);
1298
+ return;
1299
+ }
1300
+ const view = new DataView(out.buffer, out.byteOffset, out.byteLength);
1301
+ for (let i = 0; i < count; i++) view.setUint16(at + 2 * i, src[from + i], true);
1302
+ }
1303
+ function writeBody(c, out, view, at) {
1304
+ if (c.kind === ARRAY2) {
1305
+ putU16s(out, at, c.data, c.off, c.len);
1306
+ } else if (c.kind === BITSET) {
1307
+ const words = c.data;
1308
+ if (LITTLE_ENDIAN) out.set(new Uint8Array(words.buffer, words.byteOffset, BITSET_BYTES), at);
1309
+ else for (let i = 0; i < WORDS; i++) view.setUint32(at + 4 * i, words[i], true);
1310
+ } else {
1311
+ view.setUint16(at, c.len, true);
1312
+ putU16s(out, at + 2, c.data, c.off, 2 * c.len);
1313
+ }
1314
+ }
1315
+ function serializeContainers(keys, conts) {
1316
+ const n = conts.length;
1317
+ let hasRun = false;
1318
+ for (let i = 0; i < n; i++) if (conts[i].kind === RUN2) hasRun = true;
1319
+ const offsets = !hasRun || n >= NO_OFFSET_THRESHOLD;
1320
+ let at = hasRun ? 4 + (n + 7 >>> 3) : 8;
1321
+ const describeAt = at;
1322
+ at += 4 * n;
1323
+ const offsetsAt = at;
1324
+ if (offsets) at += 4 * n;
1325
+ let total = at;
1326
+ for (let i = 0; i < n; i++) total += bodySize(conts[i]);
1327
+ const out = new Uint8Array(total);
1328
+ const view = new DataView(out.buffer);
1329
+ if (hasRun) {
1330
+ view.setUint32(0, SERIAL_COOKIE | n - 1 << 16, true);
1331
+ for (let i = 0; i < n; i++) {
1332
+ if (conts[i].kind === RUN2) {
1333
+ out[4 + (i >>> 3)] = out[4 + (i >>> 3)] | 1 << (i & 7);
1334
+ }
1335
+ }
1336
+ } else {
1337
+ view.setUint32(0, SERIAL_COOKIE_NO_RUNCONTAINER, true);
1338
+ view.setUint32(4, n, true);
1339
+ }
1340
+ for (let i = 0; i < n; i++) {
1341
+ const c = conts[i];
1342
+ view.setUint16(describeAt + 4 * i, keys[i], true);
1343
+ view.setUint16(describeAt + 4 * i + 2, c.card - 1, true);
1344
+ if (offsets) view.setUint32(offsetsAt + 4 * i, at, true);
1345
+ writeBody(c, out, view, at);
1346
+ at += bodySize(c);
1347
+ }
1348
+ return out;
1349
+ }
1350
+ function decodeContainers(input) {
1351
+ const bytes = Uint8Array.prototype.slice.call(input);
1352
+ const layout = parsePortableLayout(bytes);
1353
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
1354
+ const keys = new Array(layout.length);
1355
+ const conts = new Array(layout.length);
1356
+ let n = 0;
1357
+ let end = bytes.byteLength === 0 ? 0 : 8;
1358
+ let slabLength = 0;
1359
+ let small = 0;
1360
+ for (const { cardinality, kind, offset } of layout) {
1361
+ if (kind === ARRAY) {
1362
+ slabLength += cardinality;
1363
+ small++;
1364
+ } else if (kind !== BITMAP) {
1365
+ slabLength += 2 * view.getUint16(offset, true);
1366
+ small++;
1367
+ }
1368
+ }
1369
+ const own = LITTLE_ENDIAN && bytes.byteOffset === 0 && bytes.buffer instanceof ArrayBuffer && bytes.buffer.byteLength === bytes.byteLength;
1370
+ const alias = own && small === 1;
1371
+ const slab = alias ? NO_U16 : new Uint16Array(slabLength);
1372
+ let used = 0;
1373
+ for (const { key, cardinality, kind, offset } of layout) {
1374
+ keys[n] = key;
1375
+ if (kind === ARRAY) {
1376
+ if (alias && offset % 2 === 0) {
1377
+ const values = new Uint16Array(bytes.buffer, offset, cardinality);
1378
+ conts[n++] = new Container(ARRAY2, values, 0, cardinality, cardinality, false);
1379
+ } else {
1380
+ const into = alias ? new Uint16Array(cardinality) : slab;
1381
+ getU16s(bytes, view, offset, into, alias ? 0 : used, cardinality);
1382
+ conts[n++] = new Container(
1383
+ ARRAY2,
1384
+ into,
1385
+ alias ? 0 : used,
1386
+ cardinality,
1387
+ cardinality,
1388
+ small > 1
1389
+ );
1390
+ used += cardinality;
1391
+ }
1392
+ end = offset + 2 * cardinality;
1393
+ } else if (kind === BITMAP) {
1394
+ let words;
1395
+ if (own && offset % 4 === 0) {
1396
+ words = new Uint32Array(bytes.buffer, offset, WORDS);
1397
+ } else {
1398
+ words = new Uint32Array(WORDS);
1399
+ if (LITTLE_ENDIAN) {
1400
+ new Uint8Array(words.buffer).set(bytes.subarray(offset, offset + BITSET_BYTES));
1401
+ } else {
1402
+ for (let i = 0; i < WORDS; i++) words[i] = view.getUint32(offset + 4 * i, true);
1403
+ }
1404
+ }
1405
+ conts[n++] = bitsetContainer(words, cardinality);
1406
+ end = offset + BITSET_BYTES;
1407
+ } else {
1408
+ const runs = view.getUint16(offset, true);
1409
+ if (alias && (offset + 2) % 2 === 0) {
1410
+ const pairs = new Uint16Array(bytes.buffer, offset + 2, 2 * runs);
1411
+ conts[n++] = new Container(RUN2, pairs, 0, runs, cardinality, false);
1412
+ } else {
1413
+ const into = alias ? new Uint16Array(2 * runs) : slab;
1414
+ getU16s(bytes, view, offset + 2, into, alias ? 0 : used, 2 * runs);
1415
+ conts[n++] = new Container(RUN2, into, alias ? 0 : used, runs, cardinality, small > 1);
1416
+ used += 2 * runs;
1417
+ }
1418
+ end = offset + 2 + 4 * runs;
1419
+ }
1420
+ }
1421
+ return { keys, conts, end };
1422
+ }
1423
+ var NO_U16 = new Uint16Array(0);
1424
+ function getU16s(bytes, view, at, slab, to, count) {
1425
+ if (LITTLE_ENDIAN) {
1426
+ new Uint8Array(slab.buffer, 2 * to, 2 * count).set(bytes.subarray(at, at + 2 * count));
1427
+ return;
1428
+ }
1429
+ for (let i = 0; i < count; i++) slab[to + i] = view.getUint16(at + 2 * i, true);
1430
+ }
1431
+ function trailingBytes(length, end) {
1432
+ return new IntegrityError2(
1433
+ `portable roaring: ${length - end} bytes follow the bitmap's last container, which ends at byte ${end}. One buffer holds one bitmap: to load several as one segment, combine them first and serialize the result.`
1434
+ );
1435
+ }
1436
+
1437
+ // src/ts-roaring/bitmap.ts
1438
+ var MAX_ID = 4294967295;
1439
+ function isId(value) {
1440
+ return Number.isInteger(value) && value >= 0 && value <= MAX_ID;
1441
+ }
1442
+ function badId(value) {
1443
+ return new ValidationError2(`${String(value)} is not an integer from 0 to ${MAX_ID}`);
1444
+ }
1445
+ function checkedId(value) {
1446
+ if (!isId(value)) throw badId(value);
1447
+ return value;
1448
+ }
1449
+ function collect(values) {
1450
+ if (values instanceof Uint32Array) return values;
1451
+ if (Array.isArray(values)) {
1452
+ const list = values;
1453
+ const out2 = new Uint32Array(list.length);
1454
+ for (let i = 0; i < list.length; i++) {
1455
+ const v = list[i];
1456
+ if (v >>> 0 !== v) throw badId(v);
1457
+ out2[i] = v;
1458
+ }
1459
+ return out2;
1460
+ }
1461
+ let out = new Uint32Array(1024);
1462
+ let n = 0;
1463
+ for (const v of values) {
1464
+ if (n === out.length) {
1465
+ const grown = new Uint32Array(2 * n);
1466
+ grown.set(out);
1467
+ out = grown;
1468
+ }
1469
+ out[n++] = checkedId(v);
1470
+ }
1471
+ return out.subarray(0, n);
1472
+ }
1473
+ function collectLenient(values) {
1474
+ const list = Array.isArray(values) ? values : Array.from(values);
1475
+ const out = new Uint32Array(list.length);
1476
+ let n = 0;
1477
+ for (let i = 0; i < list.length; i++) {
1478
+ const v = list[i];
1479
+ if (v >>> 0 === v) out[n++] = v;
1480
+ }
1481
+ return out.subarray(0, n);
1482
+ }
1483
+ function sortedIds(ids, owned) {
1484
+ for (let i = 1; i < ids.length; i++) {
1485
+ if (ids[i - 1] > ids[i]) return (owned ? ids : ids.slice()).sort();
1486
+ }
1487
+ return ids;
1488
+ }
1489
+ function lowerBound2(keys, key, from = 0) {
1490
+ let lo = from;
1491
+ let hi = keys.length;
1492
+ while (lo < hi) {
1493
+ const mid = lo + hi >>> 1;
1494
+ if (keys[mid] < key) lo = mid + 1;
1495
+ else hi = mid;
1496
+ }
1497
+ return lo;
1498
+ }
1499
+ function gallopKeys(keys, key, from) {
1500
+ let step = 1;
1501
+ let lo = from;
1502
+ let hi = from;
1503
+ while (hi < keys.length && keys[hi] < key) {
1504
+ lo = hi + 1;
1505
+ hi += step;
1506
+ step *= 2;
1507
+ }
1508
+ return lowerBoundIn(keys, key, lo, Math.min(hi, keys.length));
1509
+ }
1510
+ function lowerBoundIn(keys, key, from, to) {
1511
+ let lo = from;
1512
+ let hi = to;
1513
+ while (lo < hi) {
1514
+ const mid = lo + hi >>> 1;
1515
+ if (keys[mid] < key) lo = mid + 1;
1516
+ else hi = mid;
1517
+ }
1518
+ return lo;
1519
+ }
1520
+ var OR = 0;
1521
+ var AND = 1;
1522
+ var AND_NOT = 2;
1523
+ function combineContainers(op, a, b) {
1524
+ if (op === OR) return containerOr(a, b, !a.shared);
1525
+ if (op === AND) return containerAnd(a, b, !a.shared);
1526
+ return containerAndNot(a, b, !a.shared);
1527
+ }
1528
+ var TsBitmap = class _TsBitmap {
1529
+ #keys;
1530
+ #conts;
1531
+ #size;
1532
+ constructor(keys, conts, size) {
1533
+ this.#keys = keys;
1534
+ this.#conts = conts;
1535
+ this.#size = size;
337
1536
  }
338
1537
  static empty() {
339
- return new _SafeBitmap(new RoaringBitmap32());
1538
+ return new _TsBitmap([], [], 0);
340
1539
  }
341
1540
  static fromValues(values) {
342
- return new _SafeBitmap(new RoaringBitmap32(values));
1541
+ const bitmap = _TsBitmap.empty();
1542
+ bitmap.addMany(values);
1543
+ return bitmap;
343
1544
  }
344
1545
  /**
345
- * Cap the size, check the structure, then deserialize with the **portable** format.
346
- * Throws `IntegrityError` if the input exceeds `maxBytes`, is not a well-formed portable bitmap, or fails to
347
- * decode — the native addon is never handed unbounded, malformed or unsafe-format input. With `whole`, bytes
348
- * after the bitmap's last container are refused too; without it they are ignored, as the native decoder ignores
349
- * them.
1546
+ * Cap the size, check the structure, then build the containers. With `whole`, bytes after the last container are
1547
+ * refused too; without it they are ignored.
350
1548
  *
351
- * The structural check is what makes the decoded bitmap's answers mean anything. The native deserializer
352
- * bounds its reads and checks nothing else, so bytes of the right length and the wrong shape (containers or
353
- * values out of order, overlapping runs, a cardinality that disagrees with the bits) decode into a bitmap
354
- * whose `maximum()`, `has()` and `size` are wrong, and some of those shapes crash the process when used.
1549
+ * @throws {IntegrityError} if the input exceeds `maxBytes`, is not a well-formed portable bitmap, or (with `whole`)
1550
+ * has bytes after it.
355
1551
  */
356
1552
  static safeDeserialize(bytes, maxBytes, options = {}) {
357
1553
  if (bytes.length > maxBytes) {
358
- throw new IntegrityError2(`serialized bitmap is ${bytes.length}B, exceeds cap ${maxBytes}B`);
1554
+ throw new IntegrityError3(`serialized bitmap is ${bytes.length}B, exceeds cap ${maxBytes}B`);
359
1555
  }
360
- const end = checkPortableLayout(bytes);
1556
+ const { keys, conts, end } = decodeContainers(bytes);
361
1557
  if (options.whole === true && end !== bytes.byteLength) {
362
- throw new IntegrityError2(
363
- `portable roaring: ${bytes.byteLength - end} bytes follow the bitmap's last container, which ends at byte ${end}. One buffer holds one bitmap: to load several as one segment, combine them first (RoaringBitmap32.orMany) and serialize the result.`
364
- );
365
- }
366
- try {
367
- return new _SafeBitmap(RoaringBitmap32.deserialize(bytes, DeserializationFormat.portable));
368
- } catch (err) {
369
- throw new IntegrityError2(`failed to deserialize bitmap: ${err.message}`);
1558
+ throw trailingBytes(bytes.byteLength, end);
370
1559
  }
1560
+ let size = 0;
1561
+ for (let i = 0; i < conts.length; i++) size += conts[i].card;
1562
+ return new _TsBitmap(keys, conts, size);
371
1563
  }
372
1564
  serialize() {
373
- return this.bitmap.serialize(SerializationFormat.portable);
1565
+ return serializeContainers(this.#keys, this.#conts);
374
1566
  }
375
- /**
376
- * Convert containers to run-encoding where that is smaller. Representation only — membership is untouched, and
377
- * the portable format still round-trips through {@link RoaringCodec.safeDeserialize}.
378
- *
379
- * Roaring's third container type is a RUN, and no implementation selects it on its own: it takes an explicit
380
- * `runOptimize()` pass. Nothing here made that call, so run-shaped ids paid array or bitset prices — measured
381
- * at **570×** for a contiguous 1M-id range (128.1 KiB → 0.2 KiB) and **63×** for a 2,000-run shape
382
- * (536.5 KiB → 8.5 KiB). Sparse ids come out byte-identical, so this is never a losing trade; roaring keeps
383
- * whichever encoding is smaller per container.
384
- *
385
- * Those two factors are THIS CALL's own before/after on the same ids. They are not the ones the site quotes
386
- * (543× and 63×) — those compare the optimized encoding against the best *fixed* representation at its floor,
387
- * a different baseline that happens to land near 63× on the run shape too. `pnpm bench:encoding` prints both
388
- * columns; don't carry a figure between them without checking which denominator it had.
389
- *
390
- * Called only when writing an immutable objects generation — see {@link CodecBitmap.optimize} for why the read
391
- * path deliberately does not.
392
- *
393
- * CANONICAL, which `runOptimize()` alone is not. Where a container's run and array encodings are the same size
394
- * (cardinality = 2 × runs + 1: three values in one run, five in two), CRoaring keeps whichever kind the
395
- * container already has. A chunk built from ids starts as an array and stays one; the same set reached through
396
- * `addRange`, an earlier `runOptimize()` or an operation over run containers is a run, and serializes to other
397
- * bytes. Undoing run compression first starts every container where one built from ids starts, so the bytes
398
- * depend on membership alone. On a bitmap built from ids there is nothing to undo.
399
- */
1567
+ /** Re-encode each container canonically; membership is untouched. */
400
1568
  optimize() {
401
- this.bitmap.removeRunCompression();
402
- this.bitmap.runOptimize();
1569
+ const conts = this.#conts;
1570
+ for (let i = 0; i < conts.length; i++) conts[i] = optimize(conts[i]);
403
1571
  }
404
1572
  /**
405
- * This set as storage chunks, cut from its own containers: {@link optimize} and one `serialize` when called, then
406
- * a lazy header walk that copies one container out per step (`containerPayloads`). Per container and per byte,
407
- * never per id, and the payloads are the ones {@link SafeBitmap.fromValues} of each chunk's low 16 bits would
408
- * serialize to. The walk trusts the bytes it cuts because the native serializer wrote them, from a bitmap that
409
- * passed the structural check when it was decoded.
1573
+ * The set as storage chunks: each payload is the portable bytes of a one-container bitmap holding that chunk's low 16
1574
+ * bits, optimized the way {@link optimize} does. Nothing is built until a chunk is asked for, so a writer that yields
1575
+ * between chunks runs this in slices. The call snapshots the containers and marks each shared, so a change to the
1576
+ * bitmap while the chunks are read copies a container instead of altering what the chunks will say. The bitmap's own
1577
+ * containers are not optimized by it.
410
1578
  */
411
1579
  encodeChunks() {
412
- this.optimize();
413
- return containerPayloads(this.serialize());
1580
+ const keys = this.#keys.slice();
1581
+ const conts = this.#conts.slice();
1582
+ for (let i = 0; i < conts.length; i++) conts[i].shared = true;
1583
+ return {
1584
+ *[Symbol.iterator]() {
1585
+ for (let i = 0; i < conts.length; i++) {
1586
+ const c = optimize(conts[i]);
1587
+ yield {
1588
+ chunkKey: keys[i],
1589
+ payload: serializeContainers([0], [c]),
1590
+ cardinality: c.card
1591
+ };
1592
+ }
1593
+ }
1594
+ };
414
1595
  }
415
- /**
416
- * Largest value, or `undefined` when empty. O(1) — roaring reads it off the last container, so the engine's
417
- * per-chunk range assertion costs one call per chunk rather than a walk per id. The last container holds the
418
- * largest value only because {@link SafeBitmap.safeDeserialize} refuses bytes whose containers or values are
419
- * out of order.
420
- */
421
1596
  maximum() {
422
- return this.bitmap.isEmpty ? void 0 : this.bitmap.maximum();
1597
+ const last = this.#conts.length - 1;
1598
+ if (last < 0) return void 0;
1599
+ return this.#keys[last] * 65536 + containerMax(this.#conts[last]);
423
1600
  }
424
1601
  add(value) {
425
- this.bitmap.add(value);
1602
+ checkedId(value);
1603
+ const key = value >>> 16;
1604
+ const low = value & 65535;
1605
+ const at = lowerBound2(this.#keys, key);
1606
+ const found = this.#keys[at] === key;
1607
+ if (!found) {
1608
+ this.#insert(at, key, arrayContainer(Uint16Array.of(low), 1));
1609
+ this.#size++;
1610
+ return;
1611
+ }
1612
+ const before = this.#conts[at];
1613
+ const after = containerAdd(before, low);
1614
+ this.#conts[at] = after;
1615
+ this.#size += after.card - before.card;
426
1616
  }
1617
+ /**
1618
+ * Add the ids. They are grouped by key in ascending order, so each container is touched once, a key already held is
1619
+ * merged where it is, and the new keys are put in with one pass over the key list however many there are.
1620
+ */
427
1621
  addMany(values) {
428
- this.bitmap.addMany(values);
1622
+ const ids = sortedIds(collect(values), !(values instanceof Uint32Array));
1623
+ const fresh = [];
1624
+ let at = 0;
1625
+ for (let i = 0; i < ids.length; ) {
1626
+ const key = ids[i] >>> 16;
1627
+ let end = i + 1;
1628
+ while (end < ids.length && ids[end] >>> 16 === key) end++;
1629
+ const group = fromSortedIds(ids, i, end);
1630
+ i = end;
1631
+ at = gallopKeys(this.#keys, key, at);
1632
+ if (this.#keys[at] === key) {
1633
+ const before = this.#conts[at];
1634
+ const after = containerOr(before, group, !before.shared);
1635
+ this.#conts[at] = after;
1636
+ this.#size += after.card - before.card;
1637
+ } else {
1638
+ fresh.push({ key, group });
1639
+ this.#size += group.card;
1640
+ }
1641
+ }
1642
+ if (fresh.length > 0) this.#insertAll(fresh);
429
1643
  }
430
1644
  remove(value) {
431
- this.bitmap.remove(value);
1645
+ if (!isId(value)) return;
1646
+ const key = value >>> 16;
1647
+ const at = lowerBound2(this.#keys, key);
1648
+ if (this.#keys[at] !== key) return;
1649
+ const before = this.#conts[at];
1650
+ const after = containerRemove(before, value & 65535);
1651
+ if (after === null) {
1652
+ this.#keys.splice(at, 1);
1653
+ this.#conts.splice(at, 1);
1654
+ this.#size -= before.card;
1655
+ return;
1656
+ }
1657
+ this.#conts[at] = after;
1658
+ this.#size += after.card - before.card;
432
1659
  }
1660
+ /** Remove the ids (anything that is not an id is ignored), grouped by key; the keys left empty go in one pass. */
433
1661
  removeMany(values) {
434
- this.bitmap.removeMany(values);
1662
+ const ids = sortedIds(collectLenient(values), true);
1663
+ const keys = this.#keys;
1664
+ const conts = this.#conts;
1665
+ let at = 0;
1666
+ let emptied = 0;
1667
+ for (let i = 0; i < ids.length; ) {
1668
+ const key = ids[i] >>> 16;
1669
+ let end = i + 1;
1670
+ while (end < ids.length && ids[end] >>> 16 === key) end++;
1671
+ const from = i;
1672
+ i = end;
1673
+ at = gallopKeys(keys, key, at);
1674
+ if (keys[at] !== key) continue;
1675
+ const before = conts[at];
1676
+ if (before.card === 0) continue;
1677
+ const after = containerAndNot(before, fromSortedIds(ids, from, end), !before.shared);
1678
+ this.#size -= before.card - (after === null ? 0 : after.card);
1679
+ if (after === null) {
1680
+ conts[at] = EMPTIED;
1681
+ emptied++;
1682
+ } else {
1683
+ conts[at] = after;
1684
+ }
1685
+ }
1686
+ if (emptied > 0) this.#dropEmptied();
435
1687
  }
436
1688
  has(value) {
437
- return this.bitmap.has(value);
1689
+ if (!isId(value)) return false;
1690
+ const key = value >>> 16;
1691
+ const at = lowerBound2(this.#keys, key);
1692
+ return this.#keys[at] === key && containerHas(this.#conts[at], value & 65535);
438
1693
  }
439
1694
  get size() {
440
- return this.bitmap.size;
1695
+ return this.#size;
441
1696
  }
442
1697
  get isEmpty() {
443
- return this.bitmap.isEmpty;
1698
+ return this.#size === 0;
444
1699
  }
445
1700
  clone() {
446
- return new _SafeBitmap(this.bitmap.clone());
1701
+ const conts = new Array(this.#conts.length);
1702
+ for (let i = 0; i < conts.length; i++) {
1703
+ const c = this.#conts[i];
1704
+ c.shared = true;
1705
+ conts[i] = c;
1706
+ }
1707
+ return new _TsBitmap(this.#keys.slice(), conts, this.#size);
447
1708
  }
448
- // The binary set ops take the `CodecBitmap` interface type (per the seam), but a single store is
449
- // single-codec (homogeneity contract), so `other` is always a `SafeBitmap` here — reach its private
450
- // `bitmap` (accessible on same-class instances) for the native op.
451
- /** In-place union: `this = this ∪ other`. */
452
1709
  orInPlace(other) {
453
- this.bitmap.orInPlace(other.bitmap);
454
- }
455
- /** In-place difference: `this = this \ other`. */
456
- andNotInPlace(other) {
457
- this.bitmap.andNotInPlace(other.bitmap);
1710
+ this.#combine(_TsBitmap.#of(other), OR);
458
1711
  }
459
- /** In-place intersection: `this = this ∩ other`. */
460
1712
  andInPlace(other) {
461
- this.bitmap.andInPlace(other.bitmap);
1713
+ this.#combine(_TsBitmap.#of(other), AND);
1714
+ }
1715
+ andNotInPlace(other) {
1716
+ this.#combine(_TsBitmap.#of(other), AND_NOT);
462
1717
  }
463
- /** Ascending iterator over the set values. */
464
1718
  [Symbol.iterator]() {
465
- return this.bitmap[Symbol.iterator]();
1719
+ return new BitmapIterator(this.#keys, this.#conts);
466
1720
  }
467
1721
  toArray() {
468
- return this.bitmap.toArray();
1722
+ return Array.from(this.toUint32Array());
469
1723
  }
470
- /** The values as one fresh ascending `Uint32Array`, exported natively. */
1724
+ /** The ids as a new ascending `Uint32Array`. */
471
1725
  toUint32Array() {
472
- return this.bitmap.toUint32Array();
1726
+ const out = new Uint32Array(this.#size);
1727
+ let at = 0;
1728
+ for (let i = 0; i < this.#conts.length; i++) {
1729
+ at = appendIds(this.#conts[i], out, at, this.#keys[i] * 65536);
1730
+ }
1731
+ return out;
473
1732
  }
1733
+ static #of(other) {
1734
+ if (!(other instanceof _TsBitmap)) {
1735
+ throw new ValidationError2("a TypeScript roaring bitmap combines only with another one");
1736
+ }
1737
+ return other;
1738
+ }
1739
+ #insert(at, key, container) {
1740
+ if (at === this.#keys.length) {
1741
+ this.#keys.push(key);
1742
+ this.#conts.push(container);
1743
+ } else {
1744
+ this.#keys.splice(at, 0, key);
1745
+ this.#conts.splice(at, 0, container);
1746
+ }
1747
+ }
1748
+ /** Put the new keys, ascending and none held, in: after the last key by pushing, else in one merge pass. */
1749
+ #insertAll(fresh) {
1750
+ const keys = this.#keys;
1751
+ const conts = this.#conts;
1752
+ if (keys.length === 0 || keys[keys.length - 1] < fresh[0].key) {
1753
+ for (const { key, group } of fresh) {
1754
+ keys.push(key);
1755
+ conts.push(group);
1756
+ }
1757
+ return;
1758
+ }
1759
+ const outKeys = [];
1760
+ const outConts = [];
1761
+ let i = 0;
1762
+ let j = 0;
1763
+ while (i < keys.length || j < fresh.length) {
1764
+ if (j === fresh.length || i < keys.length && keys[i] < fresh[j].key) {
1765
+ outKeys.push(keys[i]);
1766
+ outConts.push(conts[i++]);
1767
+ } else {
1768
+ const next = fresh[j++];
1769
+ outKeys.push(next.key);
1770
+ outConts.push(next.group);
1771
+ }
1772
+ }
1773
+ this.#keys = outKeys;
1774
+ this.#conts = outConts;
1775
+ }
1776
+ /** Remove the keys whose container was emptied by {@link removeMany}, in one pass. */
1777
+ #dropEmptied() {
1778
+ let kept = 0;
1779
+ for (let i = 0; i < this.#conts.length; i++) {
1780
+ if (this.#conts[i] === EMPTIED) continue;
1781
+ this.#keys[kept] = this.#keys[i];
1782
+ this.#conts[kept++] = this.#conts[i];
1783
+ }
1784
+ this.#keys.length = kept;
1785
+ this.#conts.length = kept;
1786
+ }
1787
+ /**
1788
+ * Walk both key lists and rebuild this one: where both hold a key, the combine of the two containers; where only this
1789
+ * does, its container, unless the operation is an intersection; where only `that` does, a copy of its container for a
1790
+ * union and nothing otherwise. A combine that leaves no value drops the key. An intersection jumps over a stretch of
1791
+ * keys the other side lacks by doubling steps, so a few keys against many cost the few.
1792
+ */
1793
+ #combine(that, op) {
1794
+ const a = this.#keys;
1795
+ const b = that.#keys;
1796
+ const ca = this.#conts;
1797
+ const cb = that.#conts;
1798
+ const keys = [];
1799
+ const conts = [];
1800
+ let size = 0;
1801
+ let i = 0;
1802
+ let j = 0;
1803
+ while (i < a.length && j < b.length) {
1804
+ const ka = a[i];
1805
+ const kb = b[j];
1806
+ if (ka === kb) {
1807
+ const c = combineContainers(op, ca[i++], cb[j++]);
1808
+ if (c !== null) {
1809
+ keys.push(ka);
1810
+ conts.push(c);
1811
+ size += c.card;
1812
+ }
1813
+ } else if (ka < kb) {
1814
+ if (op === AND) {
1815
+ i = gallopKeys(a, kb, i + 1);
1816
+ } else {
1817
+ keys.push(ka);
1818
+ conts.push(ca[i]);
1819
+ size += ca[i++].card;
1820
+ }
1821
+ } else if (op === AND) {
1822
+ j = gallopKeys(b, ka, j + 1);
1823
+ } else {
1824
+ if (op === OR) {
1825
+ keys.push(kb);
1826
+ conts.push(cloneContainer(cb[j]));
1827
+ size += cb[j].card;
1828
+ }
1829
+ j++;
1830
+ }
1831
+ }
1832
+ if (op !== AND) {
1833
+ for (; i < a.length; i++) {
1834
+ keys.push(a[i]);
1835
+ conts.push(ca[i]);
1836
+ size += ca[i].card;
1837
+ }
1838
+ }
1839
+ if (op === OR) {
1840
+ for (; j < b.length; j++) {
1841
+ keys.push(b[j]);
1842
+ conts.push(cloneContainer(cb[j]));
1843
+ size += cb[j].card;
1844
+ }
1845
+ }
1846
+ this.#keys = keys;
1847
+ this.#conts = conts;
1848
+ this.#size = size;
1849
+ }
1850
+ };
1851
+ var EMPTIED = arrayContainer(new Uint16Array(0), 0);
1852
+ var tsRoaringCodec = {
1853
+ empty: () => TsBitmap.empty(),
1854
+ fromValues: (values) => TsBitmap.fromValues(values),
1855
+ safeDeserialize: (bytes, maxBytes, options) => TsBitmap.safeDeserialize(bytes, maxBytes, options),
1856
+ owns: (bitmap) => bitmap instanceof TsBitmap,
1857
+ intersectSmallestFirst: true
474
1858
  };
1859
+
1860
+ // src/roaring-codec.ts
475
1861
  function bitmapAsLoadInput(input) {
476
- return input instanceof RoaringBitmap32 || input instanceof ReadonlyRoaringView ? { bitmap: input } : input;
1862
+ if (typeof input !== "object" || input === null) return input;
1863
+ const tag = Object.prototype.toString.call(input).slice(8, -1);
1864
+ if (tag === "Uint8Array" || tag === "Uint8ClampedArray") return input;
1865
+ return Symbol.iterator in input && typeof input.serialize === "function" ? { bitmap: input } : input;
1866
+ }
1867
+ var activeCodec = tsRoaringCodec;
1868
+ function flagshipCodec() {
1869
+ return activeCodec;
477
1870
  }
478
- var roaringCodec = {
479
- empty: () => SafeBitmap.empty(),
480
- fromValues: (values) => SafeBitmap.fromValues(values),
481
- safeDeserialize: (bytes, maxBytes, options) => SafeBitmap.safeDeserialize(bytes, maxBytes, options),
482
- owns: (bitmap) => bitmap instanceof SafeBitmap
483
- };
484
1871
  var ReadonlyRoaringView = class {
485
1872
  #bitmap;
486
1873
  constructor(bitmap) {
@@ -499,7 +1886,7 @@ var ReadonlyRoaringView = class {
499
1886
  serialize(...args) {
500
1887
  if (args.length !== 1 || args[0] !== "portable") {
501
1888
  const got = args.length === 0 ? "no argument" : args.map((a) => typeof a === "string" ? `'${a}'` : typeof a).join(", ");
502
- throw new ValidationError2(
1889
+ throw new ValidationError3(
503
1890
  `a decoded bitmap serializes only as serialize('portable'); got ${got}`
504
1891
  );
505
1892
  }
@@ -507,7 +1894,7 @@ var ReadonlyRoaringView = class {
507
1894
  }
508
1895
  };
509
1896
  function deserializePortable(bytes) {
510
- return new ReadonlyRoaringView(decodeSerialized(bytes, roaringCodec));
1897
+ return new ReadonlyRoaringView(decodeSerialized(bytes, flagshipCodec()));
511
1898
  }
512
1899
 
513
1900
  // src/system-clock.ts
@@ -648,7 +2035,7 @@ import {
648
2035
  DEFAULT_RETRY_POLICY,
649
2036
  NOOP_METRICS,
650
2037
  RetryingStorageChunkSource,
651
- ValidationError as ValidationError3,
2038
+ ValidationError as ValidationError4,
652
2039
  isStorageBackend
653
2040
  } from "@cloudbitmaps/core";
654
2041
  function resolveRetryPolicy(partial) {
@@ -672,7 +2059,7 @@ function wireStore(options, clock, rng, metrics) {
672
2059
  if (options.retry !== false) {
673
2060
  const { onRetry: userOnRetry, ...ov } = options.retry ?? {};
674
2061
  if (userOnRetry !== void 0 && typeof userOnRetry !== "function") {
675
- throw new ValidationError3("retry.onRetry must be a function");
2062
+ throw new ValidationError4("retry.onRetry must be a function");
676
2063
  }
677
2064
  retryOptions = {
678
2065
  clock,
@@ -703,7 +2090,7 @@ function wireStore(options, clock, rng, metrics) {
703
2090
  function resolveStorageSource(options, clock) {
704
2091
  const storage = options.storage;
705
2092
  if (storage === null || typeof storage !== "object") {
706
- throw new ValidationError3(
2093
+ throw new ValidationError4(
707
2094
  "`storage` must be a StorageBackend, an IStorageDriver, or a StorageChunkSource"
708
2095
  );
709
2096
  }
@@ -713,14 +2100,14 @@ function resolveStorageSource(options, clock) {
713
2100
  const hasPutImmutable = typeof storage.putImmutable === "function";
714
2101
  const isBackend = isStorageBackend(storage);
715
2102
  if (isBackend && (hasGetChunk || hasPutImmutable)) {
716
- throw new ValidationError3(
2103
+ throw new ValidationError4(
717
2104
  `\`storage\` is a StorageBackend that also exposes ${hasGetChunk ? "`getChunk`" : "`putImmutable`"} \u2014 ambiguous. A backend must not also be a driver or a source; pass whichever one you mean.`
718
2105
  );
719
2106
  }
720
2107
  const hasStorageHalf = isObject(asBackend.storage);
721
2108
  const hasRegistryHalf = isObject(asBackend.registry);
722
2109
  if (!isBackend && hasPutImmutable && hasRegistryHalf) {
723
- throw new ValidationError3(
2110
+ throw new ValidationError4(
724
2111
  "`storage` looks like a driver that also carries a `registry`. Passed as a bare driver it would have no pointer at all \u2014 generations would resolve by list-scan, so reads could serve a generation that was written but never published. If you meant a backend, use a backend class \u2014 S3Storage, GcsStorage, AzureBlobStorage, LocalFsStorage or MemoryStorage \u2014 or, to pair a driver of your own with a registry, brand the pair with `brandAsBackend` from `@cloudbitmaps/core/driver-kit`."
725
2112
  );
726
2113
  }
@@ -729,11 +2116,11 @@ function resolveStorageSource(options, clock) {
729
2116
  const registryOk = typeof asBackend.registry.compareAndSwap === "function";
730
2117
  if (!storageOk || !registryOk) {
731
2118
  const bad = !storageOk ? "`storage` half is not an IStorageDriver (no `putImmutable`)" : "`registry` half is not an IRegistryDriver (no `compareAndSwap`)";
732
- throw new ValidationError3(
2119
+ throw new ValidationError4(
733
2120
  "`storage` looks like a backend but its " + bad + " \u2014 use a backend class, or brand a pair of drivers with `brandAsBackend` from `@cloudbitmaps/core/driver-kit`."
734
2121
  );
735
2122
  }
736
- throw new ValidationError3(
2123
+ throw new ValidationError4(
737
2124
  "`storage` must be a backend \u2014 S3Storage, GcsStorage, AzureBlobStorage, LocalFsStorage or MemoryStorage. An object with `.storage` and `.registry` is not one: a backend builds both halves from a single bucket and prefix, so they cannot disagree, and hand-assembling them re-opens exactly that mismatch \u2014 a store whose pointer and generations live in different places reads as empty rather than failing. A driver author who genuinely wants halves of their own \u2014 an instrumented driver, a registry in a database you already run \u2014 brands the pair with `brandAsBackend` from `@cloudbitmaps/core/driver-kit`, which is taking on that they agree."
738
2125
  );
739
2126
  }
@@ -754,18 +2141,18 @@ function resolveStorageSource(options, clock) {
754
2141
  };
755
2142
  }
756
2143
  if (hasGetChunk && hasPutImmutable) {
757
- throw new ValidationError3(
2144
+ throw new ValidationError4(
758
2145
  "`storage` exposes both `getChunk` and `putImmutable` \u2014 ambiguous; pass a StorageBackend, an IStorageDriver, or a StorageChunkSource, not a hybrid"
759
2146
  );
760
2147
  }
761
2148
  if (!hasGetChunk && !hasPutImmutable) {
762
- throw new ValidationError3(
2149
+ throw new ValidationError4(
763
2150
  "`storage` must be a StorageBackend, an IStorageDriver, or a StorageChunkSource"
764
2151
  );
765
2152
  }
766
2153
  if (hasGetChunk) {
767
2154
  if (options.encryption?.keystore !== void 0 || options.encryption?.required === true) {
768
- throw new ValidationError3(
2155
+ throw new ValidationError4(
769
2156
  "keystore/requireEncryption apply only when the store builds its own read path: a StorageChunkSource of your own reads an encrypted segment by itself, if it must; to have the store decrypt, pass a backend"
770
2157
  );
771
2158
  }
@@ -787,32 +2174,32 @@ function resolveStorageSource(options, clock) {
787
2174
  }
788
2175
 
789
2176
  // src/options.ts
790
- import { ValidationError as ValidationError4 } from "@cloudbitmaps/core";
2177
+ import { ValidationError as ValidationError5 } from "@cloudbitmaps/core";
791
2178
  var keysOf = () => (keys) => keys;
792
2179
  var kindOf = (v) => v === null ? "null" : Array.isArray(v) ? "an array" : `a ${typeof v}`;
793
2180
  function optionsError(options, op, known, booleans = [], misplaced = []) {
794
2181
  if (options === void 0 || options === null) return void 0;
795
2182
  if (typeof options !== "object" || Array.isArray(options)) {
796
- return new ValidationError4(`${op}: options must be an object; got ${kindOf(options)}`);
2183
+ return new ValidationError5(`${op}: options must be an object; got ${kindOf(options)}`);
797
2184
  }
798
2185
  const bag = options;
799
2186
  const unknown = Object.keys(bag).filter((k) => !known.includes(k) && bag[k] !== void 0);
800
2187
  for (const k of misplaced) if (!unknown.includes(k) && bag[k] !== void 0) unknown.push(k);
801
2188
  if (unknown.length > 0) {
802
- return new ValidationError4(
2189
+ return new ValidationError5(
803
2190
  `${op}: unknown option${unknown.length > 1 ? "s" : ""} ${unknown.map((k) => `"${k}"`).join(", ")}; it takes { ${known.join(", ")} }`
804
2191
  );
805
2192
  }
806
2193
  const audit = bag.audit;
807
2194
  if (audit !== void 0 && audit !== null && typeof audit.onEvent !== "function") {
808
- return new ValidationError4(
2195
+ return new ValidationError5(
809
2196
  `${op}: audit must be a sink with an onEvent(event) method, such as a RecordingAuditSink`
810
2197
  );
811
2198
  }
812
2199
  for (const name of booleans) {
813
2200
  const v = bag[name];
814
2201
  if (v !== void 0 && typeof v !== "boolean") {
815
- return new ValidationError4(`${op}: \`${name}\` must be a boolean; got ${kindOf(v)}`);
2202
+ return new ValidationError5(`${op}: \`${name}\` must be a boolean; got ${kindOf(v)}`);
816
2203
  }
817
2204
  }
818
2205
  return void 0;
@@ -837,9 +2224,9 @@ import {
837
2224
  excludingReservedRows as excludingReservedRows2,
838
2225
  readRetentionPolicy,
839
2226
  CloudRoaringError,
840
- ValidationError as ValidationError6,
2227
+ ValidationError as ValidationError7,
841
2228
  WriteConflictError as WriteConflictError2,
842
- IntegrityError as IntegrityError3,
2229
+ IntegrityError as IntegrityError4,
843
2230
  NotFoundError as NotFoundError2,
844
2231
  UnsupportedError as UnsupportedError3,
845
2232
  CapabilityError,
@@ -871,7 +2258,7 @@ function eraseNamespace(namespace, deps, options) {
871
2258
  }
872
2259
  function validateRef(ref, verb) {
873
2260
  if (typeof ref !== "object" || ref === null) {
874
- throw new ValidationError5(
2261
+ throw new ValidationError6(
875
2262
  "a segment ref is an object such as { segment: 'name' }; store.segment() takes the bare name"
876
2263
  );
877
2264
  }
@@ -892,7 +2279,7 @@ function validateConcurrency(concurrency) {
892
2279
  function requireScope(options, op) {
893
2280
  if (options.namespace !== void 0) {
894
2281
  if (typeof options.namespace !== "string") {
895
- throw new ValidationError5(
2282
+ throw new ValidationError6(
896
2283
  `${op}: namespace must be a string; got ${kindOf(options.namespace)}`
897
2284
  );
898
2285
  }
@@ -900,12 +2287,12 @@ function requireScope(options, op) {
900
2287
  }
901
2288
  refuseReservedNamespace(options.namespace);
902
2289
  if (options.namespace !== void 0 && options.allNamespaces === true) {
903
- throw new ValidationError5(
2290
+ throw new ValidationError6(
904
2291
  `${op}: pass a namespace or { allNamespaces: true }, not both: with both, it is unclear whether to scan one namespace or every one`
905
2292
  );
906
2293
  }
907
2294
  if (options.namespace === void 0 && options.allNamespaces !== true) {
908
- throw new ValidationError5(
2295
+ throw new ValidationError6(
909
2296
  `${op} scans the global id space across all namespaces \u2014 pass an explicit \`namespace\`, or \`{ allNamespaces: true }\` to intentionally sweep the whole fleet`
910
2297
  );
911
2298
  }
@@ -1013,16 +2400,16 @@ var originOf;
1013
2400
  function assertOneStore(verb, role, h, origin) {
1014
2401
  if (h instanceof Segment) {
1015
2402
  if (originOf(h) === origin) return;
1016
- throw new ValidationError5(
2403
+ throw new ValidationError6(
1017
2404
  `${verb}: ${role} belongs to another store; combine segments of one store: open each with this store's segment()`
1018
2405
  );
1019
2406
  }
1020
2407
  if (typeof h === "object" && h !== null && h[SEGMENT_BRAND] === true) {
1021
- throw new ValidationError5(
2408
+ throw new ValidationError6(
1022
2409
  `${verb}: ${role} comes from another installed copy of @cloudbitmaps/roaring, so it belongs to another store; install one copy and combine segments of one store`
1023
2410
  );
1024
2411
  }
1025
- throw new ValidationError5(`${verb}: ${role} must be a segment from this store's segment()`);
2412
+ throw new ValidationError6(`${verb}: ${role} must be a segment from this store's segment()`);
1026
2413
  }
1027
2414
  var MATERIALIZE_MANY_KEYS = [
1028
2415
  "operands",
@@ -1112,7 +2499,7 @@ var CloudRoaring = class _CloudRoaring {
1112
2499
  */
1113
2500
  static rejectUnknownOptions(options) {
1114
2501
  if (options === null || options === void 0 || typeof options !== "object") {
1115
- throw new ValidationError5(
2502
+ throw new ValidationError6(
1116
2503
  "CloudRoaring needs an options object with a `storage` key \u2014 got " + (options === null ? "null" : typeof options)
1117
2504
  );
1118
2505
  }
@@ -1130,7 +2517,7 @@ var CloudRoaring = class _CloudRoaring {
1130
2517
  const tag = Object.prototype.toString.call(value).slice(8, -1);
1131
2518
  if (typeof value !== "object" || value === null || NOT_A_GROUP[tag] !== void 0) {
1132
2519
  const got = typeof value !== "object" ? typeof value : NOT_A_GROUP[tag];
1133
- throw new ValidationError5(
2520
+ throw new ValidationError6(
1134
2521
  `CloudRoaring's \`${group}\` must be an object${offOk ? " or `false`" : ""} \u2014 got ${got}`
1135
2522
  );
1136
2523
  }
@@ -1140,7 +2527,7 @@ var CloudRoaring = class _CloudRoaring {
1140
2527
  if (unknown.length === 0) return;
1141
2528
  const takes = (keys) => keys.map((k) => `\`${k}\``).join(", ");
1142
2529
  const named = [...new Set(unknown.map((u) => u.group))];
1143
- throw new ValidationError5(
2530
+ throw new ValidationError6(
1144
2531
  `CloudRoaring does not take ${takes(unknown.map((u) => u.group === null ? u.key : `${u.group}.${u.key}`))}. ` + named.map(
1145
2532
  (g) => g === null ? `The store takes ${takes(OPTION_KEYS.top)}.` : `\`${g}\` takes ${takes(OPTION_KEYS[g])}.`
1146
2533
  ).join(" ") + " https://github.com/cloudbitmaps/cloudbitmaps/blob/main/docs/guide/api-reference.md#build-a-store--new-cloudroaringoptions"
@@ -1158,7 +2545,7 @@ var CloudRoaring = class _CloudRoaring {
1158
2545
  ];
1159
2546
  const entropy = options.seams?.entropy;
1160
2547
  if (entropy !== void 0 && typeof entropy !== "function") {
1161
- throw new ValidationError5(
2548
+ throw new ValidationError6(
1162
2549
  "CloudRoaring's `seams.entropy` must be a function `(length) => Uint8Array` returning that many random bytes"
1163
2550
  );
1164
2551
  }
@@ -1166,7 +2553,7 @@ var CloudRoaring = class _CloudRoaring {
1166
2553
  if (seam === void 0) continue;
1167
2554
  const has = (m) => seam !== null && typeof seam[m] === "function";
1168
2555
  if (seam === null || typeof seam !== "object" || !needs.every(has)) {
1169
- throw new ValidationError5(
2556
+ throw new ValidationError6(
1170
2557
  `CloudRoaring's \`${name}\` must be an object with ${needs.map((m) => `\`${m}()\``).join(" and ")}`
1171
2558
  );
1172
2559
  }
@@ -1186,7 +2573,7 @@ var CloudRoaring = class _CloudRoaring {
1186
2573
  requirePositiveInt("cache.readerMaxBytes", cache.readerMaxBytes);
1187
2574
  const ttl = cache.ttlMs;
1188
2575
  if (ttl !== void 0 && (typeof ttl !== "number" || !Number.isFinite(ttl) || ttl <= 0)) {
1189
- throw new ValidationError5(
2576
+ throw new ValidationError6(
1190
2577
  `cache.ttlMs must be a finite number above 0 (milliseconds); got ${typeof ttl === "string" ? JSON.stringify(ttl) : String(ttl)}`
1191
2578
  );
1192
2579
  }
@@ -1218,7 +2605,7 @@ var CloudRoaring = class _CloudRoaring {
1218
2605
  const deps = {
1219
2606
  storage: wired.storage,
1220
2607
  cache,
1221
- codec: roaringCodec,
2608
+ codec: flagshipCodec(),
1222
2609
  // the facade injects the flagship codec; core stays codec-agnostic
1223
2610
  clock,
1224
2611
  metrics,
@@ -1261,7 +2648,7 @@ var CloudRoaring = class _CloudRoaring {
1261
2648
  clock: this.clock,
1262
2649
  rng: this.rng,
1263
2650
  entropy: this.entropy,
1264
- codec: roaringCodec,
2651
+ codec: flagshipCodec(),
1265
2652
  // facade injects the flagship codec
1266
2653
  keystore: this.keystore,
1267
2654
  requireEncryption: this.requireEncryption,
@@ -1278,17 +2665,17 @@ var CloudRoaring = class _CloudRoaring {
1278
2665
  */
1279
2666
  segment(name, options) {
1280
2667
  if (typeof name === "object" && name !== null) {
1281
- throw new ValidationError5(
2668
+ throw new ValidationError6(
1282
2669
  Array.isArray(name) ? "segment: the name is a string, store.segment('name'), not an array" : "segment: the name is a string, not a ref: for a ref, call store.segment(ref.segment, { namespace: ref.namespace })"
1283
2670
  );
1284
2671
  }
1285
2672
  if (options !== void 0 && options !== null) {
1286
2673
  if (typeof options !== "object" || Array.isArray(options)) {
1287
- throw new ValidationError5("segment: options must be an object such as { namespace }");
2674
+ throw new ValidationError6("segment: options must be an object such as { namespace }");
1288
2675
  }
1289
2676
  const proto = Object.getPrototypeOf(options);
1290
2677
  if (proto !== null && Object.getPrototypeOf(proto) !== null) {
1291
- throw new ValidationError5(
2678
+ throw new ValidationError6(
1292
2679
  "segment: options must be a plain object such as { namespace }, not a class instance or an object built on another"
1293
2680
  );
1294
2681
  }
@@ -1296,7 +2683,7 @@ var CloudRoaring = class _CloudRoaring {
1296
2683
  (k) => k !== "namespace" && options[k] !== void 0
1297
2684
  );
1298
2685
  if (unknown.length > 0) {
1299
- throw new ValidationError5(
2686
+ throw new ValidationError6(
1300
2687
  `segment: unknown option${unknown.length > 1 ? "s" : ""} ${unknown.map((k) => `"${k}"`).join(", ")}; a handle takes { namespace } only`
1301
2688
  );
1302
2689
  }
@@ -1406,20 +2793,20 @@ var CloudRoaring = class _CloudRoaring {
1406
2793
  /** The one body of the forms above. */
1407
2794
  async materializeMany(options) {
1408
2795
  if (typeof options !== "object" || options === null) {
1409
- throw new ValidationError5(
2796
+ throw new ValidationError6(
1410
2797
  "materializeMany needs an options object with `operands`, `outputs` and `keep`"
1411
2798
  );
1412
2799
  }
1413
2800
  const epochAt = options.feed === void 0 ? 0 : this.epochNow();
1414
2801
  const unknown = unknownManyKeys(options);
1415
2802
  if (unknown.length > 0) {
1416
- throw new ValidationError5(
2803
+ throw new ValidationError6(
1417
2804
  `materializeMany: unknown option${unknown.length > 1 ? "s" : ""} ${unknown.map((k) => `"${k}"`).join(", ")}`
1418
2805
  );
1419
2806
  }
1420
2807
  const dryRunIn = options.dryRun;
1421
2808
  if (dryRunIn !== void 0 && typeof dryRunIn !== "boolean") {
1422
- throw new ValidationError5("materializeMany: dryRun must be a boolean");
2809
+ throw new ValidationError6("materializeMany: dryRun must be a boolean");
1423
2810
  }
1424
2811
  const dryRun = dryRunIn === true;
1425
2812
  const operandsIn = options.operands;
@@ -1431,7 +2818,7 @@ var CloudRoaring = class _CloudRoaring {
1431
2818
  const feedIn = options.feed;
1432
2819
  const mayBeEmptyIn = options.mayBeEmpty;
1433
2820
  if (feedIn !== void 0 && options.maxBufferedBytes === void 0) {
1434
- throw new ValidationError5(
2821
+ throw new ValidationError6(
1435
2822
  "materializeMany: maxBufferedBytes is required with a feed: the feed is read once, so the call runs as one group and the budget is what bounds it"
1436
2823
  );
1437
2824
  }
@@ -1441,15 +2828,15 @@ var CloudRoaring = class _CloudRoaring {
1441
2828
  const budgetOption = options.budget;
1442
2829
  const allowAbsentOperands = options.allowAbsentOperands;
1443
2830
  if (typeof pinOption !== "boolean")
1444
- throw new ValidationError5("materializeMany: pin must be a boolean");
2831
+ throw new ValidationError6("materializeMany: pin must be a boolean");
1445
2832
  if (allowAbsentOperands !== void 0 && typeof allowAbsentOperands !== "boolean") {
1446
- throw new ValidationError5("materializeMany: allowAbsentOperands must be a boolean");
2833
+ throw new ValidationError6("materializeMany: allowAbsentOperands must be a boolean");
1447
2834
  }
1448
2835
  if (typeof operandsIn !== "object" || operandsIn === null || Array.isArray(operandsIn)) {
1449
- throw new ValidationError5("materializeMany: operands must be an object of name to segment");
2836
+ throw new ValidationError6("materializeMany: operands must be an object of name to segment");
1450
2837
  }
1451
2838
  if (!Array.isArray(outputsIn) || outputsIn.length === 0) {
1452
- throw new ValidationError5("materializeMany: outputs must be a non-empty array");
2839
+ throw new ValidationError6("materializeMany: outputs must be a non-empty array");
1453
2840
  }
1454
2841
  const names = Object.keys(operandsIn);
1455
2842
  const handles = /* @__PURE__ */ new Map();
@@ -1460,14 +2847,14 @@ var CloudRoaring = class _CloudRoaring {
1460
2847
  }
1461
2848
  if (mayBeEmptyIn !== void 0 && feedIn === void 0) {
1462
2849
  if (!Array.isArray(mayBeEmptyIn)) {
1463
- throw new ValidationError5(
2850
+ throw new ValidationError6(
1464
2851
  "materializeMany: mayBeEmpty must be an array of fed operand names"
1465
2852
  );
1466
2853
  }
1467
2854
  if (mayBeEmptyIn.length > 0) {
1468
2855
  const first = mayBeEmptyIn[0];
1469
2856
  const what = typeof first !== "string" ? "something that is not a name" : handles.has(first) ? `"${first}", a stored operand` : `"${first}", which is not an operand of this call`;
1470
- throw new ValidationError5(
2857
+ throw new ValidationError6(
1471
2858
  `materializeMany: mayBeEmpty names ${what}; it names fed operands, and this call has no feed`
1472
2859
  );
1473
2860
  }
@@ -1477,13 +2864,13 @@ var CloudRoaring = class _CloudRoaring {
1477
2864
  const destKeys = /* @__PURE__ */ new Set();
1478
2865
  outputsIn.forEach((raw, i) => {
1479
2866
  if (typeof raw !== "object" || raw === null) {
1480
- throw new ValidationError5(`outputs[${i}] must be an object`);
2867
+ throw new ValidationError6(`outputs[${i}] must be an object`);
1481
2868
  }
1482
2869
  const bad = Object.keys(raw).filter(
1483
2870
  (k) => !MATERIALIZE_MANY_OUTPUT_KEYS.includes(k)
1484
2871
  );
1485
2872
  if (bad.length > 0) {
1486
- throw new ValidationError5(
2873
+ throw new ValidationError6(
1487
2874
  `outputs[${i}]: unknown option${bad.length > 1 ? "s" : ""} ${bad.map((k) => `"${k}"`).join(", ")}`
1488
2875
  );
1489
2876
  }
@@ -1491,12 +2878,12 @@ var CloudRoaring = class _CloudRoaring {
1491
2878
  const dest = spec.dest;
1492
2879
  assertOneStore("materializeMany", `outputs[${i}].dest`, dest, this.origin);
1493
2880
  if (operandKeys.has(dest.key())) {
1494
- throw new ValidationError5(
2881
+ throw new ValidationError6(
1495
2882
  `outputs[${i}].dest is also an operand of the call: one call is one pass over operands that do not change under it, so chain two calls`
1496
2883
  );
1497
2884
  }
1498
2885
  if (destKeys.has(dest.key())) {
1499
- throw new ValidationError5(
2886
+ throw new ValidationError6(
1500
2887
  `outputs[${i}].dest names a segment another output of the call writes`
1501
2888
  );
1502
2889
  }
@@ -1569,13 +2956,13 @@ var CloudRoaring = class _CloudRoaring {
1569
2956
  held.set(key, { at, handle });
1570
2957
  } else if (prior.at !== void 0 && at !== void 0) {
1571
2958
  if (!samePin(prior.at, at)) {
1572
- throw new ValidationError5(
2959
+ throw new ValidationError6(
1573
2960
  `materializeMany: operand "${name}" holds a segment another operand holds, ${twoPins(prior.at, at)}: one call reads a segment at one generation`
1574
2961
  );
1575
2962
  }
1576
2963
  } else if (prior.at !== void 0 || at !== void 0) {
1577
2964
  if (!pinOption) {
1578
- throw new ValidationError5(
2965
+ throw new ValidationError6(
1579
2966
  `materializeMany: operand "${name}" holds a segment another operand holds, ${twoPins(prior.at, at)}: one call reads a segment at one generation`
1580
2967
  );
1581
2968
  }
@@ -1603,7 +2990,7 @@ var CloudRoaring = class _CloudRoaring {
1603
2990
  const final = rebindCombineMany(compiled, operandSpecs(pins));
1604
2991
  return runCombineMany(final, {
1605
2992
  source,
1606
- codec: roaringCodec,
2993
+ codec: flagshipCodec(),
1607
2994
  clock: this.clock,
1608
2995
  ...metricsOn ? { metrics: this.metrics } : {}
1609
2996
  });
@@ -1663,7 +3050,7 @@ var CloudRoaring = class _CloudRoaring {
1663
3050
  /** A call's feed with the store's erasure counter: read once here, checked by the combine before any record is read. */
1664
3051
  feedOf(feed, mayBeEmpty, epochAt) {
1665
3052
  if (typeof feed !== "object" || feed === null || Array.isArray(feed)) {
1666
- throw new ValidationError5(
3053
+ throw new ValidationError6(
1667
3054
  "materializeMany: feed must be an object with names, records and counts"
1668
3055
  );
1669
3056
  }
@@ -2106,9 +3493,10 @@ var CloudRoaring = class _CloudRoaring {
2106
3493
  * `input` is ids (any sync or async iterable of integers in `[0, 2^32)`), or a whole bitmap: `{ bitmap }`, anything
2107
3494
  * with `serialize('portable')` such as `roaring`'s `RoaringBitmap32`, or `{ serialized }`, portable Roaring bytes.
2108
3495
  * A bitmap is checked (size cap, structure, safe deserializer) before the first request, written from its own
2109
- * containers with no per-id work, and gives the generation chunk for chunk what its ids would. A bare
2110
- * `RoaringBitmap32`, or a bitmap `deserializePortable` returned, passed as ids loads as `{ bitmap }`. A
2111
- * `Uint8Array` or `Buffer` passed as ids is refused with `ValidationError`, since each byte would load as an id:
3496
+ * containers with no per-id work, and gives the generation chunk for chunk what its ids would. An
3497
+ * iterable with a `serialize` method (a `RoaringBitmap32`, another copy's bitmap, or a bitmap `deserializePortable`
3498
+ * returned) passed as ids loads as `{ bitmap }` and is not iterated. A `Uint8Array` or `Buffer` passed as ids is
3499
+ * refused with `ValidationError`, since each byte would load as an id, even when it has a `serialize` of its own:
2112
3500
  * pass bytes as `{ serialized }`.
2113
3501
  *
2114
3502
  * Ids are held whole in memory before the object is written: the generation's bitmaps and a buffer of up to about 28
@@ -2210,7 +3598,7 @@ var CloudRoaring = class _CloudRoaring {
2210
3598
  const sameBackend = reads !== void 0 && (reads.origin === this.origin || this.registry !== void 0 && REGISTRY_OF.get(reads.origin) === this.registry);
2211
3599
  if (sameBackend && reads.keys.includes(segmentKey(ref))) {
2212
3600
  const named = ref.namespace === void 0 ? ref.segment : `${ref.namespace}/${ref.segment}`;
2213
- throw new ValidationError5(
3601
+ throw new ValidationError6(
2214
3602
  `load: the ids come from a read of the segment "${named}" that is being loaded, and a load publishes over whatever the segment is by then, so another process's newer load of it can be replaced by a result built from the one before, with no conflict reported. This release has no fenced in-place update: write the result into a new segment and point readers at it`
2215
3603
  );
2216
3604
  }
@@ -2274,7 +3662,7 @@ var CloudRoaring = class _CloudRoaring {
2274
3662
  async dropSegment(ref, options) {
2275
3663
  ref = validateRef(ref, "dropSegment");
2276
3664
  if (options === void 0 || options === null) {
2277
- throw new ValidationError5("dropSegment: options { confirmSegment } are required");
3665
+ throw new ValidationError6("dropSegment: options { confirmSegment } are required");
2278
3666
  }
2279
3667
  checkOptions(options, "dropSegment", CALL_KEYS.dropSegment, ["dryRun"]);
2280
3668
  const deps = this.lifecycleDeps("dropSegment");
@@ -2563,7 +3951,7 @@ var CloudRoaring = class _CloudRoaring {
2563
3951
  return new SegmentEngine({
2564
3952
  storage: this.retryOptions === void 0 ? pinned : new RetryingStorageChunkSource2(pinned, this.retryOptions),
2565
3953
  cache: this.cache,
2566
- codec: roaringCodec,
3954
+ codec: flagshipCodec(),
2567
3955
  clock: this.clock,
2568
3956
  metrics: this.metrics,
2569
3957
  budget: this.budget,
@@ -2593,7 +3981,7 @@ var CloudRoaring = class _CloudRoaring {
2593
3981
  if (held.has(key)) {
2594
3982
  const before = held.get(key);
2595
3983
  if (!samePin(before, at)) {
2596
- throw new ValidationError5(
3984
+ throw new ValidationError6(
2597
3985
  `the same segment is in this combine twice, ${twoPins(before, at)}: one call reads a segment at one generation, so materialise one of them into a segment of its own first, with \`materializeMany({ operands: { src: seg }, outputs: [{ dest, expr: { or: ['src'] } }], keep })\``
2598
3986
  );
2599
3987
  }
@@ -2727,7 +4115,7 @@ var CloudRoaring = class _CloudRoaring {
2727
4115
  checkOptions(options, "exportSegments", CALL_KEYS.exportSegments, [], MISPLACED.exportSegments);
2728
4116
  const opts = picked(options, CALL_KEYS.exportSegments);
2729
4117
  const registry = this.requireRegistry("exportSegments");
2730
- return runExport(this, registry, sink, { ...opts, codec: roaringCodec });
4118
+ return runExport(this, registry, sink, { ...opts, codec: flagshipCodec() });
2731
4119
  }
2732
4120
  };
2733
4121
  var withBatches = (gen, batches) => Object.assign(gen, { batches });
@@ -2755,7 +4143,7 @@ var readOptions = (options) => ({
2755
4143
  });
2756
4144
  var NO_SEGMENTS = [];
2757
4145
  function segmentList(list, what) {
2758
- if (!Array.isArray(list)) throw new ValidationError5(`${what} must be an array of segments`);
4146
+ if (!Array.isArray(list)) throw new ValidationError6(`${what} must be an array of segments`);
2759
4147
  return list;
2760
4148
  }
2761
4149
  var STREAM_SOURCES = /* @__PURE__ */ new WeakMap();
@@ -2768,7 +4156,7 @@ function operandsLabel(verb) {
2768
4156
  return verb === "andNot" ? "andNot: `excludes`" : `${verb}: \`others\``;
2769
4157
  }
2770
4158
  function refuseNoOperands(verb) {
2771
- throw new ValidationError5(
4159
+ throw new ValidationError6(
2772
4160
  verb === "intersect" ? "intersect requires at least one segment to intersect with; to read every id of one segment, use iterate()" : "intersectInto requires at least one segment to intersect with; to copy this segment into dest, call materializeMany({ operands: { src: thisSegment }, outputs: [{ dest, expr: { or: ['src'] } }], keep })"
2773
4161
  );
2774
4162
  }
@@ -2849,7 +4237,7 @@ var Segment = class _Segment {
2849
4237
  */
2850
4238
  constructor(parts) {
2851
4239
  if (!minting) {
2852
- throw new ValidationError5(
4240
+ throw new ValidationError6(
2853
4241
  "a Segment is not constructed directly; call `store.segment(name)`"
2854
4242
  );
2855
4243
  }
@@ -2963,11 +4351,11 @@ var Segment = class _Segment {
2963
4351
  leaseUntilOf(op, options) {
2964
4352
  if (options === void 0 || options === null) return void 0;
2965
4353
  if (typeof options !== "object" || Array.isArray(options)) {
2966
- throw new ValidationError5(`${op}: options must be an object such as { leaseUntil }`);
4354
+ throw new ValidationError6(`${op}: options must be an object such as { leaseUntil }`);
2967
4355
  }
2968
4356
  const unknown = Object.keys(options).filter((k) => k !== "leaseUntil");
2969
4357
  if (unknown.length > 0) {
2970
- throw new ValidationError5(
4358
+ throw new ValidationError6(
2971
4359
  `${op}: unknown option${unknown.length > 1 ? "s" : ""} ${unknown.map((k) => `"${k}"`).join(", ")}; this version takes { leaseUntil } only`
2972
4360
  );
2973
4361
  }
@@ -2975,17 +4363,17 @@ var Segment = class _Segment {
2975
4363
  if (until === void 0) return void 0;
2976
4364
  const now = this.clock.now();
2977
4365
  if (typeof until !== "number" || !Number.isSafeInteger(until)) {
2978
- throw new ValidationError5(
4366
+ throw new ValidationError6(
2979
4367
  `${op}: leaseUntil must be an integer epoch-MILLISECONDS; got ${String(until)}`
2980
4368
  );
2981
4369
  }
2982
4370
  if (until <= now) {
2983
- throw new ValidationError5(
4371
+ throw new ValidationError6(
2984
4372
  `${op}: leaseUntil (${until}) is not after now (${now}); it is epoch MILLISECONDS, so a value in seconds reads as long past. Use \`Date.now() + hours * 3_600_000\``
2985
4373
  );
2986
4374
  }
2987
4375
  if (until > now + MAX_LEASE_MS) {
2988
- throw new ValidationError5(
4376
+ throw new ValidationError6(
2989
4377
  `${op}: leaseUntil is more than 14 days away; the longest lease is ${MAX_LEASE_MS} ms. Take a new lease when a job outlasts it`
2990
4378
  );
2991
4379
  }
@@ -3089,22 +4477,22 @@ var Segment = class _Segment {
3089
4477
  const { generation, fingerprint, version } = at ?? {};
3090
4478
  const unknown = typeof at === "object" && at !== null ? Object.keys(at).filter((k) => !["generation", "fingerprint", "version"].includes(k)) : [];
3091
4479
  if (unknown.length > 0) {
3092
- throw new ValidationError5(
4480
+ throw new ValidationError6(
3093
4481
  `pinAt: unknown option${unknown.length > 1 ? "s" : ""} ${unknown.map((k) => `"${k}"`).join(", ")}; pinAt takes { generation, fingerprint } and a pin's \`version\`, which it does not read`
3094
4482
  );
3095
4483
  }
3096
4484
  if (generation === null) {
3097
- throw new ValidationError5(
4485
+ throw new ValidationError6(
3098
4486
  "pinAt: the pin named no generation (the segment had none when it was pinned), so there is nothing to reopen"
3099
4487
  );
3100
4488
  }
3101
4489
  if (version !== void 0 && typeof version !== "string") {
3102
- throw new ValidationError5(
4490
+ throw new ValidationError6(
3103
4491
  "pinAt: `version`, when given, is the string a pin recorded in its pinnedAt; pinAt does not read it, so leave it out if you have none"
3104
4492
  );
3105
4493
  }
3106
4494
  if (typeof generation !== "number" || !Number.isSafeInteger(generation) || generation < 0 || typeof fingerprint !== "string" || !/^\d+:\d+$/.test(fingerprint)) {
3107
- throw new ValidationError5(
4495
+ throw new ValidationError6(
3108
4496
  "pinAt: pass { generation, fingerprint } as recorded by an earlier pin (its pinnedAt); a generation number without the fingerprint of its object does not identify it"
3109
4497
  );
3110
4498
  }
@@ -3153,7 +4541,7 @@ var Segment = class _Segment {
3153
4541
  if (role === void 0) return;
3154
4542
  const { namespace, segment } = dest.ref;
3155
4543
  const named = namespace === void 0 ? segment : `${namespace}/${segment}`;
3156
- throw new ValidationError5(
4544
+ throw new ValidationError6(
3157
4545
  `${verb}: the destination "${named}" is also ${role} of the call, and a call that reads a segment while it publishes to it can replace a newer load of it with a result built from an older one, with no conflict reported. This release has no fenced in-place update: combine into a new segment and point readers at it`
3158
4546
  );
3159
4547
  }
@@ -3549,7 +4937,7 @@ export {
3549
4937
  CloudRoaringError,
3550
4938
  CountingMetricsSink,
3551
4939
  InProcessKeystore,
3552
- IntegrityError3 as IntegrityError,
4940
+ IntegrityError4 as IntegrityError,
3553
4941
  KeyUnavailableError,
3554
4942
  LeaseExpiredError2 as LeaseExpiredError,
3555
4943
  LeaseLimitError,
@@ -3561,7 +4949,7 @@ export {
3561
4949
  StaleOperandError,
3562
4950
  TransientError,
3563
4951
  UnsupportedError3 as UnsupportedError,
3564
- ValidationError6 as ValidationError,
4952
+ ValidationError7 as ValidationError,
3565
4953
  WriteConflictError2 as WriteConflictError,
3566
4954
  deserializePortable,
3567
4955
  destroySegment,