Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 20 additions & 31 deletions zstd/src/test/java/io/github/dfa1/zstd/RefPrefixTest.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.github.dfa1.zstd;

import static java.lang.foreign.ValueLayout.JAVA_BYTE;
import static io.github.dfa1.zstd.ZstdTestSupport.bytesOf;
import static io.github.dfa1.zstd.ZstdTestSupport.segmentOf;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

Expand All @@ -21,8 +22,8 @@ void roundTripsWithMatchingPrefix() {
try (Arena arena = Arena.ofConfined();
ZstdCompressCtx cctx = new ZstdCompressCtx();
ZstdDecompressCtx dctx = new ZstdDecompressCtx()) {
MemorySegment prefix = copy(arena, prefixBytes);
MemorySegment src = copy(arena, dataBytes);
MemorySegment prefix = segmentOf(arena, prefixBytes);
MemorySegment src = segmentOf(arena, dataBytes);
MemorySegment frame = arena.allocate(Zstd.compressBound(dataBytes.length));
MemorySegment out = arena.allocate(dataBytes.length);

Expand All @@ -34,7 +35,7 @@ void roundTripsWithMatchingPrefix() {

// Then
assertThat(m).isEqualTo(dataBytes.length);
assertThat(bytes(out, (int) m)).isEqualTo(dataBytes);
assertThat(bytesOf(out, (int) m)).isEqualTo(dataBytes);
}
}

Expand All @@ -47,8 +48,8 @@ void prefixIsAppliedAndRequiredToDecode() {
// for random content.)
byte[] random = randomBytes(0xBEEF, 16384);
try (Arena arena = Arena.ofConfined()) {
MemorySegment prefix = copy(arena, random);
MemorySegment src = copy(arena, random);
MemorySegment prefix = segmentOf(arena, random);
MemorySegment src = segmentOf(arena, random);

long baseline;
try (ZstdCompressCtx cctx = new ZstdCompressCtx().level(19)) {
Expand All @@ -58,7 +59,7 @@ void prefixIsAppliedAndRequiredToDecode() {
try (ZstdCompressCtx cctx = new ZstdCompressCtx().level(19)) {
cctx.refPrefix(prefix);
MemorySegment f = cctx.compress(arena, src);
frame = bytes(f, (int) f.byteSize());
frame = bytesOf(f, (int) f.byteSize());
}

// Then — the prefix slashes the frame (16 KiB random → tens of bytes)
Expand All @@ -68,16 +69,16 @@ void prefixIsAppliedAndRequiredToDecode() {
try (ZstdDecompressCtx dctx = new ZstdDecompressCtx()) {
MemorySegment out = arena.allocate(random.length);
dctx.refPrefix(prefix);
long m = dctx.decompress(out, copy(arena, frame));
assertThat(bytes(out, (int) m)).isEqualTo(random);
long m = dctx.decompress(out, segmentOf(arena, frame));
assertThat(bytesOf(out, (int) m)).isEqualTo(random);
}

// But — it cannot be recovered without the prefix
boolean reproduced;
try (ZstdDecompressCtx dctx = new ZstdDecompressCtx()) {
MemorySegment out = arena.allocate(random.length);
long m = dctx.decompress(out, copy(arena, frame));
reproduced = Arrays.equals(bytes(out, (int) m), random);
long m = dctx.decompress(out, segmentOf(arena, frame));
reproduced = Arrays.equals(bytesOf(out, (int) m), random);
} catch (ZstdException e) {
reproduced = false;
}
Expand All @@ -91,8 +92,8 @@ void clearingPrefixWithNullCompressesPlainly() {
byte[] dataBytes = "the quick brown fox".getBytes();
try (Arena arena = Arena.ofConfined();
ZstdCompressCtx cctx = new ZstdCompressCtx()) {
MemorySegment prefix = copy(arena, "a prior version of the text".getBytes());
MemorySegment src = copy(arena, dataBytes);
MemorySegment prefix = segmentOf(arena, "a prior version of the text".getBytes());
MemorySegment src = segmentOf(arena, dataBytes);
MemorySegment frame = arena.allocate(Zstd.compressBound(dataBytes.length));

// When — set then clear the prefix before compressing
Expand All @@ -105,7 +106,7 @@ void clearingPrefixWithNullCompressesPlainly() {
try (ZstdDecompressCtx dctx = new ZstdDecompressCtx()) {
MemorySegment out = arena.allocate(dataBytes.length);
long m = dctx.decompress(out, frame.asSlice(0, n));
restored = bytes(out, (int) m);
restored = bytesOf(out, (int) m);
}
assertThat(restored).isEqualTo(dataBytes);
}
Expand All @@ -118,8 +119,8 @@ void prefixIsSingleUseAndDoesNotStickAcrossFrames() {
byte[] random = randomBytes(0xCAFE, 16384);
try (Arena arena = Arena.ofConfined();
ZstdCompressCtx cctx = new ZstdCompressCtx().level(19)) {
MemorySegment prefix = copy(arena, random);
MemorySegment src = copy(arena, random);
MemorySegment prefix = segmentOf(arena, random);
MemorySegment src = segmentOf(arena, random);
MemorySegment first = arena.allocate(Zstd.compressBound(random.length));
MemorySegment second = arena.allocate(Zstd.compressBound(random.length));

Expand All @@ -137,7 +138,7 @@ void prefixIsSingleUseAndDoesNotStickAcrossFrames() {
try (ZstdDecompressCtx dctx = new ZstdDecompressCtx()) {
MemorySegment out = arena.allocate(random.length);
long m = dctx.decompress(out, second.asSlice(0, n2));
restored = bytes(out, (int) m);
restored = bytesOf(out, (int) m);
}
assertThat(restored).isEqualTo(random);
}
Expand Down Expand Up @@ -221,7 +222,7 @@ void refPrefixReturnsTheSameContextForChaining() {
try (Arena arena = Arena.ofConfined();
ZstdCompressCtx cctx = new ZstdCompressCtx();
ZstdDecompressCtx dctx = new ZstdDecompressCtx()) {
MemorySegment prefix = copy(arena, "a prior version".getBytes());
MemorySegment prefix = segmentOf(arena, "a prior version".getBytes());

// When setting and then clearing a prefix on both contexts
ZstdCompressCtx cSet = cctx.refPrefix(prefix);
Expand All @@ -243,7 +244,7 @@ void loadDictionaryFromSegmentReturnsTheSameContextForChaining() {
try (Arena arena = Arena.ofConfined();
ZstdCompressCtx cctx = new ZstdCompressCtx();
ZstdDecompressCtx dctx = new ZstdDecompressCtx()) {
MemorySegment dict = copy(arena, "dictionary sample payload ".repeat(64).getBytes());
MemorySegment dict = segmentOf(arena, "dictionary sample payload ".repeat(64).getBytes());

// When loading and then clearing a segment dictionary on both contexts
ZstdCompressCtx cSet = cctx.loadDictionary(dict);
Expand All @@ -259,18 +260,6 @@ void loadDictionaryFromSegmentReturnsTheSameContextForChaining() {
}
}

private static MemorySegment copy(Arena arena, byte[] src) {
MemorySegment seg = arena.allocate(src.length);
MemorySegment.copy(src, 0, seg, JAVA_BYTE, 0, src.length);
return seg;
}

private static byte[] bytes(MemorySegment seg, int len) {
byte[] out = new byte[len];
MemorySegment.copy(seg, JAVA_BYTE, 0, out, 0, len);
return out;
}

private static byte[] randomBytes(long seed, int n) {
byte[] b = new byte[n];
new Random(seed).nextBytes(b);
Expand Down
18 changes: 6 additions & 12 deletions zstd/src/test/java/io/github/dfa1/zstd/ZstdDictionaryTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -429,12 +429,6 @@ void rejectsHeapCompressDictSegment() {
// Then it fails fast
assertThatThrownBy(result).isInstanceOf(IllegalArgumentException.class);
}

private MemorySegment nativeDict(Arena arena, byte[] raw) {
MemorySegment seg = arena.allocate(raw.length);
MemorySegment.copy(raw, 0, seg, ValueLayout.JAVA_BYTE, 0, raw.length);
return seg;
}
}

@Nested
Expand Down Expand Up @@ -614,12 +608,6 @@ void loadAndRefReturnTheSameDecompressContext() {
assertThat(dctx.refDictionary(null)).isSameAs(dctx);
}
}

private MemorySegment nativeDict(Arena arena, byte[] raw) {
MemorySegment seg = arena.allocate(raw.length);
MemorySegment.copy(raw, 0, seg, ValueLayout.JAVA_BYTE, 0, raw.length);
return seg;
}
}

private static byte[] record(int i) {
Expand All @@ -629,4 +617,10 @@ private static byte[] record(int i) {
+ ",\"score\":" + (i * 7 % 1000)
+ ",\"tag\":\"event\"}").getBytes(StandardCharsets.UTF_8);
}

private static MemorySegment nativeDict(Arena arena, byte[] raw) {
MemorySegment seg = arena.allocate(raw.length);
MemorySegment.copy(raw, 0, seg, ValueLayout.JAVA_BYTE, 0, raw.length);
return seg;
}
}
9 changes: 2 additions & 7 deletions zstd/src/test/java/io/github/dfa1/zstd/ZstdFrameTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@
import java.lang.foreign.MemorySegment;
import java.lang.foreign.ValueLayout;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static io.github.dfa1.zstd.ZstdTestSupport.trainDictionary;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

Expand Down Expand Up @@ -409,11 +408,7 @@ void matchesThroughTheSegmentOverload() {
}

private ZstdDictionary trainDict() {
List<byte[]> samples = new ArrayList<>();
for (int i = 0; i < 3000; i++) {
samples.add(("{\"id\":" + i + ",\"k\":\"v" + (i % 30) + "\"}").getBytes(StandardCharsets.UTF_8));
}
return ZstdDictionary.train(samples, 8 * 1024);
return trainDictionary(3000);
}
}

Expand Down
9 changes: 2 additions & 7 deletions zstd/src/test/java/io/github/dfa1/zstd/ZstdMemoryTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@
import org.junit.jupiter.api.Test;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

import static io.github.dfa1.zstd.ZstdTestSupport.trainDictionary;
import static org.assertj.core.api.Assertions.assertThat;

class ZstdMemoryTest {
Expand Down Expand Up @@ -76,11 +75,7 @@ void streamsReportContextSize() {
}

private ZstdDictionary trainDict() {
List<byte[]> samples = new ArrayList<>();
for (int i = 0; i < 2000; i++) {
samples.add(("{\"id\":" + i + ",\"k\":\"v" + (i % 20) + "\"}").getBytes(StandardCharsets.UTF_8));
}
return ZstdDictionary.train(samples, 8 * 1024);
return trainDictionary(2000);
}
}
}
39 changes: 11 additions & 28 deletions zstd/src/test/java/io/github/dfa1/zstd/ZstdSegmentStreamTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import static java.lang.foreign.ValueLayout.JAVA_BYTE;
import static io.github.dfa1.zstd.ZstdTestSupport.bytesOf;
import static io.github.dfa1.zstd.ZstdTestSupport.segmentOf;
import static io.github.dfa1.zstd.ZstdTestSupport.trainDictionary;
import static org.assertj.core.api.Assertions.assertThat;

class ZstdSegmentStreamTest {
Expand All @@ -26,7 +26,7 @@ void roundTripsInOneCallEach() {
ZstdCompressStream cs = new ZstdCompressStream();
ZstdDecompressStream ds = new ZstdDecompressStream()) {

MemorySegment src = segment(arena, original);
MemorySegment src = segmentOf(arena, original);
MemorySegment dst = arena.allocate(Zstd.compressBound(original.length));

// When compressed in one END step
Expand All @@ -42,7 +42,7 @@ void roundTripsInOneCallEach() {

assertThat(d.isComplete()).isTrue();
assertThat(d.bytesProduced()).isEqualTo(original.length);
assertThat(bytes(out, d.bytesProduced())).isEqualTo(original);
assertThat(bytesOf(out, d.bytesProduced())).isEqualTo(original);
}
}
}
Expand Down Expand Up @@ -71,7 +71,7 @@ private byte[] drive(byte[] input, int chunk, boolean compress) {
ZstdCompressStream cs = compress ? new ZstdCompressStream() : null;
ZstdDecompressStream ds = compress ? null : new ZstdDecompressStream()) {

MemorySegment src = segment(arena, input);
MemorySegment src = segmentOf(arena, input);
MemorySegment dst = arena.allocate(chunk);
long srcOff = 0;
ZstdStreamResult r;
Expand All @@ -81,7 +81,7 @@ private byte[] drive(byte[] input, int chunk, boolean compress) {
? cs.compress(dst, srcSlice, ZstdEndDirective.END)
: ds.decompress(dst, srcSlice);
srcOff += r.bytesConsumed();
collected.writeBytes(bytes(dst, r.bytesProduced()));
collected.writeBytes(bytesOf(dst, r.bytesProduced()));
} while (!r.isComplete());
return collected.toByteArray();
}
Expand All @@ -97,7 +97,7 @@ void tracksByteCounters() {
try (Arena arena = Arena.ofConfined();
ZstdCompressStream cs = new ZstdCompressStream()) {

MemorySegment src = segment(arena, original);
MemorySegment src = segmentOf(arena, original);
MemorySegment dst = arena.allocate(Zstd.compressBound(original.length));

// fresh stream: nothing moved yet
Expand Down Expand Up @@ -127,35 +127,18 @@ void roundTripsAgainstDictionary() {
ZstdCompressStream cs = new ZstdCompressStream(3, dict);
ZstdDecompressStream ds = new ZstdDecompressStream(dict)) {

MemorySegment src = segment(arena, record);
MemorySegment src = segmentOf(arena, record);
MemorySegment dst = arena.allocate(Zstd.compressBound(record.length));
ZstdStreamResult c = cs.compress(dst, src, ZstdEndDirective.END);

MemorySegment out = arena.allocate(record.length);
ds.decompress(out, dst.asSlice(0, c.bytesProduced()));
assertThat(bytes(out, record.length)).isEqualTo(record);
assertThat(bytesOf(out, record.length)).isEqualTo(record);
}
}

private ZstdDictionary trainDict() {
List<byte[]> samples = new ArrayList<>();
for (int i = 0; i < 3000; i++) {
samples.add(("{\"id\":" + i + ",\"user\":\"u" + (i % 30) + "\",\"event\":\"x\"}")
.getBytes(StandardCharsets.UTF_8));
}
return ZstdDictionary.train(samples, 8 * 1024);
return trainDictionary(3000);
}
}

private static MemorySegment segment(Arena arena, byte[] bytes) {
MemorySegment seg = arena.allocate(Math.max(bytes.length, 1));
MemorySegment.copy(bytes, 0, seg, JAVA_BYTE, 0, bytes.length);
return seg;
}

private static byte[] bytes(MemorySegment seg, long len) {
byte[] out = new byte[Math.toIntExact(len)];
MemorySegment.copy(seg, JAVA_BYTE, 0, out, 0, out.length);
return out;
}
}
Loading
Loading