- C 74.6%
- Python 4.7%
- C++ 4.4%
- Scheme 3.9%
- JavaScript 3.7%
- Other 8.7%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| bindings | ||
| examples | ||
| include | ||
| pkg-config | ||
| src | ||
| tests | ||
| CHANGELOG.md | ||
| LICENSE | ||
| Makefile | ||
| README.md | ||
libvaptvupt — VaptVupt codec library for application developers
A compression library you can drop into any project, in any of 7 languages. Built on the VaptVupt C codec that beats zstd-3 on aggregate ratio by 1.07% while delivering 1.27× faster decode.
| Property | Value |
|---|---|
| Aggregate ratio vs zstd-3 | −1.07% (vv wins) |
| Decode throughput | 1.27× zstd-3 in aggregate |
| Per-fixture ratio wins vs zstd-3 | 4 of 8 fixtures (Silesia subset) |
Random-data decode (--fast) |
26,773 MB/s — 3.7× zstd-19, 1.5× lz4-9 |
| Library size | ~115 KB static, ~117 KB shared |
| Dependencies | None (zero runtime deps; pure C11) |
| License | GPL-3.0-or-later |
What's in the box
libvaptvupt-1.0.0/
├── src/ # C source (amalgamated single file)
│ ├── vaptvupt.c # the codec
│ └── main.c # CLI binary source (vaptvupt)
├── include/ # public headers
│ ├── vaptvupt.h # full C API
│ └── vaptvupt_api.h # simplified level-based API
├── bindings/
│ ├── cpp/vaptvupt.hpp # C++17 RAII header-only wrapper
│ ├── python/vaptvupt.py # Python ctypes binding (no compiler needed)
│ ├── nodejs/index.js # Node.js binding (zero npm deps; uses CLI)
│ ├── java/ # Java JNI binding + native shim
│ ├── guile/vaptvupt.scm # GNU Guile 3.0 dynamic-FFI binding
│ └── haskell/VaptVupt.hs # Haskell GHC FFI binding (ByteString)
├── tests/ # test suite per language (76 tests total)
├── examples/ # minimal example per language
├── pkg-config/ # libvaptvupt.pc.in template
└── Makefile # builds shared+static libs, runs all tests
Quick start
Build the library
make # → build/libvaptvupt.so + build/libvaptvupt.a + build/vaptvupt CLI
Install system-wide
sudo make install # → /usr/local/lib/libvaptvupt.{so,a} + /usr/local/include/vaptvupt.h
Default PREFIX=/usr/local. Override:
make install PREFIX=$HOME/.local
Use from pkg-config
pkg-config --cflags libvaptvupt # → -I/usr/local/include
pkg-config --libs libvaptvupt # → -L/usr/local/lib -lvaptvupt
Run all language tests
make test # runs C, C++, Python, Node.js, Java, Guile, Haskell tests
make test-c # individual languages
make test-cpp
make test-py
make test-node
make test-java
make test-guile
make test-haskell
Language quick reference
C
#include "vaptvupt_api.h"
uint8_t cmp[1024];
int64_t cmp_len = vvz_compress(src, src_len, cmp, sizeof(cmp), /*level=*/5);
uint8_t dec[1024];
int64_t dec_len = vvz_decompress(cmp, cmp_len, dec, sizeof(dec));
For the full API including streaming, see include/vaptvupt.h.
C++ (header-only wrapper, requires C++17)
#include <vaptvupt.hpp>
auto cmp = vaptvupt::compress(input, vaptvupt::Level::Extreme);
auto dec = vaptvupt::decompress(cmp, original_size);
// Streaming
vaptvupt::Compressor c(vaptvupt::Mode::Balanced);
c.write(chunk1);
c.write(chunk2);
auto out = c.finish();
Throws vaptvupt::Error on failure. Compressor/Decompressor use
RAII — buffers freed automatically.
Python (ctypes — no compiler needed at install)
import vaptvupt
from vaptvupt import Compressor, Level, Mode, Options
cmp = vaptvupt.compress(b"hello " * 100, Level.EXTREME)
out = vaptvupt.decompress(cmp, expected_size=600)
# Streaming
c = Compressor(mode=Mode.BALANCED)
c.write(b"chunk 1 ")
c.write(b"chunk 2 ")
cmp = c.finish()
Loads libvaptvupt.so via ctypes. Set LIBVAPTVUPT_PATH=/path/to/lib
or rely on LD_LIBRARY_PATH / find_library.
Node.js (zero npm deps)
const vv = require('vaptvupt');
const cmp = await vv.compress(buffer, { level: vv.Level.EXTREME });
const out = await vv.decompress(cmp);
// File-to-file (most efficient for large files)
await vv.compressFile('input.bin', 'output.vv');
await vv.decompressFile('output.vv', 'restored.bin');
The Node binding wraps the vaptvupt CLI binary via child_process
- temp files. Set
VAPTVUPT_BIN=/path/to/vaptvuptor rely onPATH. For tighter integration, build a native N-API addon against the shared library.
Java (JNI)
import vaptvupt.VaptVupt;
import vaptvupt.VaptVupt.Level;
import vaptvupt.VaptVupt.Mode;
byte[] cmp = VaptVupt.compress(data, Level.EXTREME);
byte[] out = VaptVupt.decompress(cmp, originalSize);
// Streaming with try-with-resources
try (VaptVupt.Compressor c = new VaptVupt.Compressor(Mode.BALANCED)) {
c.write(chunk1);
c.write(chunk2);
byte[] cmp = c.finish();
}
Throws VaptVuptException. Run with -Djava.library.path=/path/to/build
or place libvaptvupt_jni.so on LD_LIBRARY_PATH.
Guile Scheme (dynamic-FFI)
(use-modules (vaptvupt) (rnrs bytevectors))
(define src (string->utf8 "hello world hello world hello world ..."))
(define cmp (vv-compress src level-extreme))
(define out (vv-decompress cmp (bytevector-length src)))
;; Streaming
(define cs (vv-make-compressor mode-balanced))
(vv-write cs chunk1)
(vv-write cs chunk2)
(define cmp (vv-finish cs))
Errors are thrown via (throw 'vv-error code message). Set
LIBVAPTVUPT_PATH=/path/to/libvaptvupt.so or rely on the dynamic
loader's standard search paths. Tested with GNU Guile 3.0.9.
Haskell (GHC FFI)
{-# LANGUAGE OverloadedStrings #-}
import qualified VaptVupt as VV
import VaptVupt (Level(..), Mode(..))
main = do
cmp <- VV.compressLevel Extreme "hello world hello world ..."
out <- VV.decompress cmp originalSize
-- Streaming
cs <- VV.newCompressor ModeBalanced
VV.writeChunk cs "chunk 1 "
VV.writeChunk cs "chunk 2 "
cmp <- VV.finish cs
Compile with ghc -package bytestring -lvaptvupt YourMain.hs.
Throws VVException on errors. Tested with GHC 9.4.7.
Compression levels and modes
| Level (simple API) | Mode (full API) | Use case |
|---|---|---|
1 (FAST) |
VV_MODE_ULTRA_FAST |
Wire-protocol compression, ephemeral data |
5 (BALANCED, default) |
VV_MODE_BALANCED |
Hot-path writes, incremental snapshots |
9 (EXTREME) |
VV_MODE_EXTREME |
Cold storage, archival, max ratio |
Decode speed is the same across all levels — only encode speed and
compressed size change. Pick EXTREME for write-once-read-many workloads.
Performance summary (vs zstd-3 on Silesia subset, vv-extreme)
| Fixture | vv-extreme | zstd-3 | Δ |
|---|---|---|---|
| fx_text | 128,238 | 137,790 | −6.93% ✓ |
| fx_json | 198,213 | 203,276 | −2.49% ✓ |
| fx_source | 206,350 | 195,078 | +5.78% |
| bash | 738,698 | 727,132 | +1.59% |
| dickens | 3,818,656 | 3,669,252 | +4.07% |
| xml | 643,067 | 639,138 | +0.61% |
| sao | 5,410,425 | 5,551,158 | −2.54% ✓ |
| x-ray | 5,881,236 | 6,086,279 | −3.37% ✓ |
| Aggregate | 17,024,883 | 17,209,103 | −1.07% ✓ |
API stability
- Wire format: stable since VaptVupt 1.0.0, backward-compatible across the 1.x and 2.x lines. Files compressed with libvaptvupt 1.0.0 will decode with any future 1.x or 2.x release.
- C API: source-compatible across libvaptvupt 1.x. New fields in
vv_options_tare added at the end with sensible defaults viavv_default_options(). - Language bindings match this stability: Python's ctypes layout, Java's JNI signatures, and the Node.js / C++ APIs are all 1.x-stable.
- Encoder bytes are NOT bit-exact across releases — only roundtrip correctness is guaranteed. Use content hashes, not compressed hashes, for deduplication.
License
GPL-3.0-or-later — see LICENSE.
For commercial use under a different license, contact the upstream VaptVupt project.