Skip to content

Commit

Permalink
Support read-only bitround codec
Browse files Browse the repository at this point in the history
Fixes #233. Introduces `BitroundCodec` with a no-op for decoding because
bit-rounding is lossy, and precision cannot be restored. Encoding is not
yet implemented, reflecting zarrita's current focus on read-heavy
contexts. Open an issue if encoding support is needed.
  • Loading branch information
manzt committed Dec 3, 2024
1 parent ea665ce commit 9ba5e2e
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 1 deletion.
4 changes: 3 additions & 1 deletion packages/core/src/codecs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { Crc32cCodec } from "./codecs/crc32c.js";
import { JsonCodec } from "./codecs/json2.js";
import { TransposeCodec } from "./codecs/transpose.js";
import { VLenUTF8 } from "./codecs/vlen-utf8.js";
import { BitroundCodec } from "./codecs/bitround.js";

type ChunkMetadata<D extends DataType> = {
data_type: D;
Expand All @@ -31,7 +32,8 @@ function create_default_registry(): Map<string, () => Promise<CodecEntry>> {
.set("bytes", () => BytesCodec)
.set("crc32c", () => Crc32cCodec)
.set("vlen-utf8", () => VLenUTF8)
.set("json2", () => JsonCodec);
.set("json2", () => JsonCodec)
.set("bitround", () => BitroundCodec);
}

export const registry: Map<string, () => Promise<CodecEntry>> =
Expand Down
53 changes: 53 additions & 0 deletions packages/core/src/codecs/bitround.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import type { Chunk, Float32, Float64 } from "../metadata.js";

/**
* A codec for bit-rounding.
*
* Reduces floating-point precision by truncating mantissa bits during encoding.
* Decoding is a no-op as the process is lossy and precision cannot be restored.
*
* Note: {@link BitroundCodec.encode} is not yet implemented since Zarrita is
* primarily used in read-only contexts (web browser). If you need encoding support,
* please open an issue at {@link https://github.com/manzt/zarrita.js/issues}.
*
* @see {@link https://github.com/zarr-developers/numcodecs/blob/main/numcodecs/bitround.py}
* for the original Python implementation.
*
* @remarks
* Data types are not validated, and `float16` arrays are not supported (reflecting browser support).
*/
export class BitroundCodec<D extends Float64 | Float32> {
kind = "array_to_array";

constructor(configuration: { keepbits: number }, _meta: { data_type: D }) {
if (configuration.keepbits < 0) {
throw new Error("keepbits must be zero or positive");
}
}

static fromConfig<D extends Float32 | Float64>(
configuration: { keepbits: number },
meta: { data_type: D },
): BitroundCodec<D> {
return new BitroundCodec(configuration, meta);
}

/**
* Encode a chunk of data with bit-rounding.
* @param _arr - The chunk to encode
*/
encode(_arr: Chunk<D>): Chunk<D> {
throw new Error(
"`BitroundCodec.encode` is not implemented. Please open an issue at https://github.com/manzt/zarrita.js/issues.",
);
}

/**
* Decode a chunk of data (no-op).
* @param arr - The chunk to decode
* @returns The decoded chunk
*/
decode(arr: Chunk<D>): Chunk<D> {
return arr; // No-op as bit-rounding is lossy
}
}

0 comments on commit 9ba5e2e

Please sign in to comment.