-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added libzstd (compression library) and a simple wrapper for it. (#463)
- Loading branch information
Showing
5 changed files
with
87 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
// Copyright 2021, University of Freiburg, | ||
// Chair of Algorithms and Data Structures. | ||
// Author: Johannes Kalmbach <johannes.kalmbach@gmail.com> | ||
|
||
#pragma once | ||
|
||
#include <zstd.h> | ||
|
||
#include <vector> | ||
|
||
#include "../Exception.h" | ||
|
||
class ZstdWrapper { | ||
public: | ||
// Compress the given byte array and return the result; | ||
static std::vector<char> compress(void* src, size_t numBytes, | ||
int compressionLevel = 3) { | ||
std::vector<char> result(ZSTD_compressBound(numBytes)); | ||
auto compressedSize = ZSTD_compress(result.data(), result.size(), src, | ||
numBytes, compressionLevel); | ||
result.resize(compressedSize); | ||
return result; | ||
} | ||
|
||
// Decompress the given byte array, assuming that the size of the decompressed | ||
// data is known. | ||
template <typename T> | ||
requires(std::is_trivially_copyable_v<T>) static std::vector<T> decompress( | ||
void* src, size_t numBytes, size_t knownOriginalSize) { | ||
knownOriginalSize *= sizeof(T); | ||
std::vector<T> result(knownOriginalSize / sizeof(T)); | ||
auto compressedSize = | ||
ZSTD_decompress(result.data(), knownOriginalSize, src, numBytes); | ||
AD_CHECK(compressedSize == knownOriginalSize); | ||
return result; | ||
} | ||
|
||
// Decompress the given byte array to the given buffer of the given size, | ||
// returning the number of bytes of the decompressed data. | ||
template <typename T> | ||
requires(std::is_trivially_copyable_v<T>) static size_t | ||
decompressToBuffer(const char* src, size_t numBytes, T* buffer, | ||
size_t bufferCapacity) { | ||
auto decompressedSize = ZSTD_decompress(buffer, bufferCapacity, | ||
const_cast<char*>(src), numBytes); | ||
if (ZSTD_isError(decompressedSize)) { | ||
throw std::runtime_error(std::string("error during decompression : ") + | ||
ZSTD_getErrorName(decompressedSize)); | ||
} | ||
return decompressedSize; | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
// Copyright 2021, University of Freiburg, | ||
// Chair of Algorithms and Data Structures. | ||
// Author: Johannes Kalmbach <johannes.kalmbach@gmail.com> | ||
|
||
#include <gtest/gtest.h> | ||
|
||
#include "../src/util/CompressionUsingZstd/ZstdWrapper.h" | ||
|
||
// _____________________________________________________________________________ | ||
TEST(CompressionTest, Basic) { | ||
std::vector<int> x{1, 2, 3, 4}; | ||
std::vector<char> comp = | ||
ZstdWrapper::compress(x.data(), x.size() * sizeof(int)); | ||
auto decomp = ZstdWrapper::decompress<int>(comp.data(), comp.size(), 4); | ||
ASSERT_EQ(x, decomp); | ||
} | ||
|
||
// _____________________________________________________________________________ | ||
TEST(CompressionTest, DecompressToBuffer) { | ||
std::vector<int> x{1, 2, 3, 4}; | ||
std::vector<char> comp = | ||
ZstdWrapper::compress(x.data(), x.size() * sizeof(int)); | ||
std::vector<int> decomp(4); | ||
auto numBytesDecompressed = ZstdWrapper::decompressToBuffer<int>( | ||
comp.data(), comp.size(), decomp.data(), decomp.size() * sizeof(int)); | ||
ASSERT_EQ(x, decomp); | ||
ASSERT_EQ(4ul * sizeof(int), numBytesDecompressed); | ||
} |