LZ4ストリーミングAPIの例: ダブルバッファー
著者: Takayuki Matsuoka
blockStreaming_doubleBuffer.cは、ダブルバッファーによる圧縮・展開を実装する、LZ4ストリーミングAPIのサンプルです。
注意事項:
- まず「LZ4ストリーミングAPIの基礎」を読んでください。
- 比較的高度なアプリケーションの例です。
- 出力ファイルはlz4frameと互換性がなく、プラットフォームに依存します。
このサンプルのポイント
- 少量のメモリで巨大なファイルを扱う。
- Block APIより常に高い圧縮率。
- 均一なブロックサイズ。
圧縮の仕組み
まず、入力用の「ダブルバッファー」と、出力用のLZ4圧縮データバッファーを確保します。ダブルバッファーには、「最初」のページ(Page#1)と「二番目」のページ(Page#2)の二つのページがあります。
Double Buffer
Page#1 Page#2
+---------+---------+
| Block#1 | |
+----+----+---------+
|
v
{Out#1}
Prefix Dependency
+---------+
| |
v |
+---------+----+----+
| Block#1 | Block#2 |
+---------+----+----+
|
v
{Out#2}
External Dictionary Mode
+---------+
| |
| v
+----+----+---------+
| Block#3 | Block#2 |
+----+----+---------+
|
v
{Out#3}
Prefix Dependency
+---------+
| |
v |
+---------+----+----+
| Block#3 | Block#4 |
+---------+----+----+
|
v
{Out#4}次に、最初のブロックをダブルバッファーの最初のページに読み込み、LZ4_compress_continue()で圧縮します。初回は、LZ4は先行する依存先を知りません。そのため、その行を依存関係なしで圧縮し、LZ4圧縮データバッファーに圧縮ブロック{Out#1}を生成します。その後、{Out#1}をファイルに書き込みます。
次に、二番目のブロックをダブルバッファーの二番目のページに読み込み、圧縮します。今度は、LZ4がBlock#1への依存関係を使い、圧縮率を改善できます。この依存関係を「プレフィックスモード」と呼びます。
次に、三番目のブロックをダブルバッファーの 最初 のページに読み込み、圧縮します。この場合も、LZ4はBlock#2への依存関係を使えます。この依存関係を「外部辞書モード」と呼びます。
ファイルの末尾まで、この手順を繰り返します。
展開の仕組み
展開では、逆の処理を行います。
- 最初の圧縮ブロックを読み込みます。
- 最初のページに展開し、そのページをファイルに書き込みます。
- 二番目の圧縮ブロックを読み込みます。
- 二番目のページに展開し、そのページをファイルに書き込みます。
- 三番目の圧縮ブロックを読み込みます。
- 最初 のページに展開し、そのページをファイルに書き込みます。
圧縮ファイルの末尾まで、この手順を繰り返します。