diff --git a/CHANGELOG.md b/CHANGELOG.md index a073fe3e..e5ec777e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,8 +15,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Read `vortex.parquet.variant`, the encoding vortex-jni's default writer uses for Arrow `arrow.parquet.variant` columns: each row's Apache Variant `metadata`/`value` binaries come back as a struct ([#445](https://github.com/dfa1/vortex-java/issues/445)). +- Read `vortex.zstd_buffers`, Rust's opt-in buffer-level Zstd encoding (`zstd2026.02.0`) ([#444](https://github.com/dfa1/vortex-java/issues/444)). ### Fixed +- Null rows of Rust-written `vortex.varbin` columns read as empty values: the decoder ignored the validity child ([#444](https://github.com/dfa1/vortex-java/issues/444)). +- A corrupt `vortex.zstd` frame surfaced as the zstd binding's `ZstdException` instead of `VortexException` ([#444](https://github.com/dfa1/vortex-java/issues/444)). - Dictionary-encoded Binary columns (e.g. the `value` child of `vortex.parquet.variant`) failed to read with a `ClassCastException` ([#445](https://github.com/dfa1/vortex-java/issues/445)). - Null rows of Rust-written `vortex.list` columns read as empty lists: the decoder ignored the list's validity child. - CSV export (`CsvExporter`, `vortex export`) failed on list-view columns with `unsupported array type for CSV export: ListViewArray`. diff --git a/core/src/main/java/io/github/dfa1/vortex/core/model/Editions.java b/core/src/main/java/io/github/dfa1/vortex/core/model/Editions.java index 3b4ef9a6..ef32a478 100644 --- a/core/src/main/java/io/github/dfa1/vortex/core/model/Editions.java +++ b/core/src/main/java/io/github/dfa1/vortex/core/model/Editions.java @@ -23,10 +23,8 @@ /// zone-map aggregates) has no members here. Encodings in no edition at all — `fastlanes.delta`, /// `vortex.patched` — are writable only with the guard turned off, as in Rust. /// -/// vortex-java implements every `core`-family encoding (`vortex.parquet.variant` read only), but not -/// `zstd`'s `vortex.zstd_buffers`, which has no [EncodingId.WellKnown] constant yet and is named as -/// an [EncodingId.Custom] instead: the catalog mirrors upstream faithfully rather than being -/// truncated to what is implemented today. +/// vortex-java implements every encoding in the catalog; `vortex.parquet.variant` and +/// `vortex.zstd_buffers` are read only. public final class Editions { /// The baseline `core` edition: stable encodings writable by Vortex (Rust reference) 0.36.0. @@ -85,10 +83,10 @@ public final class Editions { /// The February 2026 draft edition of the `zstd` family, declared by Rust's `vortex-zstd` plugin: /// buffer-level Zstd that keeps an array's buffer layout for GPU decompression. vortex-java - /// does not implement `vortex.zstd_buffers` yet, hence the [EncodingId.Custom]. + /// reads `vortex.zstd_buffers` but does not write it. public static final Edition ZSTD_2026_02_0 = new Edition( new EditionId(EditionFamily.ZSTD, YearMonth.of(2026, 2), 0), - Set.of(new EncodingId.Custom("vortex.zstd_buffers"))); + Set.of(EncodingId.VORTEX_ZSTD_BUFFERS)); /// Every declared edition, in Rust's declaration order (core declarations first, then the /// plugin-declared families). Order matters: diff --git a/core/src/main/java/io/github/dfa1/vortex/core/model/EncodingId.java b/core/src/main/java/io/github/dfa1/vortex/core/model/EncodingId.java index 8baf60c2..e5919683 100644 --- a/core/src/main/java/io/github/dfa1/vortex/core/model/EncodingId.java +++ b/core/src/main/java/io/github/dfa1/vortex/core/model/EncodingId.java @@ -115,6 +115,9 @@ enum WellKnown implements EncodingId { /// Parquet Variant physical encoding (`vortex.parquet.variant`): per-row Apache Variant binary /// `metadata` and `value` children, plus an optional shredded `typed_value` child. VORTEX_PARQUET_VARIANT("vortex.parquet.variant"), + /// Buffer-level Zstd (`vortex.zstd_buffers`): each buffer of a wrapped array compressed + /// independently, keeping its layout; the `zstd` edition family, opt-in in Rust. + VORTEX_ZSTD_BUFFERS("vortex.zstd_buffers"), ; // O(1) access to a WellKnown constant by its string representation @@ -258,4 +261,6 @@ public String toString() { WellKnown VORTEX_VARIANT = WellKnown.VORTEX_VARIANT; /// Well-known `vortex.parquet.variant` id. WellKnown VORTEX_PARQUET_VARIANT = WellKnown.VORTEX_PARQUET_VARIANT; + /// Well-known `vortex.zstd_buffers` id. + WellKnown VORTEX_ZSTD_BUFFERS = WellKnown.VORTEX_ZSTD_BUFFERS; } diff --git a/core/src/main/java/io/github/dfa1/vortex/core/proto/ProtoZstdBuffersMetadata.java b/core/src/main/java/io/github/dfa1/vortex/core/proto/ProtoZstdBuffersMetadata.java new file mode 100644 index 00000000..0beb7626 --- /dev/null +++ b/core/src/main/java/io/github/dfa1/vortex/core/proto/ProtoZstdBuffersMetadata.java @@ -0,0 +1,165 @@ +package io.github.dfa1.vortex.core.proto; + +import java.io.IOException; +import java.lang.foreign.MemorySegment; +import java.util.Arrays; +import javax.annotation.processing.Generated; + +/// Generated from proto3 message {@code vortex.encodings.ZstdBuffersMetadata}. +/// Do not edit by hand — regenerate via {@code ./mvnw generate-sources -pl core -P regenerate-sources}. +/// @param inner_encoding_id field tag 1 +/// @param inner_metadata field tag 2 +/// @param uncompressed_sizes field tag 3 +/// @param buffer_alignments field tag 4 +/// @param child_dtypes field tag 5 +/// @param child_lens field tag 6 +@Generated("io.github.dfa1.vortex.protogen.CodeGen") +public record ProtoZstdBuffersMetadata( + String inner_encoding_id, + byte[] inner_metadata, + java.util.List uncompressed_sizes, + java.util.List buffer_alignments, + java.util.List child_dtypes, + java.util.List child_lens +) { + + /// Decodes a {@code vortex.encodings.ZstdBuffersMetadata} from a slice of a memory segment. + /// @param __seg backing segment + /// @param __off start offset in bytes + /// @param __len payload length in bytes + /// @return decoded record + /// @throws IOException if the slice is malformed or truncated + public static ProtoZstdBuffersMetadata decode(MemorySegment __seg, long __off, long __len) throws IOException { + ProtoReader r = new ProtoReader(__seg, __off, __len); + String inner_encoding_id = ""; + byte[] inner_metadata = new byte[0]; + java.util.List uncompressed_sizes = new java.util.ArrayList<>(); + java.util.List buffer_alignments = new java.util.ArrayList<>(); + java.util.List child_dtypes = new java.util.ArrayList<>(); + java.util.List child_lens = new java.util.ArrayList<>(); + while (r.hasMore()) { + int tag = r.readVarint32(); + switch (tag >>> 3) { + case 1 -> { + inner_encoding_id = r.readString(); + } + case 2 -> { + inner_metadata = r.readBytes(); + } + case 3 -> { + int wt = tag & 7; + if (wt == 2) { + int len = r.readVarint32(); + java.util.List __target = uncompressed_sizes; + r.readPacked(len, reader -> __target.add(reader.readVarint64())); + } else { + uncompressed_sizes.add(r.readVarint64()); + } + } + case 4 -> { + int wt = tag & 7; + if (wt == 2) { + int len = r.readVarint32(); + java.util.List __target = buffer_alignments; + r.readPacked(len, reader -> __target.add(reader.readVarint32())); + } else { + buffer_alignments.add(r.readVarint32()); + } + } + case 5 -> { + MemorySegment __slice = r.readLenDelimSegment(); + child_dtypes.add(ProtoDType.decode(__slice, 0, __slice.byteSize())); + } + case 6 -> { + int wt = tag & 7; + if (wt == 2) { + int len = r.readVarint32(); + java.util.List __target = child_lens; + r.readPacked(len, reader -> __target.add(reader.readVarint64())); + } else { + child_lens.add(r.readVarint64()); + } + } + default -> r.skipField(tag & 7); + } + } + return new ProtoZstdBuffersMetadata(inner_encoding_id, inner_metadata, uncompressed_sizes, buffer_alignments, child_dtypes, child_lens); + } + + /// Encodes this record to a proto3-wire-format byte array. + /// @return encoded bytes + public byte[] encode() { + ProtoWriter w = new ProtoWriter(); + encodeTo(w); + return w.toByteArray(); + } + + void encodeTo(ProtoWriter w) { + if (inner_encoding_id != null && !inner_encoding_id.isEmpty()) { + w.writeTag(1, 2); + w.writeString(inner_encoding_id); + } + if (inner_metadata != null && inner_metadata.length != 0) { + w.writeTag(2, 2); + w.writeBytes(inner_metadata); + } + if (!uncompressed_sizes.isEmpty()) { + w.writeTag(3, 2); + int __mark = w.beginLenDelim(); + for (Long __v : uncompressed_sizes) { + w.writeVarint64(__v); + } + w.endLenDelim(__mark); + } + if (!buffer_alignments.isEmpty()) { + w.writeTag(4, 2); + int __mark = w.beginLenDelim(); + for (Integer __v : buffer_alignments) { + w.writeVarint32(__v); + } + w.endLenDelim(__mark); + } + for (ProtoDType __v : child_dtypes) { + w.writeTag(5, 2); + int __mark = w.beginLenDelim(); + __v.encodeTo(w); + w.endLenDelim(__mark); + } + if (!child_lens.isEmpty()) { + w.writeTag(6, 2); + int __mark = w.beginLenDelim(); + for (Long __v : child_lens) { + w.writeVarint64(__v); + } + w.endLenDelim(__mark); + } + } + + @Override + public boolean equals(Object __o) { + if (this == __o) { + return true; + } + if (!(__o instanceof ProtoZstdBuffersMetadata __that)) { + return false; + } + return java.util.Objects.equals(inner_encoding_id, __that.inner_encoding_id) + && java.util.Arrays.equals(inner_metadata, __that.inner_metadata) + && java.util.Objects.equals(uncompressed_sizes, __that.uncompressed_sizes) + && java.util.Objects.equals(buffer_alignments, __that.buffer_alignments) + && java.util.Objects.equals(child_dtypes, __that.child_dtypes) + && java.util.Objects.equals(child_lens, __that.child_lens); + } + + @Override + public int hashCode() { + int __h = 1; + __h = 31 * __h + java.util.Objects.hashCode(inner_encoding_id); + __h = 31 * __h + java.util.Arrays.hashCode(inner_metadata); + __h = 31 * __h + java.util.Objects.hashCode(uncompressed_sizes); + __h = 31 * __h + java.util.Objects.hashCode(buffer_alignments); + __h = 31 * __h + java.util.Objects.hashCode(child_dtypes); + __h = 31 * __h + java.util.Objects.hashCode(child_lens); + return __h; + } +} diff --git a/core/src/main/proto/encodings.proto b/core/src/main/proto/encodings.proto index a9feb647..cbb73484 100644 --- a/core/src/main/proto/encodings.proto +++ b/core/src/main/proto/encodings.proto @@ -148,6 +148,15 @@ message VariantMetadata { optional vortex.dtype.DType shredded_dtype = 1; } +message ZstdBuffersMetadata { + string inner_encoding_id = 1; + bytes inner_metadata = 2; + repeated uint64 uncompressed_sizes = 3; + repeated uint32 buffer_alignments = 4; + repeated vortex.dtype.DType child_dtypes = 5; + repeated uint64 child_lens = 6; +} + message ParquetVariantMetadata { bool has_value = 1; optional vortex.dtype.DType typed_value_dtype = 2; diff --git a/core/src/test/java/io/github/dfa1/vortex/core/model/EditionsTest.java b/core/src/test/java/io/github/dfa1/vortex/core/model/EditionsTest.java index a41713fb..7b39ef9c 100644 --- a/core/src/test/java/io/github/dfa1/vortex/core/model/EditionsTest.java +++ b/core/src/test/java/io/github/dfa1/vortex/core/model/EditionsTest.java @@ -170,7 +170,7 @@ void owningEdition_zstdBuffers_isThePluginDeclaredZstdFamily() { // Given — vortex.zstd_buffers joins Rust's zstd family, declared by the vortex-zstd // plugin, not core (array-level vortex.zstd is core2025.06.0) // When - Optional result = Editions.owningEdition(new EncodingId.Custom("vortex.zstd_buffers")); + Optional result = Editions.owningEdition(EncodingId.VORTEX_ZSTD_BUFFERS); // Then assertThat(result).contains(Editions.ZSTD_2026_02_0); diff --git a/docs/compatibility.md b/docs/compatibility.md index c782c955..0c4d751c 100644 --- a/docs/compatibility.md +++ b/docs/compatibility.md @@ -123,6 +123,7 @@ decimals ([#430](https://github.com/dfa1/vortex-java/pull/430)) and nulls in nul | `vortex.patched` | `PatchedEncodingDecoder` | `PatchedEncodingEncoder` | ✅ | ✅ | Primitive PTypes; base + chunked patches (1024-elem blocks) | | `vortex.variant` | `VariantEncodingDecoder` | `VariantEncodingEncoder` | ✅ | ✅ | Canonical container; constant / chunked-of-constants core + optional shredded child. Typed-scalar values only — nested objects need `parquet.variant` (ADR 0014) | | `vortex.parquet.variant` | `ParquetVariantEncodingDecoder` | — | ✅ | ❌ | Read only: decodes to a struct `{metadata, value?, typed_value?}` of Apache Variant binaries (Arrow's `arrow.parquet.variant` storage shape), masked by row validity. Writing is not implemented; Java writes typed-scalar variants through `vortex.variant` (ADR 0014) | +| `vortex.zstd_buffers` | `ZstdBuffersEncodingDecoder` | — | ✅ | ❌ | Read only (`zstd2026.02.0`, opt-in in Rust): each buffer of any wrapped encoding is Zstd-decompressed at its declared alignment, then the inner encoding decodes with its own children. Needs the optional zstd binding, like `vortex.zstd`. Interop-tested against a Rust-written fixture (`scripts/fixtures/zstd-buffers`) | | `vortex.onpair` | `OnPairEncodingDecoder` | `OnPairEncodingEncoder` | ✅ | ✅ | Utf8, Binary; `core2026.08.1`, a cascade candidate under the default edition (competes with FSST, as in Rust) | ### Decode shape @@ -218,7 +219,7 @@ guarantee once frozen (ADR 0023) — a write-time/read-time policy, not part of | `core2026.08.2` | `core` | `vortex.map` | | `core2026.08.3` | `core` | `vortex.variant`, `vortex.parquet.variant` (read only) — **default write target** | | `preview2026.08.0` | `preview` | nothing yet | -| `zstd2026.02.0` | `zstd` | `vortex.zstd_buffers` ❌ not implemented (buffer-level Zstd for GPU decode; declared by Rust's `vortex-zstd` plugin, opt-in) | +| `zstd2026.02.0` | `zstd` | `vortex.zstd_buffers` (read only; buffer-level Zstd for GPU decode; declared by Rust's `vortex-zstd` plugin, opt-in) | Mirrors Rust's `vortex-edition` declarations at the pinned vortex-jni release (0.86.1); `EditionCatalogParityIntegrationTest` fails the build on drift. `core` editions are frozen with a diff --git a/docs/reference.md b/docs/reference.md index c7950cbe..2f60917a 100644 --- a/docs/reference.md +++ b/docs/reference.md @@ -347,9 +347,8 @@ targeted edition is ever persisted into a `.vortex` file. | `cumulativeMembers(Edition)` | The edition's own additions plus every earlier same-family edition's | | `owningEdition(EncodingId)` | The edition an id first joined, or empty if it belongs to none | -vortex-java implements every `core`-family encoding (`vortex.parquet.variant` read only), but not -`zstd`'s `vortex.zstd_buffers`, which resolves to `EncodingId.Custom` and is stored in the catalog -anyway, mirroring upstream faithfully. +vortex-java implements every encoding in the catalog; `vortex.parquet.variant` and `zstd`'s +`vortex.zstd_buffers` are read only. `fastlanes.delta` and `vortex.patched` belong to no edition, as in Rust. ### Writer integration (`WriteOptions#editions()`) diff --git a/integration/src/test/java/io/github/dfa1/vortex/integration/ParquetVariantInteropIntegrationTest.java b/integration/src/test/java/io/github/dfa1/vortex/integration/ParquetVariantInteropIntegrationTest.java index 66555285..0e69251c 100644 --- a/integration/src/test/java/io/github/dfa1/vortex/integration/ParquetVariantInteropIntegrationTest.java +++ b/integration/src/test/java/io/github/dfa1/vortex/integration/ParquetVariantInteropIntegrationTest.java @@ -222,14 +222,16 @@ private static List readShredded(Path file) throws IOException { while (iter.hasNext()) { VariantArray column = iter.next().column("v"); StructArray struct = (StructArray) column.coreStorage(); - VarBinArray value = (VarBinArray) struct.field(1); + MaskedArray value = (MaskedArray) struct.field(1); MaskedArray typed = (MaskedArray) column.shredded(); for (long i = 0; i < struct.length(); i++) { int row = rows.size(); + // Exactly one of value / typed_value holds each row; the other is null. + assertThat(value.isValid(i)).as("value validity, row %d", row).isNotEqualTo(typed.isValid(i)); if (typed.isValid(i)) { rows.add("typed:" + ((IntArray) typed.inner()).getInt(i)); } else { - assertThat(value.getBytes(i)).isEqualTo(int8OrString(row)); + assertThat(((VarBinArray) value.inner()).getBytes(i)).isEqualTo(int8OrString(row)); rows.add("value:" + row); } } diff --git a/integration/src/test/java/io/github/dfa1/vortex/integration/ZstdBuffersInteropIntegrationTest.java b/integration/src/test/java/io/github/dfa1/vortex/integration/ZstdBuffersInteropIntegrationTest.java new file mode 100644 index 00000000..4affc66a --- /dev/null +++ b/integration/src/test/java/io/github/dfa1/vortex/integration/ZstdBuffersInteropIntegrationTest.java @@ -0,0 +1,76 @@ +package io.github.dfa1.vortex.integration; + +import io.github.dfa1.vortex.inspect.InspectorTree; +import io.github.dfa1.vortex.reader.ReadRegistry; +import io.github.dfa1.vortex.reader.ScanOptions; +import io.github.dfa1.vortex.reader.Chunk; +import io.github.dfa1.vortex.reader.VortexReader; +import io.github.dfa1.vortex.reader.array.Array; +import io.github.dfa1.vortex.reader.array.IntArray; +import io.github.dfa1.vortex.reader.array.MaskedArray; +import io.github.dfa1.vortex.reader.array.VarBinArray; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +import static org.assertj.core.api.Assertions.assertThat; + +/// Reads `fixtures/zstd_buffers.vortex`, written by Rust's own `ZstdBuffers::compress` under the +/// opt-in `zstd2026.02.0` edition (`scripts/fixtures/zstd-buffers`); vortex-jni cannot emit +/// `vortex.zstd_buffers`, so a checked-in fixture stands in for a jni-written file (#444). +/// +/// Both columns wrap an inner array that has children as well as buffers (a primitive's validity, +/// a varbin's offsets and validity), so the decoder must hand the inner encoding its decompressed +/// buffers and its untouched children together. +class ZstdBuffersInteropIntegrationTest { + + private static final int ROWS = 1_000; + + @Test + void rustWritesZstdBuffers_javaReadsEveryRow() throws IOException, URISyntaxException { + // Given + Path file = Path.of(Objects.requireNonNull( + getClass().getResource("/fixtures/zstd_buffers.vortex")).toURI()); + + // When + List result = new ArrayList<>(ROWS); + try (var reader = VortexReader.open(file, ReadRegistry.loadAll()); + var iter = reader.scan(ScanOptions.columns("ints", "strs"))) { + while (iter.hasNext()) { + Chunk chunk = iter.next(); + Array ints = chunk.column("ints"); + Array strs = chunk.column("strs"); + for (long i = 0; i < chunk.rowCount(); i++) { + result.add(render(ints, i, true) + "|" + render(strs, i, false)); + } + } + } + + // Then — the fixture's generator documents these values + try (var vf = VortexReader.open(file, ReadRegistry.loadAll())) { + assertThat(InspectorTree.build(vf).usedEncodings()).contains("vortex.zstd_buffers"); + } + assertThat(result).hasSize(ROWS); + for (int i = 0; i < ROWS; i++) { + String ints = i % 7 == 0 ? "null" : String.valueOf(i * 3 - 500); + String strs = i % 5 == 0 ? "null" : "s" + i % 13; + assertThat(result.get(i)).as("row %d", i).isEqualTo(ints + "|" + strs); + } + } + + private static String render(Array column, long i, boolean isInt) { + Array values = column; + if (column instanceof MaskedArray masked) { + if (!masked.isValid(i)) { + return "null"; + } + values = masked.inner(); + } + return isInt ? String.valueOf(((IntArray) values).getInt(i)) : ((VarBinArray) values).getString(i); + } +} diff --git a/integration/src/test/resources/fixtures/zstd_buffers.vortex b/integration/src/test/resources/fixtures/zstd_buffers.vortex new file mode 100644 index 00000000..02d49ff7 Binary files /dev/null and b/integration/src/test/resources/fixtures/zstd_buffers.vortex differ diff --git a/reader/src/main/java/io/github/dfa1/vortex/reader/ReadRegistry.java b/reader/src/main/java/io/github/dfa1/vortex/reader/ReadRegistry.java index 5fccf0bf..cdf7d352 100644 --- a/reader/src/main/java/io/github/dfa1/vortex/reader/ReadRegistry.java +++ b/reader/src/main/java/io/github/dfa1/vortex/reader/ReadRegistry.java @@ -44,6 +44,7 @@ import io.github.dfa1.vortex.reader.decode.VarBinViewEncodingDecoder; import io.github.dfa1.vortex.reader.decode.VariantEncodingDecoder; import io.github.dfa1.vortex.reader.decode.ZigZagEncodingDecoder; +import io.github.dfa1.vortex.reader.decode.ZstdBuffersEncodingDecoder; import io.github.dfa1.vortex.reader.decode.ZstdEncodingDecoder; import java.lang.foreign.MemorySegment; @@ -245,6 +246,7 @@ public Builder registerDefaults() { .register(new VariantEncodingDecoder()) .register(new VarBinViewEncodingDecoder()) .register(new ZigZagEncodingDecoder()) + .register(new ZstdBuffersEncodingDecoder()) .register(new ZstdEncodingDecoder()); } diff --git a/reader/src/main/java/io/github/dfa1/vortex/reader/decode/VarBinEncodingDecoder.java b/reader/src/main/java/io/github/dfa1/vortex/reader/decode/VarBinEncodingDecoder.java index 19208707..b9ce5e47 100644 --- a/reader/src/main/java/io/github/dfa1/vortex/reader/decode/VarBinEncodingDecoder.java +++ b/reader/src/main/java/io/github/dfa1/vortex/reader/decode/VarBinEncodingDecoder.java @@ -4,6 +4,7 @@ import io.github.dfa1.vortex.core.model.PType; import io.github.dfa1.vortex.core.error.VortexException; import io.github.dfa1.vortex.reader.array.Array; +import io.github.dfa1.vortex.reader.array.MaskedArray; import io.github.dfa1.vortex.reader.array.VarBinOffsetArray; import io.github.dfa1.vortex.core.model.EncodingId; import io.github.dfa1.vortex.core.proto.ProtoVarBinMetadata; @@ -47,7 +48,18 @@ public Array decode(DecodeContext ctx) { } MemorySegment bytes = ctx.buffer(0); + Array values = new VarBinOffsetArray(ctx.dtype(), n, bytes, offsets, offsetsPtype); - return new VarBinOffsetArray(ctx.dtype(), n, bytes, offsets, offsetsPtype); + // Children are [offsets, validity?], as Rust's VarBin deserialize reads them; ignoring the + // validity child read every null row back as an empty value. + int numChildren = ctx.node().children().length; + if (numChildren == 1) { + return values; + } + if (numChildren != 2) { + throw new VortexException(EncodingId.VORTEX_VARBIN, "expected 1 or 2 children, got " + numChildren); + } + Array validity = ctx.decodeChild(1, DType.BOOL, n); + return new MaskedArray(values, MaskedArray.requireBoolArray(validity, EncodingId.VORTEX_VARBIN, "validity child")); } } diff --git a/reader/src/main/java/io/github/dfa1/vortex/reader/decode/ZstdBuffersEncodingDecoder.java b/reader/src/main/java/io/github/dfa1/vortex/reader/decode/ZstdBuffersEncodingDecoder.java new file mode 100644 index 00000000..45c81eb4 --- /dev/null +++ b/reader/src/main/java/io/github/dfa1/vortex/reader/decode/ZstdBuffersEncodingDecoder.java @@ -0,0 +1,109 @@ +package io.github.dfa1.vortex.reader.decode; + +import io.github.dfa1.vortex.core.error.VortexException; +import io.github.dfa1.vortex.core.io.IoBounds; +import io.github.dfa1.vortex.core.model.EncodingId; +import io.github.dfa1.vortex.core.proto.ProtoZstdBuffersMetadata; +import io.github.dfa1.vortex.reader.array.Array; +import io.github.dfa1.zstd.ZstdDecompressContext; + +import java.io.IOException; +import java.lang.foreign.Arena; +import java.lang.foreign.MemorySegment; +import java.util.Arrays; + +/// Read-only decoder for `vortex.zstd_buffers` (the opt-in `zstd2026.02.0` edition): an arbitrary +/// inner array whose buffers were each Zstd-compressed independently, keeping their layout. Mirrors +/// Rust's `ZstdBuffers::deserialize` + `build_inner`: the metadata names the inner encoding and +/// carries its metadata plus each buffer's uncompressed size and alignment; the children are the +/// inner array's own, passed through untouched. +/// +/// Decoding decompresses every buffer into an arena segment at its declared alignment, appends +/// those segments to the context's segment table, and decodes a synthetic inner node over them +/// through the registry, so any registered encoding can sit inside. +public final class ZstdBuffersEncodingDecoder implements EncodingDecoder { + + // ponytail: Rust stores alignment as a u16-sized power of two; capping at 64 KiB keeps a crafted + // value from turning a small buffer into a huge aligned allocation. Raise it if Rust ever does. + private static final long MAX_ALIGNMENT = 1L << 16; + + @Override + public EncodingId encodingId() { + return EncodingId.VORTEX_ZSTD_BUFFERS; + } + + @Override + public Array decode(DecodeContext ctx) { + ZstdEncodingDecoder.requireBinding(ZstdEncodingDecoder.ZSTD_BINDING_PRESENT, EncodingId.VORTEX_ZSTD_BUFFERS); + // A zstd_buffers inner array may itself be zstd_buffers, nested through the metadata rather + // than the node tree, so the file's depth guard never sees it. Unwrap those levels in a loop + // instead of recursing through the registry: each nested metadata is strictly smaller, so + // the loop ends, and a crafted chain cannot overflow the stack. + DecodeContext current = ctx; + do { + current = unwrap(current); + } while (current.node().encodingId() == EncodingId.VORTEX_ZSTD_BUFFERS); + return current.registry().decode(current); + } + + /// Decompresses one `vortex.zstd_buffers` level, returning the context for its inner array. + private static DecodeContext unwrap(DecodeContext ctx) { + ProtoZstdBuffersMetadata meta = parseMetadata(ctx.metadata()); + + int nBuffers = ctx.node().bufferIndices().length; + if (meta.uncompressed_sizes().size() != nBuffers || meta.buffer_alignments().size() != nBuffers) { + throw new VortexException(EncodingId.VORTEX_ZSTD_BUFFERS, nBuffers + " compressed buffers but " + + meta.uncompressed_sizes().size() + " sizes and " + meta.buffer_alignments().size() + " alignments"); + } + int nChildren = ctx.node().children().length; + if (meta.child_dtypes().size() != nChildren || meta.child_lens().size() != nChildren) { + throw new VortexException(EncodingId.VORTEX_ZSTD_BUFFERS, nChildren + " children but " + + meta.child_dtypes().size() + " child dtypes and " + meta.child_lens().size() + " child lengths"); + } + if (meta.inner_encoding_id() == null || meta.inner_encoding_id().isBlank()) { + throw new VortexException(EncodingId.VORTEX_ZSTD_BUFFERS, "missing inner encoding id"); + } + + int base = ctx.segmentBuffers().length; + MemorySegment[] segments = Arrays.copyOf(ctx.segmentBuffers(), base + nBuffers); + int[] innerBuffers = new int[nBuffers]; + try (ZstdDecompressContext dctx = new ZstdDecompressContext(); + Arena scratch = Arena.ofConfined()) { + for (int i = 0; i < nBuffers; i++) { + int size = IoBounds.toIntSize(meta.uncompressed_sizes().get(i)); + MemorySegment dst = ctx.arena().allocate(size, alignment(meta.buffer_alignments().get(i))); + MemorySegment src = ZstdEncodingDecoder.asNative(ctx.buffer(i), scratch); + ZstdEncodingDecoder.decompressFrame(dctx, dst, src, null, EncodingId.VORTEX_ZSTD_BUFFERS, i); + segments[base + i] = dst; + innerBuffers[i] = base + i; + } + } + + // Empty inner metadata stays an empty segment, not null: an all-default proto (e.g. varbin + // with U8 offsets) encodes to zero bytes, and decoders read null as "missing metadata". + byte[] innerMetadata = meta.inner_metadata() == null ? new byte[0] : meta.inner_metadata(); + ArrayNode inner = new ArrayNode(EncodingId.parse(meta.inner_encoding_id()), + MemorySegment.ofArray(innerMetadata), ctx.node().children(), innerBuffers); + return new DecodeContext(inner, ctx.dtype(), ctx.rowCount(), segments, ctx.registry(), ctx.arena()); + } + + private static long alignment(int declared) { + long value = Integer.toUnsignedLong(declared); + if (value == 0 || Long.bitCount(value) != 1 || value > MAX_ALIGNMENT) { + throw new VortexException(EncodingId.VORTEX_ZSTD_BUFFERS, + "buffer alignment must be a power of two up to " + MAX_ALIGNMENT + ", got " + value); + } + return value; + } + + private static ProtoZstdBuffersMetadata parseMetadata(MemorySegment rawMeta) { + if (rawMeta == null || rawMeta.byteSize() == 0) { + throw new VortexException(EncodingId.VORTEX_ZSTD_BUFFERS, "missing metadata"); + } + try { + return ProtoZstdBuffersMetadata.decode(rawMeta, 0, rawMeta.byteSize()); + } catch (IOException e) { + throw new VortexException(EncodingId.VORTEX_ZSTD_BUFFERS, "invalid metadata", e); + } + } +} diff --git a/reader/src/main/java/io/github/dfa1/vortex/reader/decode/ZstdEncodingDecoder.java b/reader/src/main/java/io/github/dfa1/vortex/reader/decode/ZstdEncodingDecoder.java index b562b6df..509c2407 100644 --- a/reader/src/main/java/io/github/dfa1/vortex/reader/decode/ZstdEncodingDecoder.java +++ b/reader/src/main/java/io/github/dfa1/vortex/reader/decode/ZstdEncodingDecoder.java @@ -15,6 +15,7 @@ import io.github.dfa1.zstd.ZstdDecompressContext; import io.github.dfa1.zstd.ZstdDecompressDictionary; +import io.github.dfa1.zstd.ZstdException; import java.io.IOException; import java.lang.foreign.Arena; @@ -26,7 +27,7 @@ public final class ZstdEncodingDecoder implements EncodingDecoder { // The io.github.dfa1.zstd binding is an OPTIONAL dependency: probe once so a reader // touching vortex.zstd without it gets an actionable message instead of a raw // NoClassDefFoundError surfacing from the first binding call. - private static final boolean ZSTD_BINDING_PRESENT = + static final boolean ZSTD_BINDING_PRESENT = bindingPresent("io.github.dfa1.zstd.ZstdDecompressContext"); /// Reports whether the named binding class is loadable — package-private and @@ -46,11 +47,12 @@ static boolean bindingPresent(String className) { /// Fails with an actionable [VortexException] when the optional zstd binding is absent. /// - /// @param present whether the binding is on the classpath + /// @param present whether the binding is on the classpath + /// @param encoding the Zstd-backed encoding the file uses /// @throws VortexException naming the two artifacts to add, if `present` is `false` - static void requireBinding(boolean present) { + static void requireBinding(boolean present, EncodingId encoding) { if (!present) { - throw new VortexException(EncodingId.VORTEX_ZSTD, "this file uses vortex.zstd, but the " + throw new VortexException(encoding, "this file uses " + encoding.id() + ", but the " + "optional zstd binding is not on the classpath — add io.github.dfa1.zstd:zstd " + "and io.github.dfa1.zstd:zstd-platform (versions pinned by the vortex BOM)"); } @@ -63,7 +65,7 @@ public EncodingId encodingId() { @Override public Array decode(DecodeContext ctx) { - requireBinding(ZSTD_BINDING_PRESENT); + requireBinding(ZSTD_BINDING_PRESENT, EncodingId.VORTEX_ZSTD); MemorySegment rawMeta = ctx.metadata(); if (rawMeta == null) { throw new VortexException(EncodingId.VORTEX_ZSTD, "missing metadata"); @@ -203,13 +205,7 @@ private static MemorySegment decompressFrames( MemorySegment src = asNative(ctx.buffer(frameBufferBase + i), scratch); int uncompSize = IoBounds.toIntSize(meta.frames().get(i).uncompressed_size()); MemorySegment dst = out.asSlice(outOffset, uncompSize); - long written = dictionary == null - ? dctx.decompress(dst, src) - : dctx.decompress(dst, src, dictionary); - if (written != uncompSize) { - throw new VortexException(EncodingId.VORTEX_ZSTD, - "frame " + i + ": expected " + uncompSize + " bytes, got " + written); - } + decompressFrame(dctx, dst, src, dictionary, EncodingId.VORTEX_ZSTD, i); outOffset += uncompSize; } } finally { @@ -242,7 +238,31 @@ private static ZstdDecompressDictionary digestDictionary(MemorySegment dictBuffe /// Returns `seg` unchanged when it is already native (the production mmap path); otherwise /// copies it into `scratch` so the zero-copy native API can read it. - private static MemorySegment asNative(MemorySegment seg, Arena scratch) { + /// Decompresses one Zstd frame into exactly `dst`. A corrupt frame, or one whose content does + /// not fill `dst` exactly, throws [VortexException]: the binding reports frame errors as its + /// own unchecked `ZstdException`, which must not escape the reader (ADR 0003). + /// + /// @param dctx decompression context + /// @param dst output slice, sized to the frame's declared uncompressed size + /// @param src the compressed frame, native + /// @param dictionary shared dictionary, or `null` + /// @param encoding the encoding being decoded, for error attribution + /// @param frame frame index, for the error message + static void decompressFrame(ZstdDecompressContext dctx, MemorySegment dst, MemorySegment src, + ZstdDecompressDictionary dictionary, EncodingId encoding, int frame) { + long written; + try { + written = dictionary == null ? dctx.decompress(dst, src) : dctx.decompress(dst, src, dictionary); + } catch (ZstdException e) { + throw new VortexException(encoding, "frame " + frame + ": " + e.getMessage(), e); + } + if (written != dst.byteSize()) { + throw new VortexException(encoding, + "frame " + frame + ": expected " + dst.byteSize() + " bytes, got " + written); + } + } + + static MemorySegment asNative(MemorySegment seg, Arena scratch) { if (seg.isNative()) { return seg; } diff --git a/reader/src/test/java/io/github/dfa1/vortex/reader/decode/VarBinEncodingDecoderTest.java b/reader/src/test/java/io/github/dfa1/vortex/reader/decode/VarBinEncodingDecoderTest.java index 82c12d78..bbc24996 100644 --- a/reader/src/test/java/io/github/dfa1/vortex/reader/decode/VarBinEncodingDecoderTest.java +++ b/reader/src/test/java/io/github/dfa1/vortex/reader/decode/VarBinEncodingDecoderTest.java @@ -8,6 +8,7 @@ import io.github.dfa1.vortex.core.proto.ProtoVarBinMetadata; import io.github.dfa1.vortex.reader.ReadRegistry; import io.github.dfa1.vortex.reader.array.Array; +import io.github.dfa1.vortex.reader.array.MaskedArray; import io.github.dfa1.vortex.reader.array.VarBinArray; import io.github.dfa1.vortex.reader.array.VarBinOffsetArray; import org.junit.jupiter.api.Nested; @@ -55,6 +56,47 @@ void decode_i32Offsets_happyPath() { assertThat(arr.getBytes(2)).containsExactly('c'); } + /// Children are `[offsets, validity?]` (Rust's VarBin deserialize). The decoder used to ignore + /// the validity child, so every null row of a Rust-written nullable varbin read back as an + /// empty value (#444 surfaced it through `vortex.zstd_buffers`). + @Test + void decode_validityChild_masksNullRows() { + // Given "a", null, "c": validity bits 0b101 + ArrayNode offsetsNode = new ArrayNode(EncodingId.VORTEX_PRIMITIVE, null, new ArrayNode[0], new int[]{1}); + ArrayNode validityNode = new ArrayNode(EncodingId.VORTEX_BOOL, null, new ArrayNode[0], new int[]{2}); + ArrayNode varbinNode = new ArrayNode(EncodingId.VORTEX_VARBIN, i32OffsetsMeta(), + new ArrayNode[]{offsetsNode, validityNode}, new int[]{0}); + MemorySegment[] segments = {MemorySegment.ofArray("ac".getBytes(StandardCharsets.UTF_8)), + TestSegments.leInts(0, 1, 1, 2), MemorySegment.ofArray(new byte[]{0b101})}; + DecodeContext ctx = new DecodeContext(varbinNode, new DType.Utf8(true), 3, segments, + TestRegistry.ofDecoders(SUT, new PrimitiveEncodingDecoder(), new BoolEncodingDecoder()), Arena.ofAuto()); + + // When + Array result = SUT.decode(ctx); + + // Then + MaskedArray masked = (MaskedArray) result; + assertThat(masked.isValid(0)).isTrue(); + assertThat(masked.isValid(1)).isFalse(); + assertThat(((VarBinArray) masked.inner()).getString(2)).isEqualTo("c"); + } + + @Test + void decode_threeChildren_throws() { + // Given — Rust accepts only [offsets] or [offsets, validity] + ArrayNode offsetsNode = new ArrayNode(EncodingId.VORTEX_PRIMITIVE, null, new ArrayNode[0], new int[]{1}); + ArrayNode varbinNode = new ArrayNode(EncodingId.VORTEX_VARBIN, i32OffsetsMeta(), + new ArrayNode[]{offsetsNode, offsetsNode, offsetsNode}, new int[]{0}); + DecodeContext ctx = new DecodeContext(varbinNode, DType.UTF8, 1, + new MemorySegment[]{MemorySegment.ofArray(new byte[]{'a'}), TestSegments.leInts(0, 1)}, + REGISTRY, Arena.ofAuto()); + + // When / Then + assertThatThrownBy(() -> SUT.decode(ctx)) + .isInstanceOf(VortexException.class) + .hasMessageContaining("expected 1 or 2 children, got 3"); + } + /// Adversarial offsets from an untrusted file (TODO.md §Security, per-encoding /// adversarial tests). `decode()` deliberately never scans the offsets — VarBin decode /// is zero-copy and lazy — so every malformed offset has to be caught by the accessors, diff --git a/reader/src/test/java/io/github/dfa1/vortex/reader/decode/ZstdBindingGuardTest.java b/reader/src/test/java/io/github/dfa1/vortex/reader/decode/ZstdBindingGuardTest.java index 8336e126..11819c2e 100644 --- a/reader/src/test/java/io/github/dfa1/vortex/reader/decode/ZstdBindingGuardTest.java +++ b/reader/src/test/java/io/github/dfa1/vortex/reader/decode/ZstdBindingGuardTest.java @@ -1,6 +1,7 @@ package io.github.dfa1.vortex.reader.decode; import io.github.dfa1.vortex.core.error.VortexException; +import io.github.dfa1.vortex.core.model.EncodingId; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -37,7 +38,7 @@ void bindingPresent_absentClass_returnsFalse() { @Test void requireBinding_absent_throwsActionableVortexException() { // Given / When / Then — the message names the two artifacts a consumer must add - assertThatThrownBy(() -> ZstdEncodingDecoder.requireBinding(false)) + assertThatThrownBy(() -> ZstdEncodingDecoder.requireBinding(false, EncodingId.VORTEX_ZSTD)) .isInstanceOf(VortexException.class) .hasMessageContaining("io.github.dfa1.zstd:zstd") .hasMessageContaining("zstd-platform"); @@ -46,6 +47,6 @@ void requireBinding_absent_throwsActionableVortexException() { @Test void requireBinding_present_doesNotThrow() { // Given / When / Then - assertThatCode(() -> ZstdEncodingDecoder.requireBinding(true)).doesNotThrowAnyException(); + assertThatCode(() -> ZstdEncodingDecoder.requireBinding(true, EncodingId.VORTEX_ZSTD)).doesNotThrowAnyException(); } } diff --git a/reader/src/test/java/io/github/dfa1/vortex/reader/decode/ZstdBuffersEncodingDecoderTest.java b/reader/src/test/java/io/github/dfa1/vortex/reader/decode/ZstdBuffersEncodingDecoderTest.java new file mode 100644 index 00000000..2926919f --- /dev/null +++ b/reader/src/test/java/io/github/dfa1/vortex/reader/decode/ZstdBuffersEncodingDecoderTest.java @@ -0,0 +1,184 @@ +package io.github.dfa1.vortex.reader.decode; + +import io.github.dfa1.vortex.core.error.VortexException; +import io.github.dfa1.vortex.core.model.DType; +import io.github.dfa1.vortex.core.model.EncodingId; +import io.github.dfa1.vortex.core.proto.ProtoZstdBuffersMetadata; +import io.github.dfa1.vortex.core.testing.TestSegments; +import io.github.dfa1.vortex.reader.ReadRegistry; +import io.github.dfa1.vortex.reader.array.Array; +import io.github.dfa1.vortex.reader.array.IntArray; +import io.github.dfa1.zstd.ZstdCompressContext; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import java.lang.foreign.Arena; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.ValueLayout; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +/// The interop test reads a Rust-written file; these pin the metadata/children contract of Rust's +/// `ZstdBuffers::deserialize` and every malformed shape, which a real file never exercises. +class ZstdBuffersEncodingDecoderTest { + + private static final ZstdBuffersEncodingDecoder SUT = new ZstdBuffersEncodingDecoder(); + private static final ReadRegistry REGISTRY = TestRegistry.ofDecoders(SUT, new PrimitiveEncodingDecoder()); + private static final byte[] VALUES = TestSegments.leInts(7, -1, 42).toArray(ValueLayout.JAVA_BYTE); + + @Test + void wrappedPrimitive_decodesToTheInnerArray() { + // Given + ArrayNode node = zstdBuffers(meta("vortex.primitive", VALUES.length, 4), 0); + + // When + Array result = SUT.decode(ctx(node, compress(VALUES))); + + // Then + IntArray ints = (IntArray) result; + assertThat(ints.getInt(0)).isEqualTo(7); + assertThat(ints.getInt(1)).isEqualTo(-1); + assertThat(ints.getInt(2)).isEqualTo(42); + } + + @Test + void nestedZstdBuffers_unwrapsEveryLevel() { + // Given — the inner array is itself zstd_buffers over a primitive: the outer buffer + // decompresses to the inner level's compressed buffer, nested through metadata alone + byte[] innerFrame = compress(VALUES); + ProtoZstdBuffersMetadata innerMeta = new ProtoZstdBuffersMetadata("vortex.primitive", new byte[0], + List.of((long) VALUES.length), List.of(4), List.of(), List.of()); + ProtoZstdBuffersMetadata outerMeta = new ProtoZstdBuffersMetadata("vortex.zstd_buffers", innerMeta.encode(), + List.of((long) innerFrame.length), List.of(1), List.of(), List.of()); + ArrayNode node = zstdBuffers(MemorySegment.ofArray(outerMeta.encode()), 0); + + // When + Array result = SUT.decode(ctx(node, compress(innerFrame))); + + // Then + assertThat(((IntArray) result).getInt(2)).isEqualTo(42); + } + + @Test + void decompressedBuffer_honorsTheDeclaredAlignment() { + // Given — Rust holds a buffer to its declared alignment; 64 is above anything the arena + // would give by default + ArrayNode node = zstdBuffers(meta("vortex.primitive", VALUES.length, 64), 0); + + // When + Array result = SUT.decode(ctx(node, compress(VALUES))); + + // Then + assertThat(result.segmentIfPresent()).hasValueSatisfying(seg -> assertThat(seg.address() % 64).isZero()); + } + + @Nested + class Malformed { + + @Test + void missingMetadata_throws() { + // Given + ArrayNode node = zstdBuffers(null, 0); + + // When / Then + assertThatThrownBy(() -> SUT.decode(ctx(node, compress(VALUES)))) + .isInstanceOf(VortexException.class) + .hasMessageContaining("missing metadata"); + } + + @Test + void sizeCountDisagreesWithBuffers_throws() { + // Given — one compressed buffer, no declared sizes + ProtoZstdBuffersMetadata meta = new ProtoZstdBuffersMetadata("vortex.primitive", new byte[0], + List.of(), List.of(), List.of(), List.of()); + ArrayNode node = zstdBuffers(MemorySegment.ofArray(meta.encode()), 0); + + // When / Then + assertThatThrownBy(() -> SUT.decode(ctx(node, compress(VALUES)))) + .isInstanceOf(VortexException.class) + .hasMessageContaining("1 compressed buffers but 0 sizes"); + } + + @Test + void childCountDisagreesWithMetadata_throws() { + // Given — a child the metadata does not describe + ArrayNode child = new ArrayNode(EncodingId.VORTEX_PRIMITIVE, null, new ArrayNode[0], new int[]{0}); + ArrayNode node = new ArrayNode(EncodingId.VORTEX_ZSTD_BUFFERS, meta("vortex.primitive", VALUES.length, 4), + new ArrayNode[]{child}, new int[]{0}); + + // When / Then + assertThatThrownBy(() -> SUT.decode(ctx(node, compress(VALUES)))) + .isInstanceOf(VortexException.class) + .hasMessageContaining("1 children but 0 child dtypes"); + } + + @Test + void blankInnerEncodingId_throws() { + // Given + ArrayNode node = zstdBuffers(meta(" ", VALUES.length, 4), 0); + + // When / Then + assertThatThrownBy(() -> SUT.decode(ctx(node, compress(VALUES)))) + .isInstanceOf(VortexException.class) + .hasMessageContaining("missing inner encoding id"); + } + + @ParameterizedTest + @ValueSource(ints = {0, 3, 1 << 17, -1}) + void invalidAlignment_throws(int alignment) { + // Given — zero, not a power of two, above the cap, and a u32 that reads as negative + ArrayNode node = zstdBuffers(meta("vortex.primitive", VALUES.length, alignment), 0); + + // When / Then + assertThatThrownBy(() -> SUT.decode(ctx(node, compress(VALUES)))) + .isInstanceOf(VortexException.class) + .hasMessageContaining("buffer alignment must be a power of two"); + } + + @Test + void corruptFrame_throwsVortexException() { + // Given — not a Zstd frame: the binding's own ZstdException must not escape + ArrayNode node = zstdBuffers(meta("vortex.primitive", VALUES.length, 4), 0); + + // When / Then + assertThatThrownBy(() -> SUT.decode(ctx(node, new byte[]{1, 2, 3, 4, 5, 6, 7, 8}))) + .isInstanceOf(VortexException.class) + .hasMessageContaining("frame 0"); + } + + @Test + void declaredSizeLargerThanFrame_throws() { + // Given — metadata promises more bytes than the frame decompresses to + ArrayNode node = zstdBuffers(meta("vortex.primitive", VALUES.length + 4, 4), 0); + + // When / Then + assertThatThrownBy(() -> SUT.decode(ctx(node, compress(VALUES)))) + .isInstanceOf(VortexException.class) + .hasMessageContaining("frame 0"); + } + } + + private static DecodeContext ctx(ArrayNode node, byte[] frame) { + return new DecodeContext(node, DType.I32, 3, new MemorySegment[]{MemorySegment.ofArray(frame)}, + REGISTRY, Arena.ofAuto()); + } + + private static MemorySegment meta(String innerId, long uncompressedSize, int alignment) { + return MemorySegment.ofArray(new ProtoZstdBuffersMetadata(innerId, new byte[0], + List.of(uncompressedSize), List.of(alignment), List.of(), List.of()).encode()); + } + + private static ArrayNode zstdBuffers(MemorySegment meta, int bufferSegment) { + return new ArrayNode(EncodingId.VORTEX_ZSTD_BUFFERS, meta, new ArrayNode[0], new int[]{bufferSegment}); + } + + private static byte[] compress(byte[] raw) { + try (ZstdCompressContext cctx = new ZstdCompressContext()) { + return cctx.compress(raw); + } + } +} diff --git a/scripts/fixtures/zstd-buffers/Cargo.lock b/scripts/fixtures/zstd-buffers/Cargo.lock new file mode 100644 index 00000000..b272ce4c --- /dev/null +++ b/scripts/fixtures/zstd-buffers/Cargo.lock @@ -0,0 +1,3422 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "ahash" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +dependencies = [ + "cfg-if", + "const-random", + "getrandom 0.3.4", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c982642fa9e8606056828ee9a8505737230110bb1099153c79efe865c59d12ba" +dependencies = [ + "memchr", +] + +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + +[[package]] +name = "alp" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b23203d5e87df8d8393c8021b53f9193b697ba13fc4ef653911dc1235e87bfd7" +dependencies = [ + "fastlanes 0.6.1", + "itertools 0.15.0", + "num-traits", +] + +[[package]] +name = "android_system_properties" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae221649c9976a6f6c56ae1facf410f3ddb33cc661c4b7b61020a912d4237fbc" +dependencies = [ + "libc", +] + +[[package]] +name = "anyhow" +version = "1.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" + +[[package]] +name = "arc-swap" +version = "1.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c049c0be4daef0b145cb3555416b3b8ef5b7888a38aea1a3a155801fe7b0810b" +dependencies = [ + "rustversion", +] + +[[package]] +name = "arcref" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28f6098a1e8ab66ff91324cce8fea6643101882cf7d09c85acdb1485ecf61e29" + +[[package]] +name = "arrow" +version = "59.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c14b3d39f306bc28fd639d59f06e17a0f377d0021e1b7e9054e4d6fedc98774" +dependencies = [ + "arrow-arith", + "arrow-array", + "arrow-buffer", + "arrow-cast", + "arrow-data", + "arrow-ord", + "arrow-row", + "arrow-schema", + "arrow-select", + "arrow-string", +] + +[[package]] +name = "arrow-arith" +version = "59.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce2961626677665b2195eb59242af4c7befe7b8737ca2050295389362380104e" +dependencies = [ + "arrow-array", + "arrow-buffer", + "arrow-data", + "arrow-schema", + "chrono", + "num-traits", +] + +[[package]] +name = "arrow-array" +version = "59.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e5f6adeffdf587d7a31db5d2266189624b526730cd3627f9ff9fedae97ad584" +dependencies = [ + "ahash", + "arrow-buffer", + "arrow-data", + "arrow-schema", + "chrono", + "half", + "hashbrown 0.17.1", + "libc", + "num-complex", + "num-integer", + "num-traits", +] + +[[package]] +name = "arrow-buffer" +version = "59.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "097d193003ce7995d5d087089069ec2a6e0187faf5a6f8c9f38af2645d987182" +dependencies = [ + "bytes", + "half", + "num-bigint", + "num-traits", +] + +[[package]] +name = "arrow-cast" +version = "59.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "635c9c635668ad26adf76cce8fb276c4be7cf06e63bd516de7da514f9680ee53" +dependencies = [ + "arrow-array", + "arrow-buffer", + "arrow-data", + "arrow-ord", + "arrow-schema", + "arrow-select", + "atoi", + "base64", + "chrono", + "half", + "lexical-core", + "num-traits", + "ryu", +] + +[[package]] +name = "arrow-data" +version = "59.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ba2f832eaeca24b8f26143dba750e42ee4ab51cf7d65e701ca9607cfda9f358" +dependencies = [ + "arrow-buffer", + "arrow-schema", + "half", + "num-integer", + "num-traits", +] + +[[package]] +name = "arrow-ord" +version = "59.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c900759f3bd8354fd4196bc4403eee846894dc2adf66b4225472006a0bf18c5" +dependencies = [ + "arrow-array", + "arrow-buffer", + "arrow-data", + "arrow-schema", + "arrow-select", +] + +[[package]] +name = "arrow-row" +version = "59.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c6425032e28266e3fc4ff680805e57e670d6ea92473043f3e65b7ed6ac79f2" +dependencies = [ + "arrow-array", + "arrow-buffer", + "arrow-data", + "arrow-schema", + "half", +] + +[[package]] +name = "arrow-schema" +version = "59.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10fab8d4563491417ba801fab29d205104d20d4bdf37bda6cd1cf425cff598cd" +dependencies = [ + "bitflags 2.13.2", + "serde_core", + "serde_json", +] + +[[package]] +name = "arrow-select" +version = "59.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc58569193c2525915f3cc6310edba3792f1200f65d6e9ed330aa33e691493b8" +dependencies = [ + "ahash", + "arrow-array", + "arrow-buffer", + "arrow-data", + "arrow-schema", + "num-traits", +] + +[[package]] +name = "arrow-string" +version = "59.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e0813f3c35c1cfea65e14c20a953440f7783c088b7ad2d0db162ccdeefcec14" +dependencies = [ + "arrow-array", + "arrow-buffer", + "arrow-data", + "arrow-schema", + "arrow-select", + "memchr", + "num-traits", + "regex", + "regex-syntax", +] + +[[package]] +name = "async-channel" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2" +dependencies = [ + "concurrent-queue", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-executor" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c96bf972d85afc50bf5ab8fe2d54d1586b4e0b46c97c50a0c9e71e2f7bcd812a" +dependencies = [ + "async-task", + "concurrent-queue", + "fastrand", + "futures-lite", + "pin-project-lite", + "slab", +] + +[[package]] +name = "async-fs" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8034a681df4aed8b8edbd7fbe472401ecf009251c8b40556b304567052e294c5" +dependencies = [ + "async-lock", + "blocking", + "futures-lite", +] + +[[package]] +name = "async-io" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "456b8a8feb6f42d237746d4b3e9a178494627745c3c56c6ea55d92ba50d026fc" +dependencies = [ + "autocfg", + "cfg-if", + "concurrent-queue", + "futures-io", + "futures-lite", + "parking", + "polling", + "rustix", + "slab", + "windows-sys", +] + +[[package]] +name = "async-lock" +version = "3.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311" +dependencies = [ + "event-listener", + "event-listener-strategy", + "pin-project-lite", +] + +[[package]] +name = "async-net" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b948000fad4873c1c9339d60f2623323a0cfd3816e5181033c6a5cb68b2accf7" +dependencies = [ + "async-io", + "blocking", + "futures-lite", +] + +[[package]] +name = "async-process" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc50921ec0055cdd8a16de48773bfeec5c972598674347252c0399676be7da75" +dependencies = [ + "async-channel", + "async-io", + "async-lock", + "async-signal", + "async-task", + "blocking", + "cfg-if", + "event-listener", + "futures-lite", + "rustix", +] + +[[package]] +name = "async-signal" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52b5aaafa020cf5053a01f2a60e8ff5dccf550f0f77ec54a4e47285ac2bab485" +dependencies = [ + "async-io", + "async-lock", + "atomic-waker", + "cfg-if", + "futures-core", + "futures-io", + "rustix", + "signal-hook-registry", + "slab", + "windows-sys", +] + +[[package]] +name = "async-stream" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "async-task" +version = "4.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" + +[[package]] +name = "async-trait" +version = "0.1.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82f6aeea286b8eb4dd3431a1be1b59d290ace00f5bfd8e2a159bc2a05e2c1667" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.6", +] + +[[package]] +name = "atoi" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" +dependencies = [ + "num-traits", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "autocfg" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" + +[[package]] +name = "base64" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac07cdecf99051d9a5238b80f35af32cdeba5b336e55d957b318b50137e18da5" + +[[package]] +name = "better_io" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef0a3155e943e341e557863e69a708999c94ede624e37865c8e2a91b94efa78f" + +[[package]] +name = "bindgen" +version = "0.72.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" +dependencies = [ + "bitflags 2.13.2", + "cexpr", + "clang-sys", + "itertools 0.13.0", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex 1.3.0", + "syn 2.0.119", +] + +[[package]] +name = "bit-vec" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b71798fca2c1fe1086445a7258a4bc81e6e49dcd24c8d0dd9a1e57395b603f51" +dependencies = [ + "serde", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ded4057c258ba199e2d26386d3af3780957ecaee6c4ef4041c6b4b8b97c0b06" + +[[package]] +name = "bitvec" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddcec3d12c579d40898fe0a9a358a803c23e9c52ca3c425707f81c9436211837" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "blocking" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a70e4329df6cb94385eed412ec92375c3cdd8a6e502493d1229b6414e4036dfa" +dependencies = [ + "async-channel", + "async-task", + "futures-io", + "futures-lite", + "piper", +] + +[[package]] +name = "bumpalo" +version = "3.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" + +[[package]] +name = "bytemuck" +version = "1.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95832e849adfb21180ccb6826a99da14e5d266ae5c2e668e1602cf234f153797" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" + +[[package]] +name = "cc" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f74872d07caf508b30a21f6836e7d7016a2eaf7d9ff4f48deaa58cd8a0407630" +dependencies = [ + "find-msvc-tools", + "jobserver", + "libc", + "shlex 2.0.1", +] + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7648175b45a9a48536d676f68d918270699102aa8dab5496df06904c914600" + +[[package]] +name = "chacha20" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65c35e4b699c7e15ccbe7ee35c005e4fc0a278d22238a2857e6ce2dadeda1b06" +dependencies = [ + "cfg-if", + "cpufeatures", + "rand_core 0.10.1", +] + +[[package]] +name = "chrono" +version = "0.4.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" +dependencies = [ + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-link", +] + +[[package]] +name = "clang-sys" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "157a8ba7b480713b56f4c09fd13fc3e0a22a5dfab8097ba61cbc5feef950788a" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "const-random" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359" +dependencies = [ + "const-random-macro", +] + +[[package]] +name = "const-random-macro" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" +dependencies = [ + "getrandom 0.2.17", + "once_cell", + "tiny-keccak", +] + +[[package]] +name = "const_for" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "988d3bd6bf67b6d7ae2b519c55296fa57411c27c312575e47b2975f8d1d8590b" + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "cpufeatures" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca28b0ae3115b884660db4118d803791fd6756b6e88f39c0f3f7859060d7566" +dependencies = [ + "libc", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98b0cc327b5bc766e7fda9c9260cc0fa81b43a8e240440422dff70788e3f9ef1" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc74980687109a3b14c72fd458107bf0baa1da1a1a805e178d15501ba9b86d9d" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31eee39dddec8330830986fcd7625edb5a24ec90ea038215273bbc3adb08ac6" + +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + +[[package]] +name = "custom-labels" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4121f4f539659ad975da5bc6702b7d7d6de59ff1bbaec328dfe7dd5058052ef2" +dependencies = [ + "bindgen", + "cc", + "libc", + "pin-project-lite", +] + +[[package]] +name = "dashmap" +version = "6.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6361d5c062261c78a176addb82d4c821ae42bed6089de0e12603cd25de2059c" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core", +] + +[[package]] +name = "defmt" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2953bfe4f93bbd20cc71198842756f77d161884c99ebbabc41d80231ded88d1" +dependencies = [ + "bitflags 1.3.2", + "defmt-macros", +] + +[[package]] +name = "defmt-macros" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bad9c72e7ca2137e0dc3813245a0d282fd6daad32fd800af018306a9169b5fe8" +dependencies = [ + "defmt-parser", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "defmt-parser" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e" +dependencies = [ + "thiserror", +] + +[[package]] +name = "displaydoc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6232dd377dcc64799954cbd3a9bb882e9cdc1308ccd87b1c098f1fb2eaf82a8" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.6", +] + +[[package]] +name = "dtype_dispatch" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab23e69df104e2fd85ee63a533a22d2132ef5975dc6b36f9f3e5a7305e4a8ed7" + +[[package]] +name = "either" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "252afb9ae5eaa683babdc6a068b3f5726eb19e05070c731f9b2a23a7c3e8ed34" + +[[package]] +name = "enum-iterator" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4549325971814bda7a44061bf3fe7e487d447cba01e4220a4b454d630d7a016" +dependencies = [ + "enum-iterator-derive", +] + +[[package]] +name = "enum-iterator-derive" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "685adfa4d6f3d765a26bc5dbc936577de9abf756c1feeb3089b01dd395034842" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "event-listener" +version = "5.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a23add41df1562121a9393cb065eab5146a1242410f23a644851e90cfd669d2" +dependencies = [ + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" +dependencies = [ + "event-listener", + "pin-project-lite", +] + +[[package]] +name = "ext-trait" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d772df1c1a777963712fb68e014235e80863d6a91a85c4e06ba2d16243a310e5" +dependencies = [ + "ext-trait-proc_macros", +] + +[[package]] +name = "ext-trait-proc_macros" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ab7934152eaf26aa5aa9f7371408ad5af4c31357073c9e84c3b9d7f11ad639a" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "extension-traits" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a296e5a895621edf9fa8329c83aa1cb69a964643e36cf54d8d7a69b789089537" +dependencies = [ + "ext-trait", +] + +[[package]] +name = "fastlanes" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a516528425408429de7661e7101f7e7ad54f7d3fab859a3a6de239f508d17e2" +dependencies = [ + "const_for", + "num-traits", + "pastey", + "seq-macro", +] + +[[package]] +name = "fastlanes" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fcb34a73abd2872401096bf65d13e8d26e0c9ca6166d5e2b11a314ba017cdef" +dependencies = [ + "const_for", + "num-traits", + "pastey", + "seq-macro", +] + +[[package]] +name = "fastrand" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223" + +[[package]] +name = "find-msvc-tools" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aedcfb3409746eddb02b9e19ebda1c3394f759a152e48ee875a0844d1b955484" + +[[package]] +name = "flatbuffers" +version = "25.12.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35f6839d7b3b98adde531effaf34f0c2badc6f4735d26fe74709d8e513a96ef3" +dependencies = [ + "bitflags 2.13.2", + "rustc_version", +] + +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + +[[package]] +name = "form_urlencoded" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "fsst-rs" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03b614a2a7f2efc50d76c1e47d64b57c55acf6e0e718b0cae78236d147c487d0" +dependencies = [ + "rustc-hash", +] + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "futures" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a31d2a3fbaaeb2af2368bbdd904aa8e812d3c04a1ee10d3171f52d556e5d0a3" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" + +[[package]] +name = "futures-executor" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "031b47cf1a3c6cc8bc2fc76cd437f521619387907d469316e7c0bc278f1f5432" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed" + +[[package]] +name = "futures-lite" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "parking", + "pin-project-lite", +] + +[[package]] +name = "futures-macro" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb9654ba8355388abeb8dcb4fc62f511300867002afc858860463bdd9fe0c44" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.6", +] + +[[package]] +name = "futures-sink" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1944426bf7d03f1d14f708785e4b33efd750b36d48a157b836b3efc15ede8e1d" + +[[package]] +name = "futures-task" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" + +[[package]] +name = "futures-util" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "slab", +] + +[[package]] +name = "getrandom" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "libc", + "r-efi 5.3.0", + "wasip2", +] + +[[package]] +name = "getrandom" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" +dependencies = [ + "cfg-if", + "libc", + "r-efi 6.0.0", + "rand_core 0.10.1", +] + +[[package]] +name = "glob" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4eba85ea1d0a966a983acd07deee566e67395d2d96b6fb39e62b5a833f1eb0b" + +[[package]] +name = "half" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" +dependencies = [ + "cfg-if", + "crunchy", + "num-traits", + "zerocopy", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", + "allocator-api2", +] + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] + +[[package]] +name = "hermit-abi" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e17592d60ebacc7d5e169f4663c5f84f9161cc90328abcfe8456f41e4dfcb284" + +[[package]] +name = "humansize" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6cb51c9a029ddc91b07a787f1d86b53ccfa49b0e86688c946ebe8d3555685dd7" +dependencies = [ + "libm", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "icu_collections" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa68d21081c4a05d5a901a1c62add574c77048b6a1c67be3b50ce0b60d4ca513" +dependencies = [ + "displaydoc", + "potential_utf", + "utf8_iter", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d56e28588da92eee5c3201a6eff33fabdd49b62269c8938d4ff050ce4d900deb" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12f9cf5f235641ed274641dd81c3f28d870e276763d0797aeeab72317b1c646f" +dependencies = [ + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1563da1ed3e0b3bf3d74c9b85917ac9c56464d2f57242270c09c9e752f8021a0" + +[[package]] +name = "icu_properties" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e7ca276ad3145661a65914e6daf131ca5120cd3dcee8f8f3214b8875184a148" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e590f038c1464a96894fd6d10127e90a8be4509f56ff7ecef851b15cee0b7caa" + +[[package]] +name = "icu_provider" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d27bbb9d3abbefac45d55f647c9de1d44aafcd1186eb91879afef17c396c3e73" +dependencies = [ + "displaydoc", + "icu_locale_core", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "idna" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "indexmap" +version = "2.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855" +dependencies = [ + "equivalent", + "hashbrown 0.17.1", +] + +[[package]] +name = "inventory" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4f0c30c76f2f4ccee3fe55a2435f691ca00c0e4bd87abe4f4a851b1d4dac39b" +dependencies = [ + "rustversion", +] + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b4baf93f58d4425749ca49a51c50ebab072c5df6994d08fed93541c331481dc" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "jiff" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ab1baf72f08796de0260609515130699b890ac25f30e610ad894bc5856cafdb" +dependencies = [ + "defmt", + "jiff-core", + "jiff-static", + "jiff-tzdb-platform", + "log", + "portable-atomic", + "portable-atomic-util", + "serde_core", + "windows-link", +] + +[[package]] +name = "jiff-core" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e52fe76043ccecc9005d2305ebaadf7d7fc0cc89ca6baa10a94d6bc68c7128c" +dependencies = [ + "defmt", + "log", +] + +[[package]] +name = "jiff-static" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "378268a1116ad67ae6228701118ac9f491d78fda38a40a1f1a9e1348de6f7212" +dependencies = [ + "jiff-core", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "jiff-tzdb" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "142bd39932ad231f10513df9ab62661fead8719872150b7ad02a2df79f4e141e" + +[[package]] +name = "jiff-tzdb-platform" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "875a5a69ac2bab1a891711cf5eccbec1ce0341ea805560dcd90b7a2e925132e8" +dependencies = [ + "jiff-tzdb", +] + +[[package]] +name = "jobserver" +version = "0.1.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c00acbd29eabad4a2392fa0e921c874934dbbf4194312ad20f04a0ed67a3cb3" +dependencies = [ + "getrandom 0.4.3", + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7883d941dae510fb2d978fc3fe018c71c9e2892fd38854de3e8b92c2e5ad9cc5" +dependencies = [ + "cfg-if", + "futures-util", + "wasm-bindgen", +] + +[[package]] +name = "kanal" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e3953adf0cd667798b396c2fa13552d6d9b3269d7dd1154c4c416442d1ff574" +dependencies = [ + "futures-core", + "lock_api", +] + +[[package]] +name = "lasso" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e14eda50a3494b3bf7b9ce51c52434a761e383d7238ce1dd5dcec2fbc13e9fb" +dependencies = [ + "dashmap", + "hashbrown 0.14.5", +] + +[[package]] +name = "lending-iterator" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc07588c853b50689205fb5c00498aa681d89828e0ce8cbd965ebc7a5d8ae260" +dependencies = [ + "extension-traits", + "lending-iterator-proc_macros", + "macro_rules_attribute", + "never-say-never", + "nougat", + "polonius-the-crab", +] + +[[package]] +name = "lending-iterator-proc_macros" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5445dd1c0deb1e97b8a16561d17fc686ca83e8411128fb036e9668a72d51b1d" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "lexical-core" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d8d125a277f807e55a77304455eb7b1cb52f2b18c143b60e766c120bd64a594" +dependencies = [ + "lexical-parse-float", + "lexical-parse-integer", + "lexical-util", + "lexical-write-float", + "lexical-write-integer", +] + +[[package]] +name = "lexical-parse-float" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52a9f232fbd6f550bc0137dcb5f99ab674071ac2d690ac69704593cb4abbea56" +dependencies = [ + "lexical-parse-integer", + "lexical-util", +] + +[[package]] +name = "lexical-parse-integer" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a7a039f8fb9c19c996cd7b2fcce303c1b2874fe1aca544edc85c4a5f8489b34" +dependencies = [ + "lexical-util", +] + +[[package]] +name = "lexical-util" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2604dd126bb14f13fb5d1bd6a66155079cb9fa655b37f875b3a742c705dbed17" + +[[package]] +name = "lexical-write-float" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50c438c87c013188d415fbabbb1dceb44249ab81664efbd31b14ae55dabb6361" +dependencies = [ + "lexical-util", + "lexical-write-integer", +] + +[[package]] +name = "lexical-write-integer" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "409851a618475d2d5796377cad353802345cba92c867d9fbcde9cf4eac4e14df" +dependencies = [ + "lexical-util", +] + +[[package]] +name = "libc" +version = "0.2.190" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce5d3ddc6d3fa000eb1536d85e147bfe31aacaba692ed6a876f95cb7c855be78" + +[[package]] +name = "libloading" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" +dependencies = [ + "cfg-if", + "windows-link", +] + +[[package]] +name = "libm" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" + +[[package]] +name = "linux-raw-sys" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" + +[[package]] +name = "litemap" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d9d19d1d6efa0109d2f65ff4c85cddd50bd572e5a00127ab10987290bcefae" + +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6" + +[[package]] +name = "macro_rules_attribute" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf0c9b980bf4f3a37fd7b1c066941dd1b1d0152ce6ee6e8fe8c49b9f6810d862" +dependencies = [ + "macro_rules_attribute-proc_macro", + "paste", +] + +[[package]] +name = "macro_rules_attribute-proc_macro" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58093314a45e00c77d5c508f76e77c3396afbbc0d01506e7fae47b018bac2b1d" + +[[package]] +name = "memchr" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "mio" +version = "1.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1788edb87fdc09c7e26304471e2f5be8cdefb1b6930d6e3985fc02ff53bf86ee" +dependencies = [ + "libc", + "wasi", + "windows-sys", +] + +[[package]] +name = "moka" +version = "0.12.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4293f18e7567a1caf3c584855554377025c65e0aa445344d04171f5ad63d19b9" +dependencies = [ + "async-lock", + "crossbeam-channel", + "crossbeam-epoch", + "crossbeam-utils", + "equivalent", + "event-listener", + "futures-util", + "parking_lot", + "portable-atomic", + "smallvec", + "tagptr", + "uuid", +] + +[[package]] +name = "never-say-never" +version = "6.6.666" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf5a574dadd7941adeaa71823ecba5e28331b8313fb2e1c6a5c7e5981ea53ad6" + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "nougat" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97b57b9ced431322f054fc673f1d3c7fa52d80efd9df74ad2fc759f044742510" +dependencies = [ + "macro_rules_attribute", + "nougat-proc_macros", +] + +[[package]] +name = "nougat-proc_macros" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c84f77a45e99a2f9b492695d99e1c23844619caa5f3e57647cffacad773ca257" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "num-bigint" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93e7820bc0a80a0238e650327316f929ba18d5be054b647490a3a6a339f3e7c0" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ce2d95d4b3734dc35aa2f45e1aa22cd416814592a4f9d9205e11affd5b8e10b" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_enum" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0bca838442ec211fa11de3a8b0e0e8f3a4522575b5c4c06ed722e005036f26" +dependencies = [ + "num_enum_derive", + "rustversion", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "680998035259dcfcafe653688bf2aa6d3e2dc05e98be6ab46afb089dc84f1df8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" +dependencies = [ + "parking_lot_core", +] + +[[package]] +name = "onpair" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34272d1ea63266148a9a5b2b96db80a45245d034862302735f2f93413a6f9172" +dependencies = [ + "hashbrown 0.16.1", + "rand 0.9.5", +] + +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + +[[package]] +name = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-link", +] + +[[package]] +name = "parquet-variant" +version = "59.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3950502c5d383bc98ac83424c50ad06214cfb8a8554ef6f19413e71894079288" +dependencies = [ + "arrow", + "arrow-schema", + "chrono", + "half", + "indexmap", + "num-traits", + "simdutf8", + "uuid", +] + +[[package]] +name = "parquet-variant-compute" +version = "59.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28c4fc004d60a76d727fe4a383b48e8c4d629384b9d9f0cc359164ec2cbd3326" +dependencies = [ + "arrow", + "arrow-schema", + "chrono", + "half", + "indexmap", + "parquet-variant", + "parquet-variant-json", + "serde_json", + "uuid", +] + +[[package]] +name = "parquet-variant-json" +version = "59.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "216b1aecab3ee2e8f429ade4dfef24e233d008ee91ce745fb273c39fc5936b85" +dependencies = [ + "arrow-schema", + "base64", + "chrono", + "parquet-variant", + "serde_json", + "uuid", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pastey" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ee67f1008b1ba2321834326597b8e186293b049a023cdef258527550b9935b4" + +[[package]] +name = "pco" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "386342cad4c6e97f081568e5d910ea7d871314c843aa8fc564f2a6b64cab9456" +dependencies = [ + "better_io", + "dtype_dispatch", + "half", + "rand_xoshiro", +] + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "piper" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c835479a4443ded371d6c535cbfd8d31ad92c5d23ae9770a61bc155e4992a3c1" +dependencies = [ + "atomic-waker", + "fastrand", + "futures-io", +] + +[[package]] +name = "pkg-config" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6b464fbc74e149a392436b17d523f769e057cb6877f6a5c4618bc6f11800548" + +[[package]] +name = "polling" +version = "3.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218" +dependencies = [ + "cfg-if", + "concurrent-queue", + "hermit-abi", + "pin-project-lite", + "rustix", + "windows-sys", +] + +[[package]] +name = "polonius-the-crab" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a69ee997a6282f8462abf1e0d8c38c965e968799e912b3bed8c9e8a28c2f9f" + +[[package]] +name = "portable-atomic" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85" + +[[package]] +name = "portable-atomic-util" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10ab3eb7f3becc3a1cbc4f2c6f20267996cfc1a6467a873763411b136a122715" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "potential_utf" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d83eb9bc6d8e5cf568e7a1101d60ee05e81ed50ea106026f3d18deeb046d7661" +dependencies = [ + "zerovec", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro2" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prost" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "528ac67416ff8646872a3c02cad9cc4ee5dc9f9540c9b10771855c95cb2e5ae1" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-derive" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b570b25f7617e43d59005d0990ccb79e950a423952cea19671b7a876da390adf" +dependencies = [ + "anyhow", + "itertools 0.14.0", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "prost-types" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f94967dc7688f3054c7fac87473ffae4cc4c3904800e2d9f5b857246d8963b0a" +dependencies = [ + "prost", +] + +[[package]] +name = "quote" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9ef1d0d795eb7d84685bca4f72f3649f064e6641543d3a8c415898726a57b41" +dependencies = [ + "rand_chacha", + "rand_core 0.9.5", +] + +[[package]] +name = "rand" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65c9fb96cbc91e3478eaae79a69fcd3f1ae4ad052e471fe6732fff548984b4af" +dependencies = [ + "chacha20", + "getrandom 0.4.3", + "rand_core 0.10.1", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.5", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" + +[[package]] +name = "rand_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +dependencies = [ + "getrandom 0.3.4", +] + +[[package]] +name = "rand_core" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" + +[[package]] +name = "rand_xoshiro" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa" +dependencies = [ + "rand_core 0.6.4", +] + +[[package]] +name = "redox_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags 2.13.2", +] + +[[package]] +name = "regex" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad8553b9b26413251cbf30e620595c7a41b3887f03da04579c0e6b0d6a06b4b2" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" + +[[package]] +name = "roaring" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18bd8a37d17a58532776dcdf6041ce64929adca78e8489d5cacbafe99229d3e1" +dependencies = [ + "bytemuck", + "byteorder", +] + +[[package]] +name = "rustc-hash" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891efababe418670775f199f0d233d84843c227a0949a883ce15b37c78d6629d" +dependencies = [ + "bitflags 2.13.2", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "rustversion" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" + +[[package]] +name = "ryu" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" + +[[package]] +name = "seq-macro" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc711410fbe7399f390ca1c3b60ad0f53f80e95c5eb935e52268a0e2cd49acc" + +[[package]] +name = "serde" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.6", +] + +[[package]] +name = "serde_json" +version = "1.0.151" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" + +[[package]] +name = "signal-hook-registry" +version = "1.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +dependencies = [ + "errno", + "libc", +] + +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + +[[package]] +name = "sketches-ddsketch" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "513c3f5f732bfd6fbb187619c2dfe9d2f25f1a2976f01d575f0fd329d565df56" + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smallvec" +version = "1.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9395f0f0eee849a9b707b2f06bb92a6a422090e2123bb2ef8e87a0e61892a8e" + +[[package]] +name = "smol" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a33bd3e260892199c3ccfc487c88b2da2265080acb316cd920da72fdfd7c599f" +dependencies = [ + "async-channel", + "async-executor", + "async-fs", + "async-io", + "async-lock", + "async-net", + "async-process", + "blocking", + "futures-lite", +] + +[[package]] +name = "socket2" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.119" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "3.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8593e8e72159ed2257d083c7a454a85cbf854f37a0966d8d483aff8c8a3ebcee" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "synstructure" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "901704edd0dfe137f1987838ee4f259e4e063c31371bdb423f7ae38ec6f77f02" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.6", +] + +[[package]] +name = "tagptr" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "termtree" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4d1330fe7f7f872cd05165130b10602d667b205fd85be09be2814b115d4ced9" + +[[package]] +name = "thiserror" +version = "2.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09e52cb86a36cede5cb101bf8908837b3e4c6e5e59fe7fd85c23fb56200d189e" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe5197923287db20a58125f0bc85c062f7f2c892de97b18c356f9efb14b28524" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.6", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "tinystr" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1e27c91459209c2986af3dcf603a5a74a4368754ce37414f59acc971167f643" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tokio" +version = "1.53.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e95f91fcc7a621e8b030f6aa23c71fe9838ae2fb4d8118b75602a328f5144044" +dependencies = [ + "bytes", + "libc", + "mio", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys", +] + +[[package]] +name = "tokio-macros" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78773a2a397f451582ce068015985c33193cf6dea8b74d2a639fe457b2f07b0e" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.6", +] + +[[package]] +name = "tracing" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "tracing-core" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +dependencies = [ + "once_cell", +] + +[[package]] +name = "twox-hash" +version = "2.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5283634e518fe9e82c7b20520bb4bc209009fd16c82077c802f8111ecbb0117a" +dependencies = [ + "rand 0.10.3", +] + +[[package]] +name = "unicode-ident" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d245f478577f809a851594d02313b640fb437e0bb33866753cff937863096954" + +[[package]] +name = "url" +version = "2.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "uuid" +version = "1.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97277d36b9c3ace13e58fa6e753f8b0bbbf302a18dd193240d70f9e29681059a" +dependencies = [ + "getrandom 0.4.3", + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "vortex" +version = "0.86.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e6da071d96539f6061b6455379fd9db6535e76027cb473b102a9d45e40526e7" +dependencies = [ + "vortex-alp", + "vortex-array", + "vortex-arrow", + "vortex-btrblocks", + "vortex-buffer", + "vortex-bytebool", + "vortex-datetime-parts", + "vortex-decimal-byte-parts", + "vortex-edition", + "vortex-error", + "vortex-fastlanes", + "vortex-file", + "vortex-flatbuffers", + "vortex-fsst", + "vortex-io", + "vortex-ipc", + "vortex-layout", + "vortex-mask", + "vortex-metrics", + "vortex-parquet-variant", + "vortex-pco", + "vortex-proto", + "vortex-runend", + "vortex-scan", + "vortex-sequence", + "vortex-session", + "vortex-sparse", + "vortex-utils", + "vortex-zigzag", + "vortex-zstd", +] + +[[package]] +name = "vortex-alp" +version = "0.86.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "459bd99fb5f1489003f0e5995df7229f551a7f6ed4a3a3c9887587dc79b933e8" +dependencies = [ + "alp", + "itertools 0.14.0", + "num-traits", + "prost", + "vortex-array", + "vortex-buffer", + "vortex-error", + "vortex-fastlanes", + "vortex-mask", + "vortex-session", +] + +[[package]] +name = "vortex-array" +version = "0.86.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51f9cad02aa398673d382d5d13496c6c46af46f9fc0dff68db11195a5155e3ec" +dependencies = [ + "arc-swap", + "arcref", + "arrow-buffer", + "async-lock", + "bytes", + "cfg-if", + "enum-iterator", + "flatbuffers", + "futures", + "half", + "humansize", + "inventory", + "itertools 0.14.0", + "jiff", + "memchr", + "num-traits", + "num_enum", + "parking_lot", + "paste", + "pin-project-lite", + "prost", + "rand 0.10.3", + "regex", + "regex-syntax", + "rustc-hash", + "simdutf8", + "smallvec", + "static_assertions", + "tracing", + "uuid", + "vortex-array-macros", + "vortex-buffer", + "vortex-compute", + "vortex-error", + "vortex-flatbuffers", + "vortex-mask", + "vortex-proto", + "vortex-session", + "vortex-utils", +] + +[[package]] +name = "vortex-array-macros" +version = "0.86.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a684e4ad14145c3c933caf6fa34af71eaebfd7531542491540772133ca10e6d4" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.6", +] + +[[package]] +name = "vortex-arrow" +version = "0.86.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f72d6dcff160e4fb47cd0a6dcd031be408fa7ff7605ae0cb3d80fa9f2e11d27" +dependencies = [ + "arrow-array", + "arrow-buffer", + "arrow-cast", + "arrow-data", + "arrow-schema", + "arrow-select", + "itertools 0.14.0", + "num-traits", + "simdutf8", + "tracing", + "vortex-array", + "vortex-buffer", + "vortex-error", + "vortex-mask", + "vortex-runend", + "vortex-session", +] + +[[package]] +name = "vortex-btrblocks" +version = "0.86.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bc6df7630ea9f409914c351c04aca9e78122ab0db076fbc54b0dfcaf5b84737" +dependencies = [ + "itertools 0.14.0", + "pco", + "rand 0.10.3", + "vortex-alp", + "vortex-array", + "vortex-buffer", + "vortex-compressor", + "vortex-datetime-parts", + "vortex-decimal-byte-parts", + "vortex-error", + "vortex-fastlanes", + "vortex-fsst", + "vortex-onpair", + "vortex-pco", + "vortex-runend", + "vortex-sequence", + "vortex-sparse", + "vortex-utils", + "vortex-zigzag", + "vortex-zstd", +] + +[[package]] +name = "vortex-buffer" +version = "0.86.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a44f459872c724b453e927497d0e3da2b6902bdb1c41b380344377c9463fd38" +dependencies = [ + "allocator-api2", + "arrow-buffer", + "bitvec", + "bytes", + "itertools 0.14.0", + "simdutf8", + "vortex-error", +] + +[[package]] +name = "vortex-bytebool" +version = "0.86.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6156ce4fe5a5029db324fe812a999db87b88f0e653a11e440a26fc455e633732" +dependencies = [ + "num-traits", + "vortex-array", + "vortex-buffer", + "vortex-error", + "vortex-session", +] + +[[package]] +name = "vortex-compressor" +version = "0.86.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "465f796c789a7b0630130cba602ff2d672cb71883fb2ea061d6271558925c516" +dependencies = [ + "itertools 0.14.0", + "num-traits", + "parking_lot", + "rand 0.10.3", + "rustc-hash", + "tracing", + "vortex-array", + "vortex-buffer", + "vortex-error", + "vortex-mask", + "vortex-utils", +] + +[[package]] +name = "vortex-compute" +version = "0.86.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3f19f5b164afbec399bdf41c9c1b0c90afd8de98baf078a7a5ae2514ac8ba3f" +dependencies = [ + "vortex-buffer", +] + +[[package]] +name = "vortex-datetime-parts" +version = "0.86.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1feecd7ce3b66c03370f7a5450a15c759cd0a823c1fcde577c358287a902041" +dependencies = [ + "num-traits", + "prost", + "vortex-array", + "vortex-buffer", + "vortex-error", + "vortex-mask", + "vortex-session", +] + +[[package]] +name = "vortex-decimal-byte-parts" +version = "0.86.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cdd8ccb809d9bf839c1e3cd1b1adc5fd2a2ed9d3d74bb13764b73a0412fc064" +dependencies = [ + "num-traits", + "prost", + "vortex-array", + "vortex-buffer", + "vortex-error", + "vortex-mask", + "vortex-session", +] + +[[package]] +name = "vortex-edition" +version = "0.86.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b70fecc1d259c29774654ed16d011f36b568504447c2180943185f36141d038" +dependencies = [ + "parking_lot", + "vortex-error", + "vortex-session", +] + +[[package]] +name = "vortex-error" +version = "0.86.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "069ea43932ff10488f55ec10256a75a85e219607fdb29da87b888aa772de001d" +dependencies = [ + "arrow-schema", + "flatbuffers", + "jiff", + "prost", + "tokio", +] + +[[package]] +name = "vortex-fastlanes" +version = "0.86.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd5799e2e14034fa4e174fd935842318d0d858ad328b0dc17291ceb4ae96d2e1" +dependencies = [ + "fastlanes 0.7.2", + "itertools 0.14.0", + "lending-iterator", + "num-traits", + "prost", + "vortex-array", + "vortex-buffer", + "vortex-error", + "vortex-mask", + "vortex-session", +] + +[[package]] +name = "vortex-file" +version = "0.86.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b39794944bd6a9562c2928afd745c3d7f969587c07435bb37d6f37d34140b4a" +dependencies = [ + "async-stream", + "async-trait", + "bytes", + "flatbuffers", + "futures", + "itertools 0.14.0", + "kanal", + "moka", + "parking_lot", + "pin-project-lite", + "tokio", + "tracing", + "url", + "vortex-alp", + "vortex-array", + "vortex-btrblocks", + "vortex-buffer", + "vortex-bytebool", + "vortex-datetime-parts", + "vortex-decimal-byte-parts", + "vortex-edition", + "vortex-error", + "vortex-fastlanes", + "vortex-flatbuffers", + "vortex-fsst", + "vortex-io", + "vortex-layout", + "vortex-mask", + "vortex-metrics", + "vortex-onpair", + "vortex-pco", + "vortex-runend", + "vortex-scan", + "vortex-sequence", + "vortex-session", + "vortex-sparse", + "vortex-utils", + "vortex-zigzag", + "vortex-zstd", +] + +[[package]] +name = "vortex-flatbuffers" +version = "0.86.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d9ad94c8aa7cee143a234ce2c04f896ad6a7d01c615752328ca5305dfd897fc" +dependencies = [ + "flatbuffers", + "vortex-buffer", + "vortex-error", +] + +[[package]] +name = "vortex-fsst" +version = "0.86.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "612d95a0d18cac5e50318afc59bd41a24a384558c847bfda8797eff274b83a7f" +dependencies = [ + "fsst-rs", + "num-traits", + "prost", + "vortex-array", + "vortex-buffer", + "vortex-error", + "vortex-mask", + "vortex-session", +] + +[[package]] +name = "vortex-io" +version = "0.86.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9624f11d3d30e4965909717aec04670fe62106643449855fc8032faa6f1b9fbb" +dependencies = [ + "async-executor", + "async-fs", + "async-stream", + "async-trait", + "bytes", + "crossbeam-channel", + "custom-labels", + "futures", + "glob", + "kanal", + "parking_lot", + "pin-project-lite", + "smol", + "tokio", + "tracing", + "vortex-array", + "vortex-buffer", + "vortex-error", + "vortex-metrics", + "vortex-session", + "vortex-utils", + "wasm-bindgen-futures", +] + +[[package]] +name = "vortex-ipc" +version = "0.86.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a499ec004d6e1b23d52ba3aff0ce843a0689fc3e8eec0d8fc8a552e4de60472d" +dependencies = [ + "bytes", + "flatbuffers", + "futures", + "itertools 0.14.0", + "pin-project-lite", + "vortex-array", + "vortex-buffer", + "vortex-error", + "vortex-flatbuffers", + "vortex-session", +] + +[[package]] +name = "vortex-json" +version = "0.86.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ce0763be583581780f7f2ed8bb799d82b9084618dac19be05e460ca10ceafbb" +dependencies = [ + "arrow-array", + "arrow-schema", + "prost", + "vortex-array", + "vortex-arrow", + "vortex-edition", + "vortex-error", + "vortex-proto", + "vortex-session", +] + +[[package]] +name = "vortex-layout" +version = "0.86.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5877370f62b2fef5a8a6056a71aac81d80a456ca5667e4260182535cdffb6f11" +dependencies = [ + "arcref", + "arrow-array", + "arrow-schema", + "async-stream", + "async-trait", + "bit-vec", + "flatbuffers", + "futures", + "itertools 0.14.0", + "kanal", + "moka", + "once_cell", + "parking_lot", + "paste", + "pin-project-lite", + "prost", + "rustc-hash", + "sketches-ddsketch", + "termtree", + "tokio", + "tracing", + "twox-hash", + "uuid", + "vortex-array", + "vortex-arrow", + "vortex-btrblocks", + "vortex-buffer", + "vortex-error", + "vortex-flatbuffers", + "vortex-io", + "vortex-mask", + "vortex-metrics", + "vortex-runend", + "vortex-scan", + "vortex-sequence", + "vortex-session", + "vortex-utils", +] + +[[package]] +name = "vortex-mask" +version = "0.86.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91352099d66b9292a374eabcaf36ea0edc173305e05d595ceb2676a355054ec9" +dependencies = [ + "itertools 0.14.0", + "vortex-buffer", + "vortex-error", +] + +[[package]] +name = "vortex-metrics" +version = "0.86.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d93c771036f8ae5180288b5f5a190c10f6da913a950a11592af3c8fdfe27c53" +dependencies = [ + "parking_lot", + "sketches-ddsketch", +] + +[[package]] +name = "vortex-onpair" +version = "0.86.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4f3946d4ce6ebe42253a51ce4d65769e3a0243db3419bf44a60b2a9cb74b26c" +dependencies = [ + "num-traits", + "onpair", + "prost", + "vortex-array", + "vortex-buffer", + "vortex-error", + "vortex-mask", + "vortex-session", +] + +[[package]] +name = "vortex-parquet-variant" +version = "0.86.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faff122a19770b2716402c15b233c3696447c179ebf4e93b5449afb9f427db1f" +dependencies = [ + "arrow-array", + "arrow-buffer", + "arrow-schema", + "chrono", + "parquet-variant", + "parquet-variant-compute", + "prost", + "vortex-array", + "vortex-arrow", + "vortex-buffer", + "vortex-error", + "vortex-json", + "vortex-mask", + "vortex-proto", + "vortex-session", +] + +[[package]] +name = "vortex-pco" +version = "0.86.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1113d8543d967d442e5c035392d7c7e65ae5b18267e6fac5f210cc30b7d42fd6" +dependencies = [ + "pco", + "prost", + "vortex-array", + "vortex-buffer", + "vortex-error", + "vortex-mask", + "vortex-session", +] + +[[package]] +name = "vortex-proto" +version = "0.86.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95ed2db063cc759e9461fc40a6da95ddf17f2d8af8948a3fe3b5079e1d5f9fae" +dependencies = [ + "prost", + "prost-types", +] + +[[package]] +name = "vortex-runend" +version = "0.86.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9614791732d7b4f13036318685808cb3a285b249895b0142fb92f1add57643c2" +dependencies = [ + "itertools 0.14.0", + "num-traits", + "prost", + "vortex-array", + "vortex-buffer", + "vortex-error", + "vortex-mask", + "vortex-session", +] + +[[package]] +name = "vortex-scan" +version = "0.86.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fc7d948af3a2eb6a11e31643eb7c3db1cb7e188421b0a74fd36009bbd6c283d" +dependencies = [ + "async-trait", + "futures", + "roaring", + "tracing", + "vortex-array", + "vortex-buffer", + "vortex-error", + "vortex-mask", + "vortex-session", +] + +[[package]] +name = "vortex-sequence" +version = "0.86.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a864402ea44d12e6daae1d63a9d4b65a902ebea7f12436e84066c2bffbdcbd1b" +dependencies = [ + "num-traits", + "prost", + "smallvec", + "vortex-array", + "vortex-buffer", + "vortex-error", + "vortex-mask", + "vortex-proto", + "vortex-session", +] + +[[package]] +name = "vortex-session" +version = "0.86.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32e3870512537f3a2a4df35f6044129b934bda96b44819d82744cfb2d4d9fe8f" +dependencies = [ + "arc-swap", + "lasso", + "parking_lot", + "vortex-error", + "vortex-utils", +] + +[[package]] +name = "vortex-sparse" +version = "0.86.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a58a99b9033e19bd3dabbbe18fe33cabc99b4ceb4b30329baea317e734e2ddf0" +dependencies = [ + "itertools 0.14.0", + "num-traits", + "prost", + "vortex-array", + "vortex-buffer", + "vortex-error", + "vortex-mask", + "vortex-session", +] + +[[package]] +name = "vortex-utils" +version = "0.86.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17f3f61a19a4f06e5db46faf52f76c403b6202ac662be298e36ec3cfe2d0a034" +dependencies = [ + "dashmap", + "hashbrown 0.17.1", +] + +[[package]] +name = "vortex-zigzag" +version = "0.86.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dc33b4e0a82055e8576161588258efb1b8581459db4decee20ed6a48605509e" +dependencies = [ + "vortex-array", + "vortex-buffer", + "vortex-error", + "vortex-mask", + "vortex-session", + "zigzag", +] + +[[package]] +name = "vortex-zstd" +version = "0.86.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5b49914d9a3b1bcba92a7e79a4cc3e2136f2ced349cbe91ec7eb2d30bc9dec4" +dependencies = [ + "itertools 0.14.0", + "num-traits", + "prost", + "vortex-array", + "vortex-buffer", + "vortex-edition", + "vortex-error", + "vortex-mask", + "vortex-session", + "zstd", +] + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasip2" +version = "1.0.4+wasi-0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.129" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bb54f33acc68fd454578d9820b0bde1a1a3d17aa17bb7b6595806d02886d409" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cbab34de2d982e9b48e18d216d04c4a6f641066ff19ffb699980f591ee3610e" +dependencies = [ + "js-sys", + "tokio", + "wasm-bindgen", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.129" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e29d0c35b16e224a7eeb5cd2d25e3e1968fbd65604117b44d3b789d00ee8535" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.129" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f501a8bc3719dba86ef8ae4728879c08001bea749eb1333ac5b91e040e2a6b7" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn 3.0.6", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.129" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23f0c9c52aa7cd7d77769a4cfe2a9adb1b331f489a41d912ce14513d5ab995c6" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "windows-core" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "windows-interface" +version = "0.59.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "wit-bindgen" +version = "0.57.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" + +[[package]] +name = "writeable" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ad82d2a33cdc9674dc7465672f271e096168fcdbe0f799d9e6db8c5892679dc" + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "yoke" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5" +dependencies = [ + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec8ebde2db3681e8c9980cc27822030e68752690ddfa9473e739aeb4dbde6d71" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.6", + "synstructure", +] + +[[package]] +name = "zerocopy" +version = "0.8.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6df92bf3d9227be3d53173901ddbffac2babc27ae50f397776ffd6dc33f800cb" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac4f328cf2f05d084e496c3e9c3f33ed0a183656a16e1fcec4d464d8373aec82" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "zerofrom" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f75b4683f6c7f45248d4d64056a24298c6281e0993356d7d1b4a1a962ef10d4a" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.6", + "synstructure", +] + +[[package]] +name = "zerotrie" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ea269c3bd32f0a32c321907a2ae912ba6f4649bb0fc764a15627e99a7095a3f" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0464e17806c1d976d5cba29399c7f08e516e279e2ba493f63123b5fca67dd8" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34df6fc39dbd26ddc9c10e6a2984476e13acce22e64e4487636ef494369225da" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.6", +] + +[[package]] +name = "zigzag" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70b40401a28d86ce16a330b863b86fd7dbee4d7c940587ab09ab8c019f9e3fdf" +dependencies = [ + "num-traits", +] + +[[package]] +name = "zmij" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" + +[[package]] +name = "zstd" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-buffers-fixture" +version = "0.1.0" +dependencies = [ + "tokio", + "vortex", +] + +[[package]] +name = "zstd-safe" +version = "7.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64d80649ab6db9d9f6f9c80a40becd948eda4714a0a5ac8c4d157a32231c7882" +dependencies = [ + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.1.0+zstd.1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ef0a8027ec3ee71300ab3bcbcd0393f434aa72b91ca6d635a39941deae8eea0" +dependencies = [ + "cc", + "pkg-config", +] diff --git a/scripts/fixtures/zstd-buffers/Cargo.toml b/scripts/fixtures/zstd-buffers/Cargo.toml new file mode 100644 index 00000000..9c40c666 --- /dev/null +++ b/scripts/fixtures/zstd-buffers/Cargo.toml @@ -0,0 +1,11 @@ +# Writes the vortex.zstd_buffers interop fixture (#444): vortex-jni cannot emit it (the zstd +# edition family is opt-in and the JNI writer exposes no compressor options). +[package] +name = "zstd-buffers-fixture" +version = "0.1.0" +edition = "2024" +publish = false + +[dependencies] +vortex = { version = "=0.86.1", features = ["tokio", "zstd"] } +tokio = { version = "1", features = ["full"] } diff --git a/scripts/fixtures/zstd-buffers/src/main.rs b/scripts/fixtures/zstd-buffers/src/main.rs new file mode 100644 index 00000000..36e7e888 --- /dev/null +++ b/scripts/fixtures/zstd-buffers/src/main.rs @@ -0,0 +1,57 @@ +//! Writes `zstd_buffers.vortex`: two columns, each wrapped in `vortex.zstd_buffers` by Rust's own +//! `ZstdBuffers::compress`, under the opt-in `zstd2026.02.0` edition (edition enforcement stays on). +//! +//! - `ints`: nullable i32 (`vortex.primitive`, values buffer + validity child), every 7th row null. +//! - `strs`: nullable utf8 (`vortex.varbin`, bytes buffer + offsets/validity children), every 5th +//! row null. +//! +//! Row `i`: `ints = i * 3 - 500`, `strs = "s{i % 13}"`. Usage: `cargo run --release -- `. + +use std::sync::Arc; + +use vortex::VortexSessionDefault; +use vortex::array::IntoArray; +use vortex::array::arrays::PrimitiveArray; +use vortex::array::arrays::StructArray; +use vortex::array::arrays::VarBinArray; +use vortex::array::validity::Validity; +use vortex::dtype::DType; +use vortex::dtype::Nullability; +use vortex::editions::EditionSessionExt; +use vortex::encodings::zstd::ZstdBuffers; +use vortex::encodings::zstd::editions::ZSTD_2026_02; +use vortex::file::WriteOptionsSessionExt; +use vortex::layout::layouts::flat::writer::FlatLayoutStrategy; +use vortex::session::VortexSession; + +const ROWS: i32 = 1_000; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let out = std::env::args().nth(1).ok_or("usage: zstd-buffers-fixture ")?; + let session = VortexSession::default(); + session.enable_edition(ZSTD_2026_02)?; + + let ints = PrimitiveArray::from_option_iter((0..ROWS).map(|i| (i % 7 != 0).then_some(i * 3 - 500))); + let strs = VarBinArray::from_iter( + (0..ROWS).map(|i| (i % 5 != 0).then(|| format!("s{}", i % 13))), + DType::Utf8(Nullability::Nullable), + ); + let table = StructArray::try_new( + ["ints", "strs"].into(), + vec![ + ZstdBuffers::compress(&ints.into_array(), 3, &session)?.into_array(), + ZstdBuffers::compress(&strs.into_array(), 3, &session)?.into_array(), + ], + ROWS as usize, + Validity::NonNullable, + )?; + + let mut file = tokio::fs::File::create(&out).await?; + session + .write_options() + .with_strategy(Arc::new(FlatLayoutStrategy::default())) + .write(&mut file, table.into_array().to_array_stream()) + .await?; + Ok(()) +}