如何使用多线程进行zlib压缩(相同的输入源)

8

我的目标是在并行线程中压缩相同来源的数据。我已经定义了一个任务列表,这些任务都有读取信息(每个任务中的数据量为500kb-1MB)。

我的压缩线程将使用ZLIB压缩每个块的数据,并将其存储在相应任务的outbuf中。

现在,我想要合并所有这些数据并创建一个标准的ZLIB格式输出文件。

从ZLIB RFC和浏览pigzee源代码后,我了解到:

ZLIB头如下所示:

     +---+---+
     |CMF|FLG| (2 bytes)
     +---+---+
     +---+---+---+---+
     |     DICTID    | (4 bytes. Present only when FLG.FDICT is set)
     +---+---+---+---+
     +=====================+
     |...compressed data...| (variable size of data)
     +=====================+
     +---+---+---+---+
     |     ADLER32   |  (4 bytes of variable data)
     +---+---+---+---+

在我的情况下,同样没有字典。
因此,当我组合两个压缩单元时,所有单元的标头都相同。
因此,我正在执行以下操作。
1. 对于第一个单元,我将编写标头+压缩数据。 2. 对于第二个单元到最后一个单元,我只编写压缩数据(没有标头和尾随部分)。 3. 所有单元完成后,我使用 adlrer32_combine() 并将所有作业输出数据的校验和转换为一个最终的adler 32,然后在底部更新输出文件。
但是问题是,在压缩时会出现错误,说某些地方数据无效。
是否已经有人尝试过类似的事情?任何相关信息都将非常有帮助。

1
关闭投票是为什么?请评论。 - Sandeep
1个回答

6
您不能简单地连接原始deflate数据流。每个deflate流都是自我终止的,因此解压缩将在第一个流的末尾结束。
您需要仔细查看pigz代码以了解如何合并deflate流。您可以使用Z_SYNC_FLUSH来完成最后一个块并将其带到字节边界,而不会结束deflate流。然后,您可以完成deflate流,并剥离标记为结束块的最终空块。除了最后一个应正常终止的deflate流之外,您还可以将一系列n-1未终止的deflate流和最后一个1终止的deflate流连接起来。

嗨,马克,在这个网址的deflate示例中 - http://www.zlib.net/zlib_how.html,头部没有单独放置(在pigz中的put_header())。我猜测它是由zlib库在deflate()调用中处理的。那么,在pigz中,如何管理以使其第一个deflate调用中没有头部。这是我的主要难点。 - Sandeep
2
你可以使用deflateInit2()来请求原始压缩(无标题或尾部)。这在zlib.h中有记录。 - Mark Adler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接