このページの内容

LZ4ストリーミングAPIの基礎

著者: Takayuki Matsuoka

LZ4のAPI群

LZ4には次のAPI群があります。

  • 「Auto Framing」API(lz4frame.h): 通常のアプリケーションで最も推奨するAPIです。LZ4コマンドラインユーティリティやnode-lz4など、LZ4フレーム形式に準拠する他のツール・ライブラリとの相互運用性を保証します。
  • 「Block」API: 単純な用途に推奨します。単一の生のメモリブロックをLZ4メモリブロックに圧縮し、その逆の展開も行います。
  • 「Streaming」API: 複雑な処理のために設計されています。例えば、メモリが制限された環境で巨大なストリームデータを圧縮する場合です。

基本的には「Auto Framing」APIを使うべきです。ただし、高度なアプリケーションを書く場合は、Block APIやStreaming APIを使う出番です。

Block APIとStreaming APIの違い

Block APIは、単一の連続したメモリブロックを圧縮・展開します。言い換えると、LZ4ライブラリは、単一の連続したメモリブロックから冗長性を見つけます。Streaming APIも同じことを行いますが、隣接する複数の連続メモリブロックを圧縮・展開します。そのため、Streaming APIはBlock APIより多くの冗長性を見つけられる可能性があります。

次の図は、APIとブロックサイズによる違いを示します。これらの図では、元のデータを連続する4KiBytesのチャンクに分割しています。

Original Data
    +---------------+---------------+----+----+----+
    | 4KiB Chunk A  | 4KiB Chunk B  | C  | D  |... |
    +---------------+---------------+----+----+----+

Example (1) : Block API, 4KiB Block
    +---------------+---------------+----+----+----+
    | 4KiB Chunk A  | 4KiB Chunk B  | C  | D  |... |
    +---------------+---------------+----+----+----+
    | Block #1      | Block #2      | #3 | #4 |... |
    +---------------+---------------+----+----+----+

                    (No Dependency)


Example (2) : Block API, 8KiB Block
    +---------------+---------------+----+----+----+
    | 4KiB Chunk A  | 4KiB Chunk B  | C  | D  |... |
    +---------------+---------------+----+----+----+
    |            Block #1           |Block #2 |... |
    +--------------------+----------+-------+-+----+
          ^              |             ^    |
          |              |             |    |
          +--------------+             +----+
          Internal Dependency          Internal Dependency


Example (3) : Streaming API, 4KiB Block
    +---------------+---------------+-----+----+----+
    | 4KiB Chunk A  | 4KiB Chunk B  | C   | D  |... |
    +---------------+---------------+-----+----+----+
    | Block #1      | Block #2      | #3  | #4 |... |
    +---------------+----+----------+-+---+-+--+----+
          ^              |   ^        | ^   |
          |              |   |        | |   |
          +--------------+   +--------+ +---+
          Dependency         Dependency Dependency
  • 例(1)には依存関係がありません。すべてのブロックを独立に圧縮します。
  • 例(2)の8KiBytesブロックには、当然ながら内部の依存関係があります。ただし、ブロック#1と#2は依然として独立に圧縮します。
  • 例(3)では、ブロック#2は#1に依存し、#3は#2と#1に、#4は#3、#2、#1に依存します。それ以降も同様です。

ここで、例(2)と(3)の違いが分かります。(2)ではチャンクBとCの間に依存関係がありませんが、(3)ではBとCの間に依存関係があります。この依存関係が圧縮率を改善します。

Streaming APIの制約

効率のため、Streaming APIは、圧縮・展開時に依存するメモリの複製を保持しません。したがって、利用者がこの依存先のメモリを明示的に保持する必要があります。通常、「依存先のメモリ」は、直前に隣接する連続したメモリで、最大64KiBytesです。LZ4は、それより前のメモリにはアクセスしません。