|
12 | 12 | import io.github.dfa1.vortex.core.PType; |
13 | 13 | import io.github.dfa1.vortex.encoding.FsstEncoding; |
14 | 14 | import io.github.dfa1.vortex.encoding.VarBinEncoding; |
| 15 | +import io.github.dfa1.vortex.encoding.VarBinViewEncoding; |
15 | 16 | import io.github.dfa1.vortex.writer.VortexWriter; |
16 | 17 | import io.github.dfa1.vortex.writer.WriteOptions; |
17 | 18 | import net.jqwik.api.Arbitraries; |
@@ -369,6 +370,76 @@ void javaWriter_jniReader_fsstUtf8Column(@TempDir Path tmp) throws IOException { |
369 | 370 | assertThat(decoded).containsExactly(data); |
370 | 371 | } |
371 | 372 |
|
| 373 | + @Test |
| 374 | + void javaWriter_jniReader_varBinViewUtf8Column_inlined(@TempDir Path tmp) throws IOException { |
| 375 | + // Given — VarBinView, all strings ≤12 bytes: inlined path (no data buffer) |
| 376 | + Path file = tmp.resolve("java_varbinview_inlined.vtx"); |
| 377 | + String[] data = {"hi", "yo", "ok", "abc", "short", "exactly12ok!"}; |
| 378 | + try (var ch = FileChannel.open(file, StandardOpenOption.CREATE, StandardOpenOption.WRITE); |
| 379 | + var sut = VortexWriter.create(ch, STRING_SCHEMA, WriteOptions.defaults(), |
| 380 | + List.of(new VarBinViewEncoding()))) { |
| 381 | + // When |
| 382 | + sut.writeChunk(Map.of("s", data)); |
| 383 | + } |
| 384 | + |
| 385 | + // Then |
| 386 | + String[] decoded = readStringColumn(file, "s"); |
| 387 | + assertThat(decoded).containsExactly(data); |
| 388 | + } |
| 389 | + |
| 390 | + @Test |
| 391 | + void javaWriter_jniReader_varBinViewUtf8Column_referenced(@TempDir Path tmp) throws IOException { |
| 392 | + // Given — VarBinView, all strings >12 bytes: reference path (data buffer present) |
| 393 | + Path file = tmp.resolve("java_varbinview_referenced.vtx"); |
| 394 | + String[] data = {"this is long text", "another long string", "yet another long one", "thirteenchars!"}; |
| 395 | + try (var ch = FileChannel.open(file, StandardOpenOption.CREATE, StandardOpenOption.WRITE); |
| 396 | + var sut = VortexWriter.create(ch, STRING_SCHEMA, WriteOptions.defaults(), |
| 397 | + List.of(new VarBinViewEncoding()))) { |
| 398 | + // When |
| 399 | + sut.writeChunk(Map.of("s", data)); |
| 400 | + } |
| 401 | + |
| 402 | + // Then |
| 403 | + String[] decoded = readStringColumn(file, "s"); |
| 404 | + assertThat(decoded).containsExactly(data); |
| 405 | + } |
| 406 | + |
| 407 | + @Test |
| 408 | + void javaWriter_jniReader_varBinViewUtf8Column_mixed(@TempDir Path tmp) throws IOException { |
| 409 | + // Given — VarBinView, mix of inlined (≤12) and referenced (>12) strings |
| 410 | + Path file = tmp.resolve("java_varbinview_mixed.vtx"); |
| 411 | + String[] data = {"short", "this is a longer string", "hi", "medium length ok", "x", "another longer string here"}; |
| 412 | + try (var ch = FileChannel.open(file, StandardOpenOption.CREATE, StandardOpenOption.WRITE); |
| 413 | + var sut = VortexWriter.create(ch, STRING_SCHEMA, WriteOptions.defaults(), |
| 414 | + List.of(new VarBinViewEncoding()))) { |
| 415 | + // When |
| 416 | + sut.writeChunk(Map.of("s", data)); |
| 417 | + } |
| 418 | + |
| 419 | + // Then |
| 420 | + String[] decoded = readStringColumn(file, "s"); |
| 421 | + assertThat(decoded).containsExactly(data); |
| 422 | + } |
| 423 | + |
| 424 | + /// VarBinView utf8 with arbitrary strings — exercises both inlined and referenced views. |
| 425 | + @Property(tries = 20) |
| 426 | + void prop_varBinView_utf8_roundTripsViaRust( |
| 427 | + @ForAll("varBinViewStringArrays") String[] data) throws IOException { |
| 428 | + Path tmp = Files.createTempDirectory("vortex-pbt-varbinview"); |
| 429 | + try { |
| 430 | + Path file = tmp.resolve("pbt_varbinview_utf8.vtx"); |
| 431 | + try (var ch = FileChannel.open(file, StandardOpenOption.CREATE, StandardOpenOption.WRITE); |
| 432 | + var sut = VortexWriter.create(ch, STRING_SCHEMA, WriteOptions.defaults(), |
| 433 | + List.of(new VarBinViewEncoding()))) { |
| 434 | + sut.writeChunk(Map.of("s", data)); |
| 435 | + } |
| 436 | + String[] decoded = readStringColumn(file, "s"); |
| 437 | + assertThat(decoded).containsExactly(data); |
| 438 | + } finally { |
| 439 | + deleteDir(tmp); |
| 440 | + } |
| 441 | + } |
| 442 | + |
372 | 443 | @Test |
373 | 444 | void javaWriter_jniReader_dictEncodedUtf8Column(@TempDir Path tmp) throws IOException { |
374 | 445 | // Given — DictEncoding (DictLayoutMetadata proto + children[0]=codes, children[1]=VarBin values) |
@@ -524,6 +595,15 @@ void prop_i64_roundTripsViaRust(@ForAll("i64Arrays") long[] data) throws IOExcep |
524 | 595 | } |
525 | 596 | } |
526 | 597 |
|
| 598 | + @Provide |
| 599 | + Arbitrary<String[]> varBinViewStringArrays() { |
| 600 | + // Strings 0–30 chars: spans both inlined (≤12 bytes) and referenced (>12 bytes) paths |
| 601 | + Arbitrary<String> strings = Arbitraries.strings() |
| 602 | + .alpha() |
| 603 | + .ofMinLength(0).ofMaxLength(30); |
| 604 | + return strings.array(String[].class).ofMinSize(0).ofMaxSize(1_000); |
| 605 | + } |
| 606 | + |
527 | 607 | @Provide |
528 | 608 | Arbitrary<String[]> asciiStringArrays() { |
529 | 609 | Arbitrary<String> strings = Arbitraries.strings() |
|
0 commit comments