@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.
@@ -1,99 +1,29 @@
1
- import type { CodecBitmap, CodecInterface, EncodedChunk, LoadInput, PortableBitmap } from '@cloudbitmaps/core';
2
- export declare class SafeBitmap implements CodecBitmap {
3
- private readonly bitmap;
4
- private constructor();
5
- static empty(): SafeBitmap;
6
- static fromValues(values: Iterable<number>): SafeBitmap;
7
- /**
8
- * Cap the size, check the structure, then deserialize with the **portable** format.
9
- * Throws `IntegrityError` if the input exceeds `maxBytes`, is not a well-formed portable bitmap, or fails to
10
- * decode — the native addon is never handed unbounded, malformed or unsafe-format input. With `whole`, bytes
11
- * after the bitmap's last container are refused too; without it they are ignored, as the native decoder ignores
12
- * them.
13
- *
14
- * The structural check is what makes the decoded bitmap's answers mean anything. The native deserializer
15
- * bounds its reads and checks nothing else, so bytes of the right length and the wrong shape (containers or
16
- * values out of order, overlapping runs, a cardinality that disagrees with the bits) decode into a bitmap
17
- * whose `maximum()`, `has()` and `size` are wrong, and some of those shapes crash the process when used.
18
- */
19
- static safeDeserialize(bytes: Uint8Array, maxBytes: number, options?: {
20
- readonly whole?: boolean;
21
- }): SafeBitmap;
22
- serialize(): Uint8Array;
23
- /**
24
- * Convert containers to run-encoding where that is smaller. Representation only — membership is untouched, and
25
- * the portable format still round-trips through {@link RoaringCodec.safeDeserialize}.
26
- *
27
- * Roaring's third container type is a RUN, and no implementation selects it on its own: it takes an explicit
28
- * `runOptimize()` pass. Nothing here made that call, so run-shaped ids paid array or bitset prices — measured
29
- * at **570×** for a contiguous 1M-id range (128.1 KiB → 0.2 KiB) and **63×** for a 2,000-run shape
30
- * (536.5 KiB → 8.5 KiB). Sparse ids come out byte-identical, so this is never a losing trade; roaring keeps
31
- * whichever encoding is smaller per container.
32
- *
33
- * Those two factors are THIS CALL's own before/after on the same ids. They are not the ones the site quotes
34
- * (543× and 63×) — those compare the optimized encoding against the best *fixed* representation at its floor,
35
- * a different baseline that happens to land near 63× on the run shape too. `pnpm bench:encoding` prints both
36
- * columns; don't carry a figure between them without checking which denominator it had.
37
- *
38
- * Called only when writing an immutable objects generation — see {@link CodecBitmap.optimize} for why the read
39
- * path deliberately does not.
40
- *
41
- * CANONICAL, which `runOptimize()` alone is not. Where a container's run and array encodings are the same size
42
- * (cardinality = 2 × runs + 1: three values in one run, five in two), CRoaring keeps whichever kind the
43
- * container already has. A chunk built from ids starts as an array and stays one; the same set reached through
44
- * `addRange`, an earlier `runOptimize()` or an operation over run containers is a run, and serializes to other
45
- * bytes. Undoing run compression first starts every container where one built from ids starts, so the bytes
46
- * depend on membership alone. On a bitmap built from ids there is nothing to undo.
47
- */
48
- optimize(): void;
49
- /**
50
- * This set as storage chunks, cut from its own containers: {@link optimize} and one `serialize` when called, then
51
- * a lazy header walk that copies one container out per step (`containerPayloads`). Per container and per byte,
52
- * never per id, and the payloads are the ones {@link SafeBitmap.fromValues} of each chunk's low 16 bits would
53
- * serialize to. The walk trusts the bytes it cuts because the native serializer wrote them, from a bitmap that
54
- * passed the structural check when it was decoded.
55
- */
56
- encodeChunks(): Iterable<EncodedChunk>;
57
- /**
58
- * Largest value, or `undefined` when empty. O(1) — roaring reads it off the last container, so the engine's
59
- * per-chunk range assertion costs one call per chunk rather than a walk per id. The last container holds the
60
- * largest value only because {@link SafeBitmap.safeDeserialize} refuses bytes whose containers or values are
61
- * out of order.
62
- */
63
- maximum(): number | undefined;
64
- add(value: number): void;
65
- addMany(values: Iterable<number>): void;
66
- remove(value: number): void;
67
- removeMany(values: Iterable<number>): void;
68
- has(value: number): boolean;
69
- get size(): number;
70
- get isEmpty(): boolean;
71
- clone(): SafeBitmap;
72
- /** In-place union: `this = this ∪ other`. */
73
- orInPlace(other: CodecBitmap): void;
74
- /** In-place difference: `this = this \ other`. */
75
- andNotInPlace(other: CodecBitmap): void;
76
- /** In-place intersection: `this = this ∩ other`. */
77
- andInPlace(other: CodecBitmap): void;
78
- /** Ascending iterator over the set values. */
79
- [Symbol.iterator](): IterableIterator<number>;
80
- toArray(): number[];
81
- /** The values as one fresh ascending `Uint32Array`, exported natively. */
82
- toUint32Array(): Uint32Array;
83
- }
84
1
  /**
85
- * A bare `RoaringBitmap32` of this package's own `roaring`, or a bitmap {@link deserializePortable} returned, passed
86
- * where ids go, loads as `{ bitmap }`: from its containers, through the same check as any bytes, never id by id. Any
87
- * other input passes through unchanged, and a bitmap from another copy of `roaring` is loaded as the ids it
88
- * iterates, which is correct and slower.
2
+ * The codec selection point and the load-input and decode helpers the `CloudRoaring` facade builds on.
3
+ *
4
+ * The store's codec is the TypeScript Roaring codec (`ts-roaring/bitmap.ts`): the portable format, read and written in
5
+ * JavaScript with no native addon. Every deserialize is preceded by a hard size cap and a structural check
6
+ * (`portable/layout.ts`). The `unsafe_frozen_*` formats are never used.
7
+ */
8
+ import type { CodecInterface, LoadInput, PortableBitmap } from '@cloudbitmaps/core';
9
+ /**
10
+ * An iterable that serializes itself to portable Roaring (an object with `Symbol.iterator` and a `serialize` method: a
11
+ * caller's `RoaringBitmap32` from the `roaring` package, another copy's bitmap, or a bitmap {@link deserializePortable}
12
+ * returned), passed where ids go, loads as `{ bitmap }`: from its containers, through the same check as any bytes,
13
+ * never id by id. Its `serialize` decides, even where it disagrees with what it iterates. Any other input passes
14
+ * through unchanged, so the core's own rules apply to it: a byte array (`Uint8Array`, `Buffer`) is refused as ids even
15
+ * with a `serialize` of its own, and an object that is not iterable is read as `{ serialized }` or `{ bitmap }` or
16
+ * refused, whatever else it has.
89
17
  */
90
18
  export declare function bitmapAsLoadInput(input: LoadInput): LoadInput;
91
19
  /**
92
- * The roaring {@link CodecInterface} — the flagship codec, delegating to {@link SafeBitmap}'s statics. This is
93
- * the default the `CloudRoaring` facade injects into the engine; `core/` itself never hard-references it once a
94
- * caller supplies a codec.
20
+ * The codec the store hands to the engine at every site that injects one (`CloudRoaring`, a load, a pin, an export
21
+ * and {@link deserializePortable}): the TypeScript codec unless a harness has flipped it with {@link setFlagshipCodec}.
22
+ * Internal: no public entry exports it, and a store cannot be configured with a codec.
95
23
  */
96
- export declare const roaringCodec: CodecInterface;
24
+ export declare function flagshipCodec(): CodecInterface;
25
+ /** Flip the codec the store uses, for the whole process. Test and bench harnesses only; returns the previous one. */
26
+ export declare function setFlagshipCodec(codec: CodecInterface): CodecInterface;
97
27
  /**
98
28
  * A decoded bitmap that can only be read: what {@link deserializePortable} returns. Its ids come out ascending when
99
29
  * it is iterated, which is a promise. It is a `PortableBitmap`, so a load takes it as `{ bitmap }`, and the library
@@ -111,7 +41,7 @@ export interface ReadonlyBitmap extends PortableBitmap, Iterable<number> {
111
41
  }
112
42
  /**
113
43
  * Decode portable Roaring bytes you hold into a {@link ReadonlyBitmap}, through the check a `{ serialized }` load
114
- * makes first: a size cap, a structural check, one whole bitmap, and only then the native decoder.
44
+ * makes first: a size cap, a structural check, one whole bitmap, and only then the decoder.
115
45
  *
116
46
  * @param bytes a `Uint8Array`, which a Node `Buffer` is.
117
47
  * @throws {ValidationError} for bytes that are not exactly one well-formed portable bitmap, as a load refuses them.
package/package.json CHANGED
@@ -1,13 +1,12 @@
1
1
  {
2
2
  "name": "@cloudbitmaps/roaring",
3
- "version": "0.23.0",
3
+ "version": "0.24.0",
4
4
  "description": "Distributed, cloud-native Roaring Bitmaps — query and intersect billion-scale integer sets straight out of object storage, from a bounded RAM cache over immutable objects in your own bucket, at a fraction of an always-on cache.",
5
5
  "keywords": [
6
6
  "roaring",
7
7
  "bitmap",
8
8
  "roaring-bitmap",
9
9
  "roaring-bitmaps",
10
- "croaring",
11
10
  "bitset",
12
11
  "compressed-bitmap",
13
12
  "lambda",
@@ -65,8 +64,7 @@
65
64
  "export-segments": "./dist/bin/export-segments.js"
66
65
  },
67
66
  "dependencies": {
68
- "roaring": "2.7.0",
69
- "@cloudbitmaps/core": "0.23.0"
67
+ "@cloudbitmaps/core": "0.24.0"
70
68
  },
71
69
  "devDependencies": {
72
70
  "@types/node": "^22.0.0",