Clast.Fsst 0.2.0

dotnet add package Clast.Fsst --version 0.2.0
                    
NuGet\Install-Package Clast.Fsst -Version 0.2.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Clast.Fsst" Version="0.2.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Clast.Fsst" Version="0.2.0" />
                    
Directory.Packages.props
<PackageReference Include="Clast.Fsst" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Clast.Fsst --version 0.2.0
                    
#r "nuget: Clast.Fsst, 0.2.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Clast.Fsst@0.2.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Clast.Fsst&version=0.2.0
                    
Install as a Cake Addin
#tool nuget:?package=Clast.Fsst&version=0.2.0
                    
Install as a Cake Tool

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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETStandard 2.0

  • 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.

Version Downloads Last Updated
0.2.0 39 7/24/2026
0.1.3 163 5/4/2026
0.1.2 151 4/26/2026
0.1.1 115 4/26/2026
0.1.0 121 4/25/2026