CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-com-github-luben--zstd-jni

JNI bindings for Zstd native library that provides fast and high compression lossless algorithm for Java and all JVM languages.

Pending
Overview
Eval results
Files

utility-functions.mddocs/

Utility Functions

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.

Capabilities

Size Estimation and Bounds

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");
}

Error Handling

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);
}

Dictionary Training

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);

Zstd Configuration Constants

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");

Common Usage Patterns

Safe Compression with Error Handling

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);
}

Smart Decompression with Size Detection

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");
    }
}

Dictionary Training Workflow

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

docs

dictionary-compression.md

direct-buffer-streaming.md

index.md

static-compression.md

stream-compression.md

utility-functions.md

tile.json