@cloudbitmaps/roaring 0.24.0 → 0.26.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.
@@ -0,0 +1,223 @@
1
+ /** What {@link RoaringBitmap.deserialize} takes as its second argument. */
2
+ export interface RoaringBitmapDeserializeOptions {
3
+ /**
4
+ * A cap on the input's size in bytes, lower than the one every decode has (537,403,396, the most any canonical
5
+ * 32-bit bitmap serializes to). Bytes over it are refused before any is read. It can only lower the cap: a value
6
+ * above it, or one that is not a non-negative integer, is a `ValidationError`.
7
+ */
8
+ readonly maxBytes?: number;
9
+ }
10
+ /**
11
+ * A mutable set of integers from 0 to 4,294,967,295 (unsigned 32-bit ids) with set algebra and the portable Roaring
12
+ * serialization. It is not designed for subclassing, and `JSON.stringify` of one gives `"{}"`: write
13
+ * `JSON.stringify([...bitmap])` or `bitmap.toArray()`. Passed to a method of the `roaring` package from npm in place of a
14
+ * `RoaringBitmap32`, it answers wrongly without throwing in JavaScript (TypeScript refuses the call): decode its
15
+ * `serialize()` bytes with that package instead.
16
+ *
17
+ * Every id argument is checked: a value that is not an integer in range (a fraction, `NaN`, a string, `null`, a
18
+ * negative, one too large) throws `ValidationError`, whose message never repeats it, and the bitmap is unchanged.
19
+ * Iterating while changing the bitmap is unsupported: collect first with `toUint32Array()`, or iterate a `clone()`.
20
+ * Everything is synchronous.
21
+ */
22
+ export declare class RoaringBitmap implements Iterable<number> {
23
+ #private;
24
+ /**
25
+ * A bitmap of `values`: an array or another iterable of ids, a `Uint32Array` (read in place when it already ascends,
26
+ * else sorted on a copy; it is never changed or kept), or another `RoaringBitmap` (a copy-on-write `clone()`).
27
+ * With no argument it is empty.
28
+ *
29
+ * @throws {ValidationError} for an id that is not an integer from 0 to 4294967295; for a value that is not an
30
+ * iterable (`null`, a number, a string, an object, an `ArrayBuffer`); and for a `Uint8Array`, `Uint8ClampedArray` or
31
+ * `Buffer`, which would read each byte as an id: call {@link RoaringBitmap.deserialize} for bytes.
32
+ */
33
+ constructor(values?: Iterable<number>);
34
+ /**
35
+ * Decode portable Roaring bytes you hold, through the check a `{ serialized }` load makes first: a size cap, a
36
+ * structural check and one whole bitmap, and only then the decoder. The result owns its storage: it keeps nothing
37
+ * of `bytes`, so a large input that is decoded and then reduced can be freed.
38
+ *
39
+ * @param bytes a `Uint8Array`, which a Node `Buffer` is.
40
+ * @param options `{ maxBytes }` lowers the size cap below the default of 537,403,396 bytes.
41
+ * @throws {ValidationError} for something that is not a `Uint8Array`; an empty or detached one (an empty buffer is
42
+ * not a bitmap: `new RoaringBitmap()` is the empty set); one over the cap or `maxBytes`; bytes that are not exactly
43
+ * one well-formed portable bitmap, including bytes after its last container; a second argument that is not
44
+ * `undefined` or an object whose only key is `maxBytes` (a format argument such as `'portable'` is one); and a
45
+ * `maxBytes` that is not an integer from 0 to the cap.
46
+ */
47
+ static deserialize(bytes: Uint8Array, options?: RoaringBitmapDeserializeOptions): RoaringBitmap;
48
+ /** How many ids it holds. */
49
+ get size(): number;
50
+ /** Whether it holds no id. */
51
+ get isEmpty(): boolean;
52
+ /**
53
+ * Whether it holds `id`.
54
+ *
55
+ * @throws {ValidationError} for a value that is not an integer from 0 to 4294967295.
56
+ */
57
+ has(id: number): boolean;
58
+ /** The smallest id, or `undefined` when it is empty. */
59
+ minimum(): number | undefined;
60
+ /** The largest id, or `undefined` when it is empty. */
61
+ maximum(): number | undefined;
62
+ /**
63
+ * Add one id; returns this bitmap, for chaining.
64
+ *
65
+ * @throws {ValidationError} for a value that is not an integer from 0 to 4294967295, and for a second argument:
66
+ * use {@link RoaringBitmap.addMany} to add several.
67
+ */
68
+ add(id: number): this;
69
+ /**
70
+ * Add every id of `values` (an iterable of ids, or a `Uint32Array`); returns this bitmap. Nothing is added if any
71
+ * of them is refused.
72
+ *
73
+ * @throws {ValidationError} as the constructor does.
74
+ */
75
+ addMany(values: Iterable<number>): this;
76
+ /**
77
+ * Remove one id; whether it was there.
78
+ *
79
+ * @throws {ValidationError} for a value that is not an integer from 0 to 4294967295, and for a second argument:
80
+ * use {@link RoaringBitmap.removeMany} to remove several.
81
+ */
82
+ remove(id: number): boolean;
83
+ /**
84
+ * Remove every id of `values` (an iterable of ids, or a `Uint32Array`); returns this bitmap. Nothing is removed if
85
+ * any of them is refused.
86
+ *
87
+ * @throws {ValidationError} as the constructor does.
88
+ */
89
+ removeMany(values: Iterable<number>): this;
90
+ /** Remove every id. */
91
+ clear(): void;
92
+ /**
93
+ * A copy. It is copy-on-write: the copy costs the key list and one flag per container, not the ids, and the first
94
+ * write to a container on either side copies that container once.
95
+ */
96
+ clone(): RoaringBitmap;
97
+ /**
98
+ * Keep only the ids `other` also holds; returns this bitmap. `other` is not changed, and may be this bitmap.
99
+ *
100
+ * @throws {ValidationError} if `other` is not a `RoaringBitmap` of this copy of the package.
101
+ */
102
+ andInPlace(other: RoaringBitmap): this;
103
+ /**
104
+ * Add the ids `other` holds; returns this bitmap. `other` is not changed, and may be this bitmap.
105
+ *
106
+ * @throws {ValidationError} if `other` is not a `RoaringBitmap` of this copy of the package.
107
+ */
108
+ orInPlace(other: RoaringBitmap): this;
109
+ /**
110
+ * Remove the ids `other` holds; returns this bitmap. `other` is not changed, and may be this bitmap.
111
+ *
112
+ * @throws {ValidationError} if `other` is not a `RoaringBitmap` of this copy of the package.
113
+ */
114
+ andNotInPlace(other: RoaringBitmap): this;
115
+ /**
116
+ * Flip the ids `other` holds: keep those only this bitmap holds, add those only `other` holds; returns this bitmap.
117
+ * `other` is not changed, and may be this bitmap (the result is then empty).
118
+ *
119
+ * @throws {ValidationError} if `other` is not a `RoaringBitmap` of this copy of the package.
120
+ */
121
+ xorInPlace(other: RoaringBitmap): this;
122
+ /**
123
+ * How many ids both bitmaps hold, without building the intersection. Neither bitmap changes; `other` may be this one.
124
+ *
125
+ * @throws {ValidationError} if `other` is not a `RoaringBitmap` of this copy of the package.
126
+ */
127
+ andCardinality(other: RoaringBitmap): number;
128
+ /**
129
+ * How many ids either bitmap holds. Neither bitmap changes; `other` may be this one.
130
+ *
131
+ * @throws {ValidationError} if `other` is not a `RoaringBitmap` of this copy of the package.
132
+ */
133
+ orCardinality(other: RoaringBitmap): number;
134
+ /**
135
+ * How many ids exactly one of the bitmaps holds. Neither bitmap changes; `other` may be this one.
136
+ *
137
+ * @throws {ValidationError} if `other` is not a `RoaringBitmap` of this copy of the package.
138
+ */
139
+ xorCardinality(other: RoaringBitmap): number;
140
+ /**
141
+ * How many ids this bitmap holds that `other` lacks. Neither bitmap changes; `other` may be this one.
142
+ *
143
+ * @throws {ValidationError} if `other` is not a `RoaringBitmap` of this copy of the package.
144
+ */
145
+ andNotCardinality(other: RoaringBitmap): number;
146
+ /**
147
+ * Whether the bitmaps share an id. Neither bitmap changes; `other` may be this one.
148
+ *
149
+ * @throws {ValidationError} if `other` is not a `RoaringBitmap` of this copy of the package.
150
+ */
151
+ intersects(other: RoaringBitmap): boolean;
152
+ /**
153
+ * Whether every id of this bitmap is in `other` (an empty bitmap is a subset of every bitmap, itself included). Neither
154
+ * bitmap changes. Unlike the `roaring` package, which answers `false`, a value that is not a bitmap is refused.
155
+ *
156
+ * @throws {ValidationError} if `other` is not a `RoaringBitmap` of this copy of the package.
157
+ */
158
+ isSubset(other: RoaringBitmap): boolean;
159
+ /**
160
+ * Whether both bitmaps hold exactly the same ids, whatever the kinds of their containers or the bytes they would
161
+ * serialize to. Neither bitmap changes.
162
+ *
163
+ * @throws {ValidationError} if `other` is not a `RoaringBitmap` of this copy of the package.
164
+ */
165
+ isEqual(other: RoaringBitmap): boolean;
166
+ /**
167
+ * The ids both bitmaps hold, as a new bitmap. Neither operand changes, and the result holds storage of its own.
168
+ *
169
+ * @throws {ValidationError} if an operand is not a `RoaringBitmap` of this copy of the package.
170
+ */
171
+ static and(a: RoaringBitmap, b: RoaringBitmap): RoaringBitmap;
172
+ /**
173
+ * The ids either bitmap holds, as a new bitmap. Neither operand changes. A container only `a` holds is shared with
174
+ * the result copy-on-write, so the next write to it, on either side, copies it once.
175
+ *
176
+ * @throws {ValidationError} if an operand is not a `RoaringBitmap` of this copy of the package.
177
+ */
178
+ static or(a: RoaringBitmap, b: RoaringBitmap): RoaringBitmap;
179
+ /**
180
+ * The ids exactly one of the bitmaps holds, as a new bitmap. Neither operand changes (see {@link RoaringBitmap.or}
181
+ * for what is shared).
182
+ *
183
+ * @throws {ValidationError} if an operand is not a `RoaringBitmap` of this copy of the package.
184
+ */
185
+ static xor(a: RoaringBitmap, b: RoaringBitmap): RoaringBitmap;
186
+ /**
187
+ * The ids of `a` that `b` lacks, as a new bitmap. Neither operand changes (see {@link RoaringBitmap.or} for what is
188
+ * shared).
189
+ *
190
+ * @throws {ValidationError} if an operand is not a `RoaringBitmap` of this copy of the package.
191
+ */
192
+ static andNot(a: RoaringBitmap, b: RoaringBitmap): RoaringBitmap;
193
+ /**
194
+ * The union of every bitmap of `bitmaps`, as a new bitmap that owns its storage (an empty list gives the empty set).
195
+ * No operand changes, and none is flagged: the result accumulates in containers of its own.
196
+ *
197
+ * @throws {ValidationError} if `bitmaps` is not an iterable, or holds anything that is not a `RoaringBitmap` of this
198
+ * copy of the package; nothing is combined then.
199
+ */
200
+ static orMany(bitmaps: Iterable<RoaringBitmap>): RoaringBitmap;
201
+ /** The ids in ascending order, each once. A bitmap that changes during the walk gives unspecified ids, and no error. */
202
+ [Symbol.iterator](): IterableIterator<number>;
203
+ /** The ids as a new ascending array. A bitmap too large to allocate as one throws the runtime's `RangeError`. */
204
+ toArray(): number[];
205
+ /** The ids as a new ascending `Uint32Array` the caller owns, never a view of the bitmap's storage. */
206
+ toUint32Array(): Uint32Array;
207
+ /**
208
+ * The portable Roaring bytes, in a new `Uint8Array`. Call {@link RoaringBitmap.runOptimize} first when the bitmap was
209
+ * decoded from bytes another writer made: its run containers stay as they were, and a bitmap that serializes over
210
+ * the size cap is refused by a load.
211
+ *
212
+ * @param format `'portable'`, the only format there is, or nothing.
213
+ * @throws {ValidationError} for any other argument.
214
+ */
215
+ serialize(format?: 'portable'): Uint8Array;
216
+ /**
217
+ * Re-encode every container in the smallest form (a run container only where it is strictly smaller than the plain
218
+ * one), so `serialize()` afterwards depends on the set alone. Membership is unchanged.
219
+ *
220
+ * @returns whether the bitmap holds at least one run container afterwards, not whether anything changed.
221
+ */
222
+ runOptimize(): boolean;
223
+ }
package/dist/index.d.ts CHANGED
@@ -29,7 +29,6 @@ import type { DestroyResult, EraseDeps } from '@cloudbitmaps/core';
29
29
  import type { SegmentInfo } from '@cloudbitmaps/core';
30
30
  import type { PreflightResult } from '@cloudbitmaps/core';
31
31
  import type { Expr, MaterializeManyFeedRecord, MaterializeManyStats } from '@cloudbitmaps/core';
32
- import { deserializePortable } from './roaring-codec.js';
33
32
  /**
34
33
  * Crypto-shred one segment. It cannot be undone through the library (a registry restore to a point before it can).
35
34
  * `confirmSegment` must equal `ref.segment` (a guard against an accidental destroy). A non-encrypted segment is
@@ -1092,8 +1091,8 @@ export declare class CloudRoaring {
1092
1091
  * with `serialize('portable')` such as `roaring`'s `RoaringBitmap32`, or `{ serialized }`, portable Roaring bytes.
1093
1092
  * A bitmap is checked (size cap, structure, safe deserializer) before the first request, written from its own
1094
1093
  * containers with no per-id work, and gives the generation chunk for chunk what its ids would. An
1095
- * iterable with a `serialize` method (a `RoaringBitmap32`, another copy's bitmap, or a bitmap `deserializePortable`
1096
- * returned) passed as ids loads as `{ bitmap }` and is not iterated. A `Uint8Array` or `Buffer` passed as ids is
1094
+ * iterable with a `serialize` method (a `RoaringBitmap32`, another copy's bitmap, or a `RoaringBitmap`
1095
+ * of this package) passed as ids loads as `{ bitmap }` and is not iterated. A `Uint8Array` or `Buffer` passed as ids is
1097
1096
  * refused with `ValidationError`, since each byte would load as an id, even when it has a `serialize` of its own:
1098
1097
  * pass bytes as `{ serialized }`.
1099
1098
  *
@@ -1499,7 +1498,7 @@ export declare class CloudRoaring {
1499
1498
  /**
1500
1499
  * **Export ("eject") every registered segment's current generation** through the injected `sink`, using only
1501
1500
  * public read APIs — so your data is readable **without CloudRoaring** (the exit path; see the README's "Your
1502
- * data stays yours"). `format: 'roaring'` (default) writes one **portable RoaringBitmap32** per segment
1501
+ * data stays yours"). `format: 'roaring'` (default) writes one **portable Roaring bitmap** per segment
1503
1502
  * (loadable by any roaring library); `'ndjson'` writes newline-delimited ids (zero-dependency, streaming).
1504
1503
  * Enumerates via the store's **own** registry (needs one — throws {@link UnsupportedError} otherwise) so the
1505
1504
  * enumeration and the read path provably share one registry. Encrypted segments are decrypted transparently
@@ -2129,6 +2128,59 @@ export declare class Segment {
2129
2128
  * {@link ValidationError} before any request.
2130
2129
  */
2131
2130
  andNotInto(dest: Segment, excludes: Segment[], options?: CombineOptions): Promise<MaterializeResult>;
2131
+ /**
2132
+ * How many ids `this ∩ others…` holds (minus `exclude`): the length of what {@link intersect} streams, without
2133
+ * streaming it. Every key all the operands hold is decoded and counted as the stream reads it, and a key only some
2134
+ * operands hold is not read, so the call makes the requests {@link intersect} makes and returns a number instead of
2135
+ * the ids. It is exact: it never answers a key from an index, so it trusts nothing {@link count} trusts.
2136
+ *
2137
+ * The range, `concurrency`, `budget`, `allowAbsentOperands` and `exclude` are {@link intersect}'s; a write option fails
2138
+ * the call with {@link ValidationError} before any request, and so does an empty `others` (to count one segment, use
2139
+ * {@link count}).
2140
+ *
2141
+ * Like a stream, a count that runs while a segment is erased or reloaded can describe two instants, within the bound
2142
+ * the streams state. A union or a difference, and an intersection with an `exclude`, looks at its operands'
2143
+ * generations every `concurrency` keys; an intersection with no `exclude` makes no such look, since it decodes every
2144
+ * key and so shows a move in the chunks it decodes, as its stream does. Either way it plans again above the last key
2145
+ * it took when one moved. A pinned handle counts the generation it pinned, and each pinned operand's object is
2146
+ * looked up once before the first key (one footer read each, which `budget` does not charge, and which the stream
2147
+ * does not make), and again at each look where there is one, so an erasure of what it pinned fails the count with
2148
+ * {@link NotFoundError}; a
2149
+ * fault the look meets other than a transient one, which is retried, is raised as it is. A call that involves a
2150
+ * handle whose lease has ended, or has ended by the next look, throws {@link LeaseExpiredError}.
2151
+ */
2152
+ intersectCount(others: Segment[], options?: CombineOptions): Promise<number>;
2153
+ /**
2154
+ * How many ids `this ∪ others…` holds (minus `exclude`): the length of what {@link union} streams, without streaming
2155
+ * it. A chunk key only one operand holds, that no `exclude` holds and the range does not cut, is answered from that
2156
+ * operand's index, so a union of segments that mostly do not overlap reads little of them; every other key is
2157
+ * decoded and counted. On handles that are not pinned it makes no more requests than {@link union} does, and reads
2158
+ * fewer bytes when the shared keys are few. An empty `others`, with no `exclude` and no range, is {@link count} of
2159
+ * `this`, answered from the registry row when it can be; when that figure is 0 it adds one registry read, to refuse
2160
+ * a segment that does not exist as the stream does.
2161
+ *
2162
+ * What it trusts: the index, for each key it answers without decoding, as {@link count} does, so a party who can write
2163
+ * an object's index can make that key's figure wrong; a decoded key is exact. A source with no per-chunk counts
2164
+ * decodes every key. It takes the options {@link intersectCount} takes; the erasure bound, the lease checks and the
2165
+ * pinned handles are as for {@link intersectCount}, a pinned operand adding a footer read before the first key and at
2166
+ * each look. An empty `others` on a pinned handle is {@link count} of the pin, with no look.
2167
+ */
2168
+ unionCount(others: Segment[], options?: CombineOptions): Promise<number>;
2169
+ /**
2170
+ * How many ids `this \ (excludes…)` holds: the length of what {@link andNot} streams, without streaming it. A chunk
2171
+ * key of `this` that no exclude holds and the range does not cut is answered from its index and not read; a key an
2172
+ * exclude shares is decoded and counted. On handles that are not pinned it makes no more requests than {@link andNot}
2173
+ * does, and reads fewer bytes when the excludes overlap little of `this`. An empty `excludes`, with no range, is
2174
+ * {@link count} of `this` (the stream of it is the whole of `this`), answered from the registry row when it can be,
2175
+ * with one registry read added when that figure is 0.
2176
+ *
2177
+ * It takes the options {@link andNot} takes (every one of {@link intersectCount}'s but `exclude`, which a count of a
2178
+ * difference has no use for, since `excludes` is its subtraction) and trusts what {@link unionCount} trusts. The
2179
+ * erasure bound, the lease checks and the pinned handles are as for {@link intersectCount}.
2180
+ */
2181
+ andNotCount(excludes: Segment[], options?: CombineOptions): Promise<number>;
2182
+ /** The one body of the three count methods, after each has checked its own options. */
2183
+ private countCombine;
2132
2184
  /**
2133
2185
  * The one body of the three combines, read as ids or as chunks. `operands` is `others` for `intersect` and
2134
2186
  * `union`, and `excludes` for `andNot`, which takes no `exclude` option.
@@ -2139,7 +2191,7 @@ export declare class Segment {
2139
2191
  }
2140
2192
  export { MemoryStorage, LocalFsStorage, InProcessKeystore } from '@cloudbitmaps/core/node';
2141
2193
  export type { InProcessKeystoreOptions, LocalFsStorageOptions, MemoryStorageOptions, } from '@cloudbitmaps/core/node';
2142
- export { deserializePortable };
2143
- export type { ReadonlyBitmap } from './roaring-codec.js';
2194
+ export { RoaringBitmap } from './bitmap.js';
2195
+ export type { RoaringBitmapDeserializeOptions } from './bitmap.js';
2144
2196
  export { excludingReservedRows, readRetentionPolicy, CloudRoaringError, ValidationError, WriteConflictError, IntegrityError, NotFoundError, UnsupportedError, CapabilityError, TransientError, KeyUnavailableError, BudgetExceededError, LeaseExpiredError, LeaseLimitError, StaleOperandError, errorKind, CountingMetricsSink, RecordingAuditSink, } from '@cloudbitmaps/core';
2145
2197
  export type { AuditEvent, Budget, BudgetOption, Clock, ConsistencyErrorEntry, ConsistencyIssue, ConsistencyReport, DestroyResult, DropResult, Entropy, EraseDeps, ErrorKind, ExportFailure, ExportFormat, ExportManifest, ExportOptions, ExportSink, ExportSkipped, ExportWriter, ExportedSegment, Expr, GenerationEntry, GenerationMetadata, IAuditSink, IMetricsSink, LoadGuard, LoadInput, LoadOptions, LoadRefusal, LoadResult, MaterializeManyFeedRecord, MaterializeManyOperandStats, MaterializeManyOutputStats, MaterializeManyStats, MetricEvent, MetricOpName, MetricsSnapshot, PinnedAt, PortableBitmap, PreflightCheck, PreflightResult, RetentionPolicy, RetireEntry, RetireExpiredOptions, RetireExpiredResult, RetryPolicy, Rng, RollbackResult, SegmentInfo, SegmentRef, SetRetentionResult, } from '@cloudbitmaps/core';