@cloudbitmaps/core 0.5.0 → 0.7.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.cjs CHANGED
@@ -1504,8 +1504,8 @@ var FOOTER = {
1504
1504
  // u32
1505
1505
  flags: 20,
1506
1506
  // u32
1507
- roaringSerializationId: 24,
1508
- // u16
1507
+ payloadCodecId: 24,
1508
+ // u16 — was `roaringSerializationId`; same offset, same width, wider meaning
1509
1509
  elementWidth: 26,
1510
1510
  // u8
1511
1511
  containerCodec: 27,
@@ -1533,7 +1533,10 @@ var FOOTER_CRC_COVERAGE = FOOTER.footerCrc32c;
1533
1533
  var FLAG_ENCRYPTED = 1 << 0;
1534
1534
  var FLAG_LITTLE_ENDIAN = 1 << 2;
1535
1535
  var ELEMENT_WIDTH_32 = 32;
1536
- var ROARING_PORTABLE_ID = 1;
1536
+ var PAYLOAD_CODEC_ROARING_PORTABLE = 1;
1537
+ var KNOWN_PAYLOAD_CODEC_IDS = /* @__PURE__ */ new Set([
1538
+ PAYLOAD_CODEC_ROARING_PORTABLE
1539
+ ]);
1537
1540
  var CONTAINER_CODEC_NONE = 0;
1538
1541
  var DEFAULT_TAIL_BYTES = 256 * 1024;
1539
1542
  var DEFAULT_MAX_INDEX_BYTES = 8 * 1024 * 1024;
@@ -1630,10 +1633,10 @@ var CrbmReader = class _CrbmReader {
1630
1633
  `.crbm element_width ${elementWidth} not supported (v1 reads 32-bit ids; 64-bit is a future major version)`
1631
1634
  );
1632
1635
  }
1633
- const serializationId = fview.getUint16(FOOTER.roaringSerializationId, true);
1634
- if (serializationId !== ROARING_PORTABLE_ID) {
1636
+ const payloadCodecId = fview.getUint16(FOOTER.payloadCodecId, true);
1637
+ if (!KNOWN_PAYLOAD_CODEC_IDS.has(payloadCodecId)) {
1635
1638
  throw new UnsupportedError(
1636
- `.crbm roaring_serialization_id ${serializationId} not supported (v1 is portable=${ROARING_PORTABLE_ID})`
1639
+ `.crbm payload_codec_id ${payloadCodecId} not supported by this build (known: ${[...KNOWN_PAYLOAD_CODEC_IDS].join(", ")}; ${PAYLOAD_CODEC_ROARING_PORTABLE}=roaring portable). A generation written by a different codec is rejected rather than decoded \u2014 a store uses one codec throughout.`
1637
1640
  );
1638
1641
  }
1639
1642
  const containerCodec = footer[FOOTER.containerCodec];
@@ -1928,8 +1931,8 @@ var CrbmWriter = class {
1928
1931
  view.setUint32(FOOTER.indexCrc32c, crc32c(indexRegion), true);
1929
1932
  view.setUint32(FOOTER.flags, FLAG_LITTLE_ENDIAN | (encrypted ? FLAG_ENCRYPTED : 0), true);
1930
1933
  view.setUint16(
1931
- FOOTER.roaringSerializationId,
1932
- this.options.roaringSerializationId ?? ROARING_PORTABLE_ID,
1934
+ FOOTER.payloadCodecId,
1935
+ this.options.payloadCodecId ?? PAYLOAD_CODEC_ROARING_PORTABLE,
1933
1936
  true
1934
1937
  );
1935
1938
  footer[FOOTER.elementWidth] = this.options.elementWidth ?? ELEMENT_WIDTH_32;
@@ -2184,6 +2187,7 @@ function writeCrbmGeneration(driver, key, chunks, options = {}) {
2184
2187
  const writer = new CrbmWriter(sink, { generation: key.generation, crypto: options.crypto });
2185
2188
  for (const { chunkKey, bitmap } of sorted) {
2186
2189
  if (bitmap.isEmpty) continue;
2190
+ bitmap.optimize?.();
2187
2191
  await writer.addChunk(chunkKey, bitmap.serialize(), bitmap.size);
2188
2192
  const pause = tick();
2189
2193
  if (pause !== null) await pause;
@@ -2199,6 +2203,7 @@ async function writeCrbmGenerationStream(driver, key, chunks, options = {}) {
2199
2203
  const writer = new CrbmWriter(sink, { generation: key.generation, crypto: options.crypto });
2200
2204
  for await (const { chunkKey, bitmap } of chunks) {
2201
2205
  if (bitmap.isEmpty) continue;
2206
+ bitmap.optimize?.();
2202
2207
  await writer.addChunk(chunkKey, bitmap.serialize(), bitmap.size);
2203
2208
  chunkKeys.push(chunkKey);
2204
2209
  cardinality += bitmap.size;
@@ -3987,7 +3992,22 @@ async function eraseNamespace(namespace, deps, options) {
3987
3992
  const destroyed = [];
3988
3993
  let segmentsShredded = 0;
3989
3994
  for (const ref of refs) {
3990
- const result = await shredSegment(ref, deps, options.allowCleartext ?? false);
3995
+ let result;
3996
+ try {
3997
+ result = await shredSegment(ref, deps, options.allowCleartext ?? false);
3998
+ } catch (err) {
3999
+ result = {
4000
+ segment: ref.segment,
4001
+ namespace: ref.namespace,
4002
+ destroyed: false,
4003
+ cryptoShredded: false,
4004
+ reason: isWriteConflictError(err) ? "contended" : `failed: ${err instanceof Error ? err.message : String(err)}`,
4005
+ // Deliberately 0, and not a partial count. `eraseWarm` may have deleted rows before it threw, but the
4006
+ // erase did not complete as a unit, so a partial figure on a failed entry would invite reading it as
4007
+ // progress toward a destruction that did not happen. The attestation that matters is `destroyed`.
4008
+ warmRowsDeleted: 0
4009
+ };
4010
+ }
3991
4011
  destroyed.push(result);
3992
4012
  if (result.cryptoShredded) {
3993
4013
  segmentsShredded += 1;