このページの内容

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への依存関係を使えます。この依存関係を「外部辞書モード」と呼びます。

ファイルの末尾まで、この手順を繰り返します。

展開の仕組み

展開では、逆の処理を行います。

  • 最初の圧縮ブロックを読み込みます。
  • 最初のページに展開し、そのページをファイルに書き込みます。
  • 二番目の圧縮ブロックを読み込みます。
  • 二番目のページに展開し、そのページをファイルに書き込みます。
  • 三番目の圧縮ブロックを読み込みます。
  • 最初 のページに展開し、そのページをファイルに書き込みます。

圧縮ファイルの末尾まで、この手順を繰り返します。