Clast.Fsst
0.2.0
dotnet add package Clast.Fsst --version 0.2.0
NuGet\Install-Package Clast.Fsst -Version 0.2.0
<PackageReference Include="Clast.Fsst" Version="0.2.0" />
<PackageVersion Include="Clast.Fsst" Version="0.2.0" />
<PackageReference Include="Clast.Fsst" />
paket add Clast.Fsst --version 0.2.0
#r "nuget: Clast.Fsst, 0.2.0"
#:package Clast.Fsst@0.2.0
#addin nuget:?package=Clast.Fsst&version=0.2.0
#tool nuget:?package=Clast.Fsst&version=0.2.0
Clast.Fsst
A C# implementation of FSST (Fast Static Symbol Table) string compression. FSST is a lightweight, byte-oriented dictionary compressor designed for columnar databases — it produces small, randomly-accessible compressed strings with very fast decompression.
This library is part of the clast-project.
Features
- FSST8 — 1-byte codes (up to 255 symbols) plus an escape byte for unmatched literals.
- FSST12 — 12-bit codes packed two-per-three-bytes (up to 4096 symbols, no escape).
- Single-string and batch compress / decompress.
- Versioned binary format for serializing symbol tables.
Target frameworks
| TFM | Notes |
|---|---|
net10.0 |
Primary development target. |
net8.0 |
LTS. |
netstandard2.0 |
Pulls in System.Memory; ships with internal polyfills for BitOperations, Index/Range, KeyValuePair.Deconstruct, etc. |
The test suite multi-targets net48, net8.0, and net10.0 so the netstandard2.0 build is exercised end-to-end through a .NET Framework 4.8 host.
Quick start
using Clast.Fsst;
using System.Text;
var corpus = new[]
{
Encoding.UTF8.GetBytes("the quick brown fox jumps over the lazy dog"),
Encoding.UTF8.GetBytes("the lazy dog sleeps in the shade"),
};
// Build a symbol table from a representative corpus.
SymbolTable table = FsstEncoder.BuildSymbolTable(corpus);
// Compress / decompress a single value.
byte[] compressed = FsstEncoder.Compress(table, corpus[0]);
FsstDecoder decoder = FsstDecoder.FromSymbolTable(table);
byte[] roundtrip = decoder.Decompress(compressed);
// Or compress / decompress a batch into caller-supplied buffers (Arrow-style prefix-sum offsets):
var (data, lengths) = FsstEncoder.CompressBatch(table, corpus);
var dst = new byte[FsstDecoder.MaxDecompressedLength(data.Length)];
var offsets = new int[corpus.Length + 1];
decoder.TryDecompressBatch(data, lengths, dst, offsets, out int totalWritten);
// Item i is now in dst[offsets[i]..offsets[i+1]].
FSST12
Fsst12Encoder / Fsst12Decoder follow the same shape but use 12-bit codes (no escape, 1.5 bytes per code on average). Prefer FSST12 when the input has a large effective symbol vocabulary; prefer FSST8 when codes must be byte-aligned for cheap random-access decoding.
SymbolMap map = Fsst12Encoder.BuildSymbolTable(corpus);
byte[] compressed = Fsst12Encoder.Compress(map, corpus[0]);
Fsst12Decoder decoder = Fsst12Decoder.FromSymbolMap(map);
byte[] roundtrip = decoder.Decompress(compressed);
Persisting a symbol table
byte[] tableBytes = FsstSerializer.ExportFsst8(table);
// ... store it, send it over the wire ...
SymbolTable restored = FsstSerializer.ImportFsst8(tableBytes);
// Or skip straight to a decoder:
FsstDecoder decoder = FsstSerializer.ImportFsst8Decoder(tableBytes);
The FSST8 export uses the cwida/fsst fsst_export() on-disk format (17-byte header
followed by raw symbol bytes in code order), so payloads are interoperable with the
reference C++ implementation.
ExportFsst12 / ImportFsst12 / ImportFsst12Decoder are the FSST12 equivalents
and use a separate length-prefixed framing (cwida does not publish an FSST12 export
format).
Bring-your-own framing
Other consumers (Lance, for example) wrap symbol tables in their own container.
FsstDecoder.FromSymbols skips the wire format entirely and takes pre-extracted
symbols indexed by code:
// lengths[i] is the byte length of the symbol for code i (0 = unused slot).
// packedValues holds 8 little-endian bytes per code.
FsstDecoder decoder = FsstDecoder.FromSymbols(lengths, packedValues);
Parse your container's framing yourself, hand over the per-code lengths and 8-byte slots, and you get back a decoder.
Project layout
src/Fsst/ library (Clast.Fsst.dll)
test/Fsst.Tests/ xUnit test suite
benchmarks/Fsst.Benchmarks/ BenchmarkDotNet harness
Build & test
dotnet build
dotnet test
References
- FSST: Fast Random Access String Compression — Peter Boncz, Thomas Neumann, Viktor Leis. PVLDB Vol. 13, 2020.
- Reference C++ implementation: https://github.com/cwida/fsst
License
Licensed under the Apache License, Version 2.0. See LICENSE.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- System.Memory (>= 4.5.5)
-
net10.0
- No dependencies.
-
net8.0
- No dependencies.
NuGet packages (2)
Showing the top 2 NuGet packages that depend on Clast.Fsst:
| Package | Downloads |
|---|---|
|
EngineeredWood.Lance
A reader and writer for the Lance columnar file format (v2.0 / v2.1 / v2.2) that speaks Apache Arrow. Preliminary 0.1.0 — APIs may change before 1.0.0. |
|
|
EngineeredWood.Vortex
A reader, writer, and predicate-based zone-pruning API for the Vortex columnar file format that speaks Apache Arrow. Preliminary 0.1.0 — APIs may change before 1.0.0. |
GitHub repositories
This package is not used by any popular GitHub repositories.