@cloudbitmaps/roaring 0.15.0 → 0.16.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.d.ts CHANGED
@@ -1332,6 +1332,7 @@ export declare class Segment {
1332
1332
  * override the store's per-op denial-of-wallet budget for this call (or `false` to lift it).
1333
1333
  */
1334
1334
  intersect(others: Segment[], options?: CombineOptions): IdStream;
1335
+ private intersectAs;
1335
1336
  /**
1336
1337
  * Materialize `this ∩ others…` (minus `exclude`) as a **new generation of `dest`** — `dest`'s previous contents
1337
1338
  * are superseded, not added to. Streaming + bounded-memory; the result is one immutable object published
@@ -1364,6 +1365,7 @@ export declare class Segment {
1364
1365
  * segment once (`unionInto`, or a load) is the cheaper shape.
1365
1366
  */
1366
1367
  union(others: Segment[], options?: CombineOptions): IdStream;
1368
+ private unionAs;
1367
1369
  /** Materialize `this ∪ others…` (minus `exclude`) as a **new generation of `dest`** — see {@link intersectInto}. */
1368
1370
  unionInto(dest: Segment, others: Segment[], options?: MaterializeOptions): Promise<MaterializeResult>;
1369
1371
  /**
@@ -1382,6 +1384,7 @@ export declare class Segment {
1382
1384
  * the suppression folds into the same pass rather than materializing an intermediate segment first.
1383
1385
  */
1384
1386
  andNot(excludes: Segment[], options?: BaseCombineOptions): IdStream;
1387
+ private andNotAs;
1385
1388
  /** Materialize `this \ (excludes…)` as a **new generation of `dest`** — see {@link intersectInto}. */
1386
1389
  andNotInto(dest: Segment, excludes: Segment[], options?: AndNotIntoOptions): Promise<MaterializeResult>;
1387
1390
  /**
@@ -1397,4 +1400,4 @@ export declare class Segment {
1397
1400
  }): Promise<CostReport>;
1398
1401
  }
1399
1402
  export { MemoryStorage, LocalFsStorage, CrbmStorageChunkSource, destroySegment, eraseNamespace, excludingReservedRows, readRetentionPolicy, MIN_EXPIRES_AT_MS, InProcessKeystore, NodeAead, aadFor, CloudRoaringError, ValidationError, WriteConflictError, IntegrityError, NotFoundError, UnsupportedError, CapabilityError, TransientError, KeyUnavailableError, BudgetExceededError, isCloudRoaringError, isWriteConflictError, isTransientError, isNotFoundError, isIntegrityError, isValidationError, CrbmReader, BufferReader, CountingMetricsSink, RecordingAuditSink, DEFAULT_RETRY_POLICY, AWS_US_EAST_1_ONDEMAND, ELASTICACHE_REDIS_US_EAST_1_ONDEMAND, ONE_REDIS_HA_CLUSTER, } from '@cloudbitmaps/core';
1400
- export type { Aead, AeadSealed, AuditEvent, BlobReader, BlobSink, Budget, BudgetOption, ChunkRef, Clock, CodecBitmap, CodecInterface, ConsistencyErrorEntry, ConsistencyIssue, ConsistencyReport, CostReport, CrbmCrypto, CrbmReaderOptions, CrbmStorageChunkSourceOptions, DestroyResult, ClearRegistrySummary, DropResult, EncodedChunk, EraseDeps, EstimateInput, ExportFailure, ExportFormat, ExportManifest, ExportOptions, ExportSink, ExportWriter, ExportedSegment, GenKey, GenerationEntry, GenerationMetadata, GovernanceMeta, IAuditSink, IKeystore, IMetricsSink, IRegistryDriver, IStorageDriver, IdRange, InProcessKeystoreOptions, LoadGuard, LoadInput, LoadOptions, LoadRefusal, LoadResult, LocalFsStorageOptions, MemoryStorageOptions, MetricEvent, MetricOpName, MetricsSnapshot, NewRegistryRecord, PinnedAt, PinnedObject, PortableBitmap, PricingProfile, RedisNodeType, RedisSizing, RegCaps, RegistryPatch, RegistryRecord, RegistryStatus, RegistrySummary, RetentionPolicy, RetireEntry, RetireExpiredOptions, RetireExpiredResult, RetryPolicy, Rng, RollbackResult, SealedRegistrySummary, SegmentInfo, SegmentRef, SegmentSize, SegmentSizing, SetRetentionResult, StorageBackend, StorageCaps, StorageChunkSource, Token, Workload, WrappedDek, } from '@cloudbitmaps/core';
1403
+ export type { Aead, AeadSealed, AuditEvent, BlobReader, BlobSink, Budget, BudgetOption, ChunkRef, Clock, CodecBitmap, CodecInterface, ConsistencyErrorEntry, ConsistencyIssue, ConsistencyReport, CostReport, CrbmCrypto, CrbmReaderOptions, CrbmStorageChunkSourceOptions, DestroyResult, ClearRegistrySummary, DropResult, EncodedChunk, EraseDeps, EstimateInput, ExportFailure, ExportFormat, ExportManifest, ExportOptions, ExportSink, ExportWriter, ExportedSegment, GenKey, GenerationEntry, GenerationMetadata, GovernanceMeta, IAuditSink, IKeystore, IMetricsSink, IRegistryDriver, IStorageDriver, IdRange, InProcessKeystoreOptions, LoadGuard, LoadInput, LoadOptions, LoadRefusal, LoadResult, LocalFsStorageOptions, MemoryStorageOptions, MetricEvent, MetricOpName, MetricsSnapshot, NewRegistryRecord, PinnedAt, PinnedObject, PortableBitmap, PricingProfile, RedisNodeType, RedisSizing, RegCaps, RegistryPatch, RegistryRecord, RegistryStatus, RegistrySummary, RegistryWriteOptions, RetentionPolicy, RetireEntry, RetireExpiredOptions, RetireExpiredResult, RetryPolicy, Rng, RollbackResult, SealedRegistrySummary, SegmentInfo, SegmentRef, SegmentSize, SegmentSizing, SetRetentionResult, StorageBackend, StorageCaps, StorageChunkSource, Token, Workload, WrappedDek, } from '@cloudbitmaps/core';
package/dist/index.js CHANGED
@@ -23,6 +23,7 @@ import {
23
23
  estimateCost,
24
24
  groundedReport,
25
25
  loadSegment,
26
+ loadSegmentChunks,
26
27
  mapWithConcurrency,
27
28
  resolveBudget,
28
29
  resolvePerOpBudget,
@@ -450,7 +451,8 @@ function bitmapAsLoadInput(input) {
450
451
  var roaringCodec = {
451
452
  empty: () => SafeBitmap.empty(),
452
453
  fromValues: (values) => SafeBitmap.fromValues(values),
453
- safeDeserialize: (bytes, maxBytes, options) => SafeBitmap.safeDeserialize(bytes, maxBytes, options)
454
+ safeDeserialize: (bytes, maxBytes, options) => SafeBitmap.safeDeserialize(bytes, maxBytes, options),
455
+ owns: (bitmap) => bitmap instanceof SafeBitmap
454
456
  };
455
457
 
456
458
  // src/system-clock.ts
@@ -875,7 +877,7 @@ var CloudRoaring = class _CloudRoaring {
875
877
  const metadata = options?.metadata;
876
878
  let result;
877
879
  try {
878
- result = await loadSegment(dest, ids, deps, {
880
+ const loadOptions = {
879
881
  ...options?.allowEmpty === void 0 ? {} : { allowEmpty: options.allowEmpty },
880
882
  ...options?.guard === void 0 ? {} : { guard: options.guard },
881
883
  ...metadata === void 0 ? {} : { metadata },
@@ -888,7 +890,8 @@ var CloudRoaring = class _CloudRoaring {
888
890
  // as a side effect of adding a guard whose entire purpose is preventing data loss. Opt in with `keep`.
889
891
  keep: options?.keep ?? KEEP_EVERY_GENERATION,
890
892
  ...options?.audit === void 0 ? {} : { audit: options.audit }
891
- });
893
+ };
894
+ result = ids instanceof CombineChunks ? await loadSegmentChunks(dest, ids.chunks, deps, loadOptions) : await loadSegment(dest, ids, deps, loadOptions);
892
895
  } finally {
893
896
  this.engine.invalidate(dest);
894
897
  }
@@ -1692,6 +1695,32 @@ var EMPTY_IDS = {
1692
1695
  async *batches() {
1693
1696
  }
1694
1697
  };
1698
+ var AS_IDS = {
1699
+ none: EMPTY_IDS,
1700
+ failing,
1701
+ intersect: (engine, refs, opts) => withBatches(engine.intersect(refs, opts), () => engine.intersectBatches(refs, opts)),
1702
+ union: (engine, refs, opts) => withBatches(engine.union(refs, opts), () => engine.unionBatches(refs, opts)),
1703
+ andNot: (engine, base, refs, opts) => withBatches(engine.andNot(base, refs, opts), () => engine.andNotBatches(base, refs, opts))
1704
+ };
1705
+ var NO_CHUNKS = {
1706
+ async *[Symbol.asyncIterator]() {
1707
+ }
1708
+ };
1709
+ var CombineChunks = class {
1710
+ constructor(chunks) {
1711
+ this.chunks = chunks;
1712
+ }
1713
+ chunks;
1714
+ };
1715
+ var AS_CHUNKS = {
1716
+ none: NO_CHUNKS,
1717
+ failing: (err) => ({
1718
+ [Symbol.asyncIterator]: () => ({ next: () => Promise.reject(err) })
1719
+ }),
1720
+ intersect: (engine, refs, opts) => engine.intersectChunks(refs, opts),
1721
+ union: (engine, refs, opts) => engine.unionChunks(refs, opts),
1722
+ andNot: (engine, base, refs, opts) => engine.andNotChunks(base, refs, opts)
1723
+ };
1695
1724
  var KEEP_EVERY_GENERATION = Number.MAX_SAFE_INTEGER;
1696
1725
  var makeSegment;
1697
1726
  var minting = false;
@@ -1990,17 +2019,20 @@ var Segment = class _Segment {
1990
2019
  * override the store's per-op denial-of-wallet budget for this call (or `false` to lift it).
1991
2020
  */
1992
2021
  intersect(others, options) {
1993
- if (this.expired() || others.some((o) => o.expired())) return EMPTY_IDS;
2022
+ return this.intersectAs(AS_IDS, others, options);
2023
+ }
2024
+ intersectAs(out, others, options) {
2025
+ if (this.expired() || others.some((o) => o.expired())) return out.none;
1994
2026
  const exclude = this.liveExcludes(options);
1995
2027
  let engine;
1996
2028
  try {
1997
2029
  engine = this.combineEngine([this, ...others, ...exclude]) ?? this.engine;
1998
2030
  } catch (err) {
1999
- return failing(err);
2031
+ return out.failing(err);
2000
2032
  }
2001
2033
  const refs = [this.ref, ...others.map((o) => o.ref)];
2002
2034
  const opts = this.refsIn(options, exclude);
2003
- return withBatches(engine.intersect(refs, opts), () => engine.intersectBatches(refs, opts));
2035
+ return out.intersect(engine, refs, opts);
2004
2036
  }
2005
2037
  /**
2006
2038
  * Materialize `this ∩ others…` (minus `exclude`) as a **new generation of `dest`** — `dest`'s previous contents
@@ -2027,7 +2059,12 @@ var Segment = class _Segment {
2027
2059
  this.combineEngine([this, ...others, ...options?.exclude ?? []]);
2028
2060
  return this.timed(
2029
2061
  "intersectInto",
2030
- () => this.materialize(dest.ref, this.intersect(others, options), "intersectInto", options)
2062
+ () => this.materialize(
2063
+ dest.ref,
2064
+ new CombineChunks(this.intersectAs(AS_CHUNKS, others, options)),
2065
+ "intersectInto",
2066
+ options
2067
+ )
2031
2068
  );
2032
2069
  }
2033
2070
  /**
@@ -2041,26 +2078,29 @@ var Segment = class _Segment {
2041
2078
  * segment once (`unionInto`, or a load) is the cheaper shape.
2042
2079
  */
2043
2080
  union(others, options) {
2081
+ return this.unionAs(AS_IDS, others, options);
2082
+ }
2083
+ unionAs(out, others, options) {
2044
2084
  const live = others.filter((o) => !o.expired());
2045
2085
  if (this.expired()) {
2046
- if (live.length === 0) return EMPTY_IDS;
2047
- return live[0].union(live.slice(1), options);
2086
+ if (live.length === 0) return out.none;
2087
+ return live[0].unionAs(out, live.slice(1), options);
2048
2088
  }
2049
2089
  if (live.length === 0 && others.length > 0) {
2050
2090
  const exclude2 = this.liveExcludes(options);
2051
- return exclude2.length > 0 ? this.andNot([...exclude2], options) : this.union([], options);
2091
+ return exclude2.length > 0 ? this.andNotAs(out, [...exclude2], options) : this.unionAs(out, [], options);
2052
2092
  }
2053
- if (live.length !== others.length) return this.union(live, options);
2093
+ if (live.length !== others.length) return this.unionAs(out, live, options);
2054
2094
  const exclude = this.liveExcludes(options);
2055
2095
  let engine;
2056
2096
  try {
2057
2097
  engine = this.combineEngine([this, ...others, ...exclude]) ?? this.engine;
2058
2098
  } catch (err) {
2059
- return failing(err);
2099
+ return out.failing(err);
2060
2100
  }
2061
2101
  const refs = [this.ref, ...others.map((o) => o.ref)];
2062
2102
  const opts = this.refsIn(options, exclude);
2063
- return withBatches(engine.union(refs, opts), () => engine.unionBatches(refs, opts));
2103
+ return out.union(engine, refs, opts);
2064
2104
  }
2065
2105
  /** Materialize `this ∪ others…` (minus `exclude`) as a **new generation of `dest`** — see {@link intersectInto}. */
2066
2106
  async unionInto(dest, others, options) {
@@ -2068,7 +2108,12 @@ var Segment = class _Segment {
2068
2108
  this.combineEngine([this, ...others, ...options?.exclude ?? []]);
2069
2109
  return this.timed(
2070
2110
  "unionInto",
2071
- () => this.materialize(dest.ref, this.union(others, options), "unionInto", options)
2111
+ () => this.materialize(
2112
+ dest.ref,
2113
+ new CombineChunks(this.unionAs(AS_CHUNKS, others, options)),
2114
+ "unionInto",
2115
+ options
2116
+ )
2072
2117
  );
2073
2118
  }
2074
2119
  /**
@@ -2087,25 +2132,25 @@ var Segment = class _Segment {
2087
2132
  * the suppression folds into the same pass rather than materializing an intermediate segment first.
2088
2133
  */
2089
2134
  andNot(excludes, options) {
2090
- if (this.expired()) return EMPTY_IDS;
2135
+ return this.andNotAs(AS_IDS, excludes, options);
2136
+ }
2137
+ andNotAs(out, excludes, options) {
2138
+ if (this.expired()) return out.none;
2091
2139
  const liveExcludes = excludes.filter((e) => !e.expired());
2092
2140
  if (liveExcludes.length === 0 && excludes.length > 0) {
2093
- return this.union([], options == null ? void 0 : readOptions(options));
2141
+ return this.unionAs(out, [], options == null ? void 0 : readOptions(options));
2094
2142
  }
2095
- if (liveExcludes.length !== excludes.length) return this.andNot(liveExcludes, options);
2143
+ if (liveExcludes.length !== excludes.length) return this.andNotAs(out, liveExcludes, options);
2096
2144
  let engine;
2097
2145
  try {
2098
2146
  engine = this.combineEngine([this, ...excludes]) ?? this.engine;
2099
2147
  } catch (err) {
2100
- return failing(err);
2148
+ return out.failing(err);
2101
2149
  }
2102
2150
  const base = this.ref;
2103
2151
  const refs = excludes.map((o) => o.ref);
2104
2152
  const opts = options == null ? void 0 : readOptions(options);
2105
- return withBatches(
2106
- engine.andNot(base, refs, opts),
2107
- () => engine.andNotBatches(base, refs, opts)
2108
- );
2153
+ return out.andNot(engine, base, refs, opts);
2109
2154
  }
2110
2155
  /** Materialize `this \ (excludes…)` as a **new generation of `dest`** — see {@link intersectInto}. */
2111
2156
  async andNotInto(dest, excludes, options) {
@@ -2113,7 +2158,12 @@ var Segment = class _Segment {
2113
2158
  this.combineEngine([this, ...excludes]);
2114
2159
  return this.timed(
2115
2160
  "andNotInto",
2116
- () => this.materialize(dest.ref, this.andNot(excludes, options), "andNotInto", options)
2161
+ () => this.materialize(
2162
+ dest.ref,
2163
+ new CombineChunks(this.andNotAs(AS_CHUNKS, excludes, options)),
2164
+ "andNotInto",
2165
+ options
2166
+ )
2117
2167
  );
2118
2168
  }
2119
2169
  /**