JNI bindings for Zstd native library that provides fast and high compression lossless algorithm for Java and all JVM languages.
—
Utility methods for size estimation, error handling, dictionary creation, and accessing Zstd configuration constants. These functions support the main compression operations and provide essential information for proper library usage.
Calculate buffer sizes and estimate data sizes for compression operations.
/**
* Returns maximum possible size of compressed data
* @param srcSize size of input data to be compressed
* @return maximum compressed size (worst case scenario)
*/
public static long compressBound(long srcSize);
/**
* Returns original size of compressed data (if stored in frame)
* @param src compressed data
* @return original uncompressed size, or 0 if unknown
*/
public static long decompressedSize(byte[] src);
/**
* Returns original size of compressed data from direct ByteBuffer
* @param src compressed data buffer
* @param srcPosition position in buffer where compressed data starts
* @param srcSize size of compressed data
* @return original uncompressed size, or 0 if unknown
*/
public static long decompressedDirectByteBufferSize(ByteBuffer src, int srcPosition, int srcSize);
/**
* Returns original size of compressed data from ByteBuffer
* @param srcBuf compressed data buffer (position to limit defines data)
* @return original uncompressed size, or 0 if unknown
*/
public static long decompressedSize(ByteBuffer srcBuf);Usage Examples:
import com.github.luben.zstd.Zstd;
// Calculate maximum compressed size for buffer allocation
byte[] data = "Some data to compress".getBytes();
long maxCompressedSize = Zstd.compressBound(data.length);
byte[] compressedBuffer = new byte[(int) maxCompressedSize];
// Compress and get actual size
long actualSize = Zstd.compress(compressedBuffer, data, 6);
if (Zstd.isError(actualSize)) {
throw new RuntimeException("Compression failed");
}
// Get original size from compressed data (if available)
long originalSize = Zstd.decompressedSize(compressedBuffer);
if (originalSize > 0) {
// Original size is known - can decompress without size parameter
byte[] decompressed = Zstd.decompress(compressedBuffer, (int) originalSize);
} else {
// Original size unknown - must track separately
System.out.println("Original size not stored in compressed data");
}Check and interpret error codes returned by compression operations.
/**
* Checks if return code indicates an error
* @param code return code from compression/decompression operations
* @return true if code represents an error
*/
public static boolean isError(long code);
/**
* Gets human-readable error message for error code
* @param code error code from failed operation
* @return descriptive error message
*/
public static String getErrorName(long code);Usage Examples:
// Safe compression with error checking
long result = Zstd.compress(dst, src, level);
if (Zstd.isError(result)) {
String errorMsg = Zstd.getErrorName(result);
throw new RuntimeException("Compression failed: " + errorMsg);
}
// Safe decompression with error checking
long decompResult = Zstd.decompress(dst, src);
if (Zstd.isError(decompResult)) {
String errorMsg = Zstd.getErrorName(decompResult);
throw new RuntimeException("Decompression failed: " + errorMsg);
}Create optimized dictionaries from sample data for improved compression ratios.
/**
* Creates a dictionary from sample data
* @param samples array of sample byte arrays representing typical data
* @param dictBuffer buffer to store the created dictionary (pre-allocated)
* @return size of dictionary written to buffer, or error code if failed
*/
public static long trainFromBuffer(byte[][] samples, byte[] dictBuffer);Usage Examples:
import java.util.*;
// Collect representative sample data
List<String> logLines = Arrays.asList(
"[2023-01-01 10:00:00] INFO: Application started",
"[2023-01-01 10:00:01] DEBUG: Configuration loaded",
"[2023-01-01 10:00:02] INFO: Database connection established",
"[2023-01-01 10:00:03] WARN: Cache miss for key user:123",
"[2023-01-01 10:00:04] ERROR: Failed to process request"
);
// Convert to byte arrays
byte[][] samples = logLines.stream()
.map(String::getBytes)
.toArray(byte[][]::new);
// Create dictionary buffer (typically 1KB to 100KB)
byte[] dictBuffer = new byte[4096]; // 4KB dictionary
// Train dictionary
long dictSize = Zstd.trainFromBuffer(samples, dictBuffer);
if (Zstd.isError(dictSize)) {
throw new RuntimeException("Dictionary training failed: " + Zstd.getErrorName(dictSize));
}
// Trim dictionary to actual size
byte[] dictionary = Arrays.copyOf(dictBuffer, (int) dictSize);
// Use dictionary for compression
byte[] logEntry = "[2023-01-01 10:00:05] INFO: New user registered".getBytes();
byte[] compressed = Zstd.compressUsingDict(logEntry, dictionary, 6);Access Zstd library constants for configuration and validation.
/**
* Gets Zstd magic number used in frame headers
* @return magic number constant
*/
public static int magicNumber();
/**
* Gets minimum window log size
* @return minimum window log value
*/
public static int windowLogMin();
/**
* Gets maximum window log size
* @return maximum window log value
*/
public static int windowLogMax();
/**
* Gets minimum chain log size
* @return minimum chain log value
*/
public static int chainLogMin();
/**
* Gets maximum chain log size
* @return maximum chain log value
*/
public static int chainLogMax();
/**
* Gets minimum hash log size
* @return minimum hash log value
*/
public static int hashLogMin();
/**
* Gets maximum hash log size
* @return maximum hash log value
*/
public static int hashLogMax();
/**
* Gets minimum search log size
* @return minimum search log value
*/
public static int searchLogMin();
/**
* Gets maximum search log size
* @return maximum search log value
*/
public static int searchLogMax();
/**
* Gets minimum search length
* @return minimum search length value
*/
public static int searchLengthMin();
/**
* Gets maximum search length
* @return maximum search length value
*/
public static int searchLengthMax();
/**
* Gets minimum target length
* @return minimum target length value
*/
public static int targetLengthMin();
/**
* Gets maximum target length
* @return maximum target length value
*/
public static int targetLengthMax();
/**
* Gets minimum frame header size
* @return minimum frame header size in bytes
*/
public static int frameHeaderSizeMin();
/**
* Gets maximum frame header size
* @return maximum frame header size in bytes
*/
public static int frameHeaderSizeMax();
/**
* Gets maximum block size
* @return maximum block size in bytes
*/
public static int blockSizeMax();Usage Examples:
// Validate compression parameters
int level = 15;
if (level < 1 || level > 22) {
throw new IllegalArgumentException("Invalid compression level");
}
// Check frame format
byte[] data = ...; // Some compressed data
if (data.length >= 4) {
int magic = Zstd.magicNumber();
// Check if data starts with Zstd magic number (platform-dependent byte order)
System.out.println("Zstd magic number: 0x" + Integer.toHexString(magic));
}
// Get configuration limits
System.out.println("Window log range: " + Zstd.windowLogMin() + " - " + Zstd.windowLogMax());
System.out.println("Maximum block size: " + Zstd.blockSizeMax() + " bytes");
System.out.println("Frame header size: " + Zstd.frameHeaderSizeMin() + " - " + Zstd.frameHeaderSizeMax() + " bytes");public static byte[] safeCompress(byte[] data, int level) {
// Calculate maximum possible size
long maxSize = Zstd.compressBound(data.length);
if (maxSize > Integer.MAX_VALUE) {
throw new IllegalArgumentException("Data too large for compression");
}
// Allocate buffer and compress
byte[] compressed = new byte[(int) maxSize];
long actualSize = Zstd.compress(compressed, data, level);
// Check for errors
if (Zstd.isError(actualSize)) {
throw new RuntimeException("Compression failed: " + Zstd.getErrorName(actualSize));
}
// Return trimmed array
return Arrays.copyOf(compressed, (int) actualSize);
}public static byte[] smartDecompress(byte[] compressed) {
// Try to get original size from frame
long originalSize = Zstd.decompressedSize(compressed);
if (originalSize > 0) {
// Size is known - decompress directly
return Zstd.decompress(compressed, (int) originalSize);
} else {
// Size unknown - must be provided by caller or use stream API
throw new IllegalArgumentException("Original size not available in compressed data");
}
}public static byte[] createOptimizedDictionary(List<byte[]> samples, int dictSize) {
// Validate inputs
if (samples.isEmpty()) {
throw new IllegalArgumentException("No samples provided");
}
// Convert to array
byte[][] sampleArray = samples.toArray(new byte[0][]);
// Create dictionary buffer
byte[] dictBuffer = new byte[dictSize];
// Train dictionary
long actualDictSize = Zstd.trainFromBuffer(sampleArray, dictBuffer);
// Check for errors
if (Zstd.isError(actualDictSize)) {
throw new RuntimeException("Dictionary training failed: " + Zstd.getErrorName(actualDictSize));
}
// Return trimmed dictionary
return Arrays.copyOf(dictBuffer, (int) actualDictSize);
}Install with Tessl CLI
npx tessl i tessl/maven-com-github-luben--zstd-jni