Skip to content

Commit d02c029

Browse files
committed
Add a documentation site
1 parent f4484a2 commit d02c029

File tree

12 files changed

+340
-1
lines changed

12 files changed

+340
-1
lines changed

.github/workflows/pages.yml

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
on:
2+
push:
3+
branches:
4+
- main
5+
- docs # temporary for testing
6+
7+
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
8+
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
9+
concurrency:
10+
group: pages
11+
cancel-in-progress: false
12+
13+
jobs:
14+
build-docs:
15+
name: Build Documentation
16+
17+
runs-on: ubuntu-latest
18+
steps:
19+
- name: Checkout
20+
uses: actions/checkout@v4
21+
- name: Setup .NET
22+
uses: actions/setup-dotnet@v4
23+
with:
24+
dotnet-version: 8.0.x
25+
26+
- name: Install docfX
27+
run: dotnet tool update -g docfx
28+
- name: Build documentation
29+
run: docfx docfx.json
30+
31+
- name: Upload artifact
32+
uses: actions/upload-pages-artifact@v3
33+
with:
34+
path: 'artifacts/_site'
35+
36+
publish-docs:
37+
name: Publish Documentation
38+
needs: build-docs
39+
40+
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
41+
permissions:
42+
actions: read
43+
pages: write
44+
id-token: write
45+
46+
# Deploy to the github-pages environment
47+
environment:
48+
name: github-pages
49+
url: ${{ steps.deployment.outputs.page_url }}
50+
51+
runs-on: ubuntu-latest
52+
steps:
53+
- name: Deploy to GitHub Pages
54+
id: deployment
55+
uses: actions/deploy-pages@v4

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,4 @@ BenchmarkDotNet.Artifacts/
2424
test-results/
2525
TestResults/
2626
.DS_Store
27+
/api/

Snappier/Snappier.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444

4545
<ItemGroup>
4646
<None Include="..\README.md" Pack="true" PackagePath="$(PackageReadmeFile)" />
47-
<None Include="..\icon.png" Pack="true" PackagePath="$(PackageIcon)" />
47+
<None Include="..\images\icon.png" Pack="true" PackagePath="$(PackageIcon)" />
4848
</ItemGroup>
4949

5050
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">

docfx.json

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
{
2+
"$schema": "https://raw.githubusercontent.com/dotnet/docfx/main/schemas/docfx.schema.json",
3+
"metadata": [
4+
{
5+
"src": [
6+
{
7+
"src": "./Snappier",
8+
"files": [
9+
"**/*.csproj"
10+
]
11+
}
12+
],
13+
"dest": "api",
14+
"properties": {
15+
"TargetFramework": "net8.0"
16+
}
17+
}
18+
],
19+
"build": {
20+
"content": [
21+
{
22+
"files": [
23+
"**/*.{md,yml}"
24+
],
25+
"exclude": [
26+
"_site/**",
27+
"artifacts/**",
28+
"**/BenchmarkDotNet.Artifacts/**"
29+
]
30+
}
31+
],
32+
"resource": [
33+
{
34+
"files": [
35+
"images/**"
36+
]
37+
}
38+
],
39+
"output": "artifacts/_site",
40+
"template": [
41+
"default",
42+
"material/material"
43+
],
44+
"globalMetadata": {
45+
"_appName": "Snappier",
46+
"_appTitle": "Snappier",
47+
"_appLogoPath": "images/icon-48.png",
48+
"_disableContribution": true,
49+
"_enableSearch": true,
50+
"pdf": false
51+
}
52+
}
53+
}

docs/block.md

+129
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
# Block Compression
2+
3+
Block compression is ideal for data up to 64KB, though it may be used for data of any size. It does not include any stream
4+
framing or CRC validation. It also doesn't automatically revert to uncompressed data in the event of data size growth.
5+
6+
## Block compression/decompression using a buffer you already own
7+
8+
```cs
9+
using Snappier;
10+
11+
public class Program
12+
{
13+
private static byte[] Data = {0, 1, 2}; // Wherever you get the data from
14+
15+
public static void Main()
16+
{
17+
// This option assumes that you are managing buffers yourself in an efficient way.
18+
// In this example, we're using heap allocated byte arrays, however in most cases
19+
// you would get these buffers from a buffer pool like ArrayPool<byte> or MemoryPool<byte>.
20+
21+
// If the output buffer is too small, an ArgumentException is thrown. This will not
22+
// occur in this example because a sufficient buffer is always allocated via
23+
// Snappy.GetMaxCompressedLength or Snappy.GetUncompressedLength. There are TryCompress
24+
// and TryDecompress overloads that return false if the output buffer is too small
25+
// rather than throwing an exception.
26+
27+
// Compression
28+
byte[] buffer = new byte[Snappy.GetMaxCompressedLength(Data)];
29+
int compressedLength = Snappy.Compress(Data, buffer);
30+
Span<byte> compressed = buffer.AsSpan(0, compressedLength);
31+
32+
// Decompression
33+
byte[] outputBuffer = new byte[Snappy.GetUncompressedLength(compressed)];
34+
int decompressedLength = Snappy.Decompress(compressed, outputBuffer);
35+
36+
for (var i = 0; i < decompressedLength; i++)
37+
{
38+
// Do something with the data
39+
}
40+
}
41+
}
42+
```
43+
44+
## Block compression/decompression using a memory pool buffer
45+
46+
```cs
47+
using Snappier;
48+
49+
public class Program
50+
{
51+
private static byte[] Data = {0, 1, 2}; // Wherever you get the data from
52+
53+
public static void Main()
54+
{
55+
// This option uses `MemoryPool<byte>.Shared`. However, if you fail to
56+
// dispose of the returned buffers correctly it can result in inefficient garbage collection.
57+
// It is important to either call .Dispose() or use a using statement.
58+
59+
// Compression
60+
using (IMemoryOwner<byte> compressed = Snappy.CompressToMemory(Data))
61+
{
62+
// Decompression
63+
using (IMemoryOwner<byte> decompressed = Snappy.DecompressToMemory(compressed.Memory.Span))
64+
{
65+
// Do something with the data
66+
}
67+
}
68+
}
69+
}
70+
```
71+
72+
## Block compression/decompression using a buffer writter
73+
74+
```cs
75+
using Snappier;
76+
using System.Buffers;
77+
78+
public class Program
79+
{
80+
private static byte[] Data = {0, 1, 2}; // Wherever you get the data from
81+
82+
public static void Main()
83+
{
84+
// This option uses `IBufferWriter<byte>`. In .NET 6 you can get a simple
85+
// implementation such as `ArrayBufferWriter<byte>` but it may also be a `PipeWriter<byte>`
86+
// or any other more advanced implementation of `IBufferWriter<byte>`.
87+
88+
// These overloads also accept a `ReadOnlySequence<byte>` which allows the source data
89+
// to be made up of buffer segments rather than one large buffer. However, segment size
90+
// may be a factor in performance. For compression, segments that are some multiple of
91+
// 64KB are recommended. For decompression, simply avoid small segments.
92+
93+
// Compression
94+
var compressedBufferWriter = new ArrayBufferWriter<byte>();
95+
Snappy.Compress(new ReadOnlySequence<byte>(Data), compressedBufferWriter);
96+
var compressedData = compressedBufferWriter.WrittenMemory;
97+
98+
// Decompression
99+
var decompressedBufferWriter = new ArrayBufferWriter<byte>();
100+
Snappy.Decompress(new ReadOnlySequence<byte>(compressedData), decompressedBufferWriter);
101+
var decompressedData = decompressedBufferWriter.WrittenMemory;
102+
103+
// Do something with the data
104+
}
105+
}
106+
```
107+
108+
## Block compression/decompression using heap allocated byte[]
109+
110+
```cs
111+
using Snappier;
112+
113+
public class Program
114+
{
115+
private static byte[] Data = {0, 1, 2}; // Wherever you get the data from
116+
117+
public static void Main()
118+
{
119+
// This is generally the least efficient option,
120+
// but in some cases may be the simplest to implement.
121+
122+
// Compression
123+
byte[] compressed = Snappy.CompressToArray(Data);
124+
125+
// Decompression
126+
byte[] decompressed = Snappy.DecompressToArray(compressed);
127+
}
128+
}
129+
```

docs/getting-started.md

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Getting Started
2+
3+
## Installing
4+
5+
Simply add a NuGet package reference to the latest version of Snappier.
6+
7+
```xml
8+
<PackageReference Include="Snappier" Version="1.1.6" />
9+
```
10+
11+
or
12+
13+
```sh
14+
dotnet add package Snappier
15+
```

docs/stream.md

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Stream Compression
2+
3+
Stream compression reads or writes the [Snappy framing format](https://github.com/google/snappy/blob/master/framing_format.txt) designed for streaming.
4+
It is ideal for data being sent over a network stream, and includes additional framing data and CRC validation.
5+
It also recognizes when an individual block in the stream compresses poorly and will include it in uncompressed form.
6+
7+
## Stream compression/decompression
8+
9+
Compressing or decompressing a stream follows the same paradigm as other compression streams in .NET. `SnappyStream` wraps an inner stream. If decompressing you read from the `SnappyStream`, if compressing you write to the `SnappyStream`
10+
11+
```cs
12+
using System.IO;
13+
using System.IO.Compression;
14+
using Snappier;
15+
16+
public class Program
17+
{
18+
public static async Task Main()
19+
{
20+
using var fileStream = File.OpenRead("somefile.txt");
21+
22+
// First, compression
23+
using var compressed = new MemoryStream();
24+
25+
using (var compressor = new SnappyStream(compressed, CompressionMode.Compress, leaveOpen: true))
26+
{
27+
await fileStream.CopyToAsync(compressor);
28+
29+
// Disposing the compressor also flushes the buffers to the inner stream
30+
// We pass true to the constructor above so that it doesn't close/dispose the inner stream
31+
// Alternatively, we could call compressor.Flush()
32+
}
33+
34+
// Then, decompression
35+
36+
compressed.Position = 0; // Reset to beginning of the stream so we can read
37+
using var decompressor = new SnappyStream(compressed, CompressionMode.Decompress);
38+
39+
var buffer = new byte[65536];
40+
var bytesRead = decompressor.Read(buffer, 0, buffer.Length);
41+
while (bytesRead > 0)
42+
{
43+
// Do something with the data
44+
45+
bytesRead = decompressor.Read(buffer, 0, buffer.Length)
46+
}
47+
}
48+
}
49+
```

docs/toc.yml

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
- name: Getting Started
2+
href: getting-started.md
3+
- name: Block Compression
4+
href: block.md
5+
- name: Stream Compression
6+
href: stream.md

images/icon-48.png

6.23 KB
Loading
File renamed without changes.

index.md

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
---
2+
_layout: landing
3+
---
4+
5+
# Snappier
6+
7+
Snappier is a pure C# port of Google's [Snappy](https://github.com/google/snappy) compression algorithm. It is designed with speed as the primary goal, rather than compression ratio, and is ideal for compressing network traffic. Please see [the Snappy README file](https://github.com/google/snappy/blob/master/README.md) for more details on Snappy.
8+
9+
## Project Goals
10+
11+
The Snappier project aims to meet the following needs of the .NET community.
12+
13+
- Cross-platform C# implementation for Linux and Windows, without P/Invoke or special OS installation requirements
14+
- Compatible with .NET 4.6.1 and later and .NET 6 and later
15+
- Use .NET paradigms, including asynchronous stream support
16+
- Full compatibility with both block and stream formats
17+
- Near C++ level performance
18+
- Note: This is only possible on .NET 6 and later with the aid of [Span&lt;T&gt;](https://docs.microsoft.com/en-us/dotnet/api/system.span-1?view=netcore-3.1) and [System.Runtime.Intrinsics](https://fiigii.com/2019/03/03/Hardware-intrinsic-in-NET-Core-3-0-Introduction/).
19+
- .NET 4.6.1 is the slowest
20+
- Keep allocations and garbage collection to a minimum using buffer pools
21+
22+
## Other Projects
23+
24+
There are other projects available for C#/.NET which implement Snappy compression.
25+
26+
- [Snappy.NET](https://snappy.machinezoo.com/) - Uses P/Invoke to C++ for great performance. However, it only works on Windows, and is a bit heap allocation heavy in some cases. It also hasn't been updated since 2014 (as of 10/2020). This project may still be the best choice if your project is on the legacy .NET Framework on Windows, where Snappier is much less performant.
27+
- [IronSnappy](https://github.com/aloneguid/IronSnappy) - Another pure C# port, based on the Golang implementation instead of the C++ implementation.

toc.yml

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
- name: Documentation
2+
href: docs/
3+
- name: API
4+
href: api/

0 commit comments

Comments
 (0)