zstdc++string压缩解压
zstd 简介
定义:
Zstandard(或Zstd)是由Facebook的Yann Collet开发的⼀个⽆损数据压缩算法。该名称也指其C语⾔的参考实现。第1版的实现于2016年8⽉31⽇发布为⾃由软件
设计Zstandard的⽬的是提供⼀个类似于DEFLATE算法的压缩⽐,但更快,特别是解压缩快的算法。
1. 它的压缩级别从负5级(最快)到22级(压缩速度最慢,但是压缩⽐最⾼)可以调节。
2. zstd包⾥⾯有压缩和解压缩的并⾏(多线程)实现。从1.
3.2版本(2017年10⽉)开始,zstd 有选择地实现⾮常长的搜索和重复数据消除
(--long,128MiB窗⼝),类似于rzip或lrzip。
3. 压缩速度在最快和最慢级别之间可以相差20倍或更多,⽽解压缩速度统统很快,在最快和最慢级别之间相差不到20%。
4. Zstandard命令⾏有⼀个“⾃适应”(--adapt)模式,根据I/O条件改变压缩级别,主要是写⼊输出的速度。
5. Zstd在其最⼤压缩级别下的压缩⽐接近lzma、lzham和ppmx,并且⽐lza或bzip2性能更好。
6. Zstandard达到了当前的Pareto边界,因为它解压缩的速度⽐任何其他当前可⽤的算法都要快,并且有类似的或者更好的压缩⽐。
7. 字典对⼩⽂件的压缩⽐有很⼤的影响,所以Zstandard可以使⽤⽤户提供的压缩字典。它还提供了⼀种训练模式,能够从⼀组样本⽣成
⼀个字典。
8. 特别是,可以加载⼀个字典来处理⽂件之间具有冗余的⼤型⽂件集,但不⼀定在每个⽂件(例如⽇志⽂件)内。
c++中应⽤
最常见的就是对于字符串的压缩,下边给出字符串源码
//
// -*- coding: utf-8-unix; -*-
// Copyright (c) 2020 Tencent, Inc.
// All rights reserved.
//
// Date: 2020/11/30 13:45
// File:
// Desc:
//
#include "util.h"
#include "third_party/zstd/zstd.h"
namespace util {
int Util::CompressString(const string& src, string& dst, int compressionlevel) {
size_t const cBuffSize = ZSTD_compressBound(src.size());
auto dstp = const_cast<void*>(static_cast<const void*>(dst.c_str()));
auto srcp = static_cast<const void*>(src.c_str());
size_t const cSize = ZSTD_compress(dstp, cBuffSize, srcp, src.size(), compressionlevel);
auto code = ZSTD_isError(cSize);
if (code) {
return code;字符串长度压缩
}
return code;
}
int Util::DecompressString(const string& src, string& dst) {
size_t const cBuffSize = ZSTD_getFrameContentSize(src.c_str(), src.size());
if (0 == cBuffSize) {
return cBuffSize;
}
if (ZSTD_CONTENTSIZE_UNKNOWN == cBuffSize) {
return StreamDecompressString(src, dst);
}
if (ZSTD_CONTENTSIZE_ERROR == cBuffSize) {
return -2;
}
auto dstp = const_cast<void*>(static_cast<const void*>(dst.c_str()));
auto srcp = static_cast<const void*>(src.c_str());
size_t const cSize = ZSTD_decompress(dstp, cBuffSize, srcp, src.size());
auto code = ZSTD_isError(cSize);
if (code) {
return code;
}
return code;
}
int Util::StreamCompressString(const string& src, string& dst, int compressionlevel) { size_t const buffInSize = ZSTD_CStreamInSize();
string buffInTmp;
auto buffIn = const_cast<void*>(static_cast<const void*>(buffInTmp.c_str()));
auto buffOutSize = ZSTD_CStreamOutSize();
string buffOutTmp;
auto buffOut = const_cast<void*>(static_cast<const void*>(buffOutTmp.c_str()));
ZSTD_CCtx* const cctx = ZSTD_createCCtx();
ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, compressionlevel);
size_t const toRead = buffInSize;
auto local_pos = 0;
auto buff_tmp = const_cast<char*>(buffInTmp.c_str());
for (;;) {
size_t read = py(buff_tmp, toRead, local_pos);
local_pos += read;
int const lastChunk = (read < toRead);
ZSTD_EndDirective const mode = lastChunk ? ZSTD_e_end : ZSTD_e_continue;
ZSTD_inBuffer input = {buffIn, read, 0};
int finished;
do {
ZSTD_outBuffer output = {buffOut, buffOutSize, 0};
size_t const remaining = ZSTD_compressStream2(cctx, &output, &input, mode); dst.d(), buffOutTmp.begin(), buffOutTmp.begin() + output.pos);
finished = lastChunk ? (remaining == 0) : (input.pos == input.size);
} while (!finished);
if (lastChunk) {
break;
}
}
ZSTD_freeCCtx(cctx);
return 0;
}
int Util::StreamDecompressString(const string& src, string& dst, int compressionlevel) { size_t const buffInSize = ZSTD_DStreamInSize();
string buffInTmp;
auto buffIn = const_cast<void*>(static_cast<const void*>(buffInTmp.c_str()));
auto buffOutSize = ZSTD_DStreamOutSize();
string buffOutTmp;
auto buffOut = const_cast<void*>(static_cast<const void*>(buffOutTmp.c_str()));
ZSTD_DCtx* const dctx = ZSTD_createDCtx();
size_t const toRead = buffInSize;
size_t read;
size_t last_ret = 0;
size_t local_pos = 0;
auto buff_tmp = const_cast<char*>(buffInTmp.c_str());
while ((read = py(buff_tmp, toRead, local_pos))) {
local_pos += read;
ZSTD_inBuffer input = {buffIn, read, 0};
while (input.pos < input.size) {
ZSTD_outBuffer output = {buffOut, buffOutSize, 0};
size_t const ret = ZSTD_decompressStream(dctx, &output, &input);
dst.d(), buffOutTmp.begin(), buffOutTmp.begin() + output.pos);
last_ret = ret;
}
}
ZSTD_freeDCtx(dctx);
if(last_ret != 0) {
return -3;
}
return 0;
}
} // namespace util
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论