Zstd: 空のフレームを生成しないようにしますか?

作成日 2020年09月08日  ·  3コメント  ·  ソース: facebook/zstd

このコードを実行します:

#include <stdio.h>     // printf
#include <zstd.h>      // presumes zstd library is installed

void compress()
{
    char buffer[256];
    ZSTD_inBuffer in;
    ZSTD_outBuffer out;
    ZSTD_CCtx *cctx;

    in.src = &in;
    in.size = 0;
    in.pos = 0;

    out.dst = buffer;
    out.size = sizeof(buffer);
    out.pos = 0;

    cctx = ZSTD_createCCtx();

    ZSTD_compressStream2(cctx, &out, &in, ZSTD_e_flush);
    printf("ZSTD_e_flush, total output size: %zd\n", out.pos);

    ZSTD_compressStream2(cctx, &out, &in, ZSTD_e_flush);
    printf("ZSTD_e_flush, total output size: %zd\n", out.pos);

    ZSTD_compressStream2(cctx, &out, &in, ZSTD_e_end);
    printf("ZSTD_e_end, total output size: %zd\n", out.pos);

    ZSTD_compressStream2(cctx, &out, &in, ZSTD_e_end);
    printf("ZSTD_e_end, total output size: %zd\n", out.pos);

    ZSTD_freeCCtx(cctx);
}

int main(int argc, const char** argv)
{
    compress();
    return 0;
}

出力:

ZSTD_e_flush, total output size: 0
ZSTD_e_flush, total output size: 0
ZSTD_e_end, total output size: 9
ZSTD_e_end, total output size: 18

空のブロックは生成されていないようですが、空のフレームが生成されており、少し一貫性がないように見えます。
現在のフレームにコンテンツがない場合、空のフレームを生成できませんか?

question

全てのコメント3件

現在のフレームにコンテンツがない場合、空のフレームを生成できませんか?

正解です。空のフレームは生成できません。 誰かが3つのzstdフレームを連結し、2番目のフレームが空である場合を想像してみてください。 2番目のフレームが空であるために存在しなかった場合、3番目のストリームを2番目のストリームとして解釈し、3番目のストリームが空であると想定します。 しかし、それは正しくありません。

Zstdは常に有効なフレームを生成しますが、これは空ではありません。

必要に応じて、空の入力を空の出力にマップするコードをzstdの上に追加できます。 しかし、zstdはそれを行うことができません。

ストリーミングzstdの現在の実装では、送信するコンテンツがない状態でflush()に指示された場合、空のブロックは生成されません。 結果として、空のブロックが生成されることはありません。

この機能が必要な場合は、おそらくストリーミング操作のオプションのパラメーターとして、リファレンス実装を更新して追加することができます。

ただし、別の問題があります。 zstdデコーダーの古いバリアントにはバグがあり、生の空のブロックを処理できません。 このバグは現在修正されていますが、ユーザーベースが十分に大きいため、この修正を当然のこととは言えません。 したがって、互換性を最大にするために、 zstd実装で生の空のブロックを生成することはできません。

回避策は、皮肉なことに1バイト大きい圧縮された空のブロックを送信することです。 空のブロックの生成が要求された場合、この手法は機能し、デプロイされたすべてのデコーダーとの互換性を維持します。

とにかく、十分な理由(サポートする重要なシナリオ)がなければ、リファレンス実装をより複雑にするインセンティブがないため、デフォルトでは、空のブロックを生成しないという現在のポリシーに固執します。

これは空のフレームとは異なります。
v1.0が出るずっと前に、 NULLコンテンツでzstdフレームを生成する機能についてのリクエストがたくさん寄せられました。
これはパイプラインの観点から理解できます。
通常のフローはinput -> zstd compression -> zstd format -> transmit -> assume zstd format -> zstd decompress -> regenerated contentです。
入力は、空を含め、何でもかまいません。 また、単純化されたパイプラインは、特別なケースを回避することを好みます。したがって、コーナーケース用の独自の特別な分岐なしで、すべてをzstdに送信することを好みます。
したがって、上記のパイプラインはnullコンテンツと互換性がある必要があり、空のフレームを生成およびデコードする機能が必要です。

質問がむしろ: zstdデコーダーがnull入力をnull出力生成として解凍するように解釈しないのはなぜですか?
その場合、答えるのはより複雑ですが、エラーのケースと信号の欠如を、空のコンテンツの有効な送信または保存と強く区別したい理由はたくさんあります。 さまざまなトラフィック分析の制約に加えて。 そして、 null入力を有効な解凍エントリにすると、これらの目的が台無しになります。

ご説明ありがとうございます。

必要に応じて、空の入力を空の出力にマップするコードをzstdの上に追加できます。

わかりました、そのような必要がある人々にとって、このコードは実装するのが難しくありません。

このページは役に立ちましたか?
0 / 5 - 0 評価