2022-04-26 18:14:09 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <Compression/ICompressionCodec.h>
|
|
|
|
#include <qpl/qpl.h>
|
2022-07-09 16:03:25 +00:00
|
|
|
#include <random>
|
2022-07-07 14:04:17 +00:00
|
|
|
|
2022-04-26 18:14:09 +00:00
|
|
|
namespace Poco
|
|
|
|
{
|
|
|
|
class Logger;
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
|
2022-07-19 21:48:41 +00:00
|
|
|
/// DeflateQplJobHWPool is resource pool to provide the job objects.
|
|
|
|
/// Job object is used for storing context information during offloading compression job to HW Accelerator.
|
2022-07-09 18:42:01 +00:00
|
|
|
class DeflateQplJobHWPool
|
2022-04-26 18:14:09 +00:00
|
|
|
{
|
|
|
|
public:
|
2022-07-09 18:42:01 +00:00
|
|
|
DeflateQplJobHWPool();
|
2022-07-15 20:12:26 +00:00
|
|
|
|
2022-07-09 18:42:01 +00:00
|
|
|
~DeflateQplJobHWPool();
|
2022-04-26 18:14:09 +00:00
|
|
|
|
2022-07-15 21:04:27 +00:00
|
|
|
qpl_job * acquireJob(UInt32 &job_id);
|
2022-07-09 18:57:38 +00:00
|
|
|
|
2022-07-15 20:12:26 +00:00
|
|
|
static void releaseJob(UInt32 job_id);
|
2022-07-11 16:08:35 +00:00
|
|
|
|
|
|
|
static const bool & isJobPoolReady() { return job_pool_ready; }
|
2022-07-07 18:14:47 +00:00
|
|
|
|
2022-07-09 21:50:57 +00:00
|
|
|
static DeflateQplJobHWPool & instance();
|
|
|
|
|
2022-04-26 18:14:09 +00:00
|
|
|
private:
|
2022-07-15 19:32:10 +00:00
|
|
|
static bool tryLockJob(UInt32 index);
|
2022-04-26 18:14:09 +00:00
|
|
|
|
2022-07-15 19:32:10 +00:00
|
|
|
static void unLockJob(UInt32 index);
|
2022-07-08 16:09:58 +00:00
|
|
|
|
2022-07-15 20:12:26 +00:00
|
|
|
/// Maximum jobs running in parallel supported by IAA hardware
|
|
|
|
static constexpr auto MAX_HW_JOB_NUMBER = 1024;
|
2022-07-11 16:08:35 +00:00
|
|
|
/// Entire buffer for storing all job objects
|
|
|
|
static std::unique_ptr<uint8_t[]> hw_jobs_buffer;
|
|
|
|
/// Job pool for storing all job object pointers
|
|
|
|
static std::array<qpl_job *, DeflateQplJobHWPool::MAX_HW_JOB_NUMBER> hw_job_ptr_pool;
|
|
|
|
/// Locks for accessing each job object pointers
|
|
|
|
static std::array<std::atomic_bool, DeflateQplJobHWPool::MAX_HW_JOB_NUMBER> hw_job_ptr_locks;
|
2022-07-09 21:50:57 +00:00
|
|
|
static bool job_pool_ready;
|
2022-07-09 16:03:25 +00:00
|
|
|
std::mt19937 random_engine;
|
|
|
|
std::uniform_int_distribution<int> distribution;
|
2022-06-08 15:47:44 +00:00
|
|
|
};
|
2022-07-07 18:14:47 +00:00
|
|
|
|
2022-07-09 18:42:01 +00:00
|
|
|
class SoftwareCodecDeflateQpl
|
2022-06-08 15:47:44 +00:00
|
|
|
{
|
|
|
|
public:
|
2022-07-09 18:42:01 +00:00
|
|
|
~SoftwareCodecDeflateQpl();
|
2022-07-15 19:32:10 +00:00
|
|
|
UInt32 doCompressData(const char * source, UInt32 source_size, char * dest, UInt32 dest_size);
|
|
|
|
void doDecompressData(const char * source, UInt32 source_size, char * dest, UInt32 uncompressed_size);
|
2022-06-08 15:47:44 +00:00
|
|
|
|
|
|
|
private:
|
2022-07-09 14:09:23 +00:00
|
|
|
qpl_job * sw_job = nullptr;
|
2022-07-13 20:12:15 +00:00
|
|
|
std::unique_ptr<uint8_t[]> sw_buffer;
|
2022-06-08 15:47:44 +00:00
|
|
|
qpl_job * getJobCodecPtr();
|
2022-04-26 18:14:09 +00:00
|
|
|
};
|
|
|
|
|
2022-07-09 18:42:01 +00:00
|
|
|
class HardwareCodecDeflateQpl
|
2022-06-08 15:47:44 +00:00
|
|
|
{
|
|
|
|
public:
|
2022-07-09 15:12:41 +00:00
|
|
|
/// RET_ERROR stands for hardware codec fail,need fallback to software codec.
|
2022-07-15 19:32:10 +00:00
|
|
|
static constexpr Int32 RET_ERROR = -1;
|
2022-07-09 15:12:41 +00:00
|
|
|
|
2022-07-09 18:42:01 +00:00
|
|
|
HardwareCodecDeflateQpl();
|
|
|
|
~HardwareCodecDeflateQpl();
|
2022-07-15 19:32:10 +00:00
|
|
|
Int32 doCompressData(const char * source, UInt32 source_size, char * dest, UInt32 dest_size) const;
|
2022-07-18 18:40:49 +00:00
|
|
|
|
2022-07-18 21:44:15 +00:00
|
|
|
///Submit job request to the IAA hardware and then busy waiting till it complete.
|
|
|
|
Int32 doDecompressDataSynchronous(const char * source, UInt32 source_size, char * dest, UInt32 uncompressed_size);
|
|
|
|
|
|
|
|
///Submit job request to the IAA hardware and return immediately. IAA hardware will process decompression jobs automatically.
|
2022-07-15 19:32:10 +00:00
|
|
|
Int32 doDecompressDataAsynchronous(const char * source, UInt32 source_size, char * dest, UInt32 uncompressed_size);
|
2022-07-18 18:40:49 +00:00
|
|
|
|
|
|
|
/// Flush result for all previous requests which means busy waiting till all the jobs in "decomp_async_job_map" are finished.
|
|
|
|
/// Must be called subsequently after several calls of doDecompressDataReq.
|
2022-07-07 18:14:47 +00:00
|
|
|
void flushAsynchronousDecompressRequests();
|
2022-06-08 15:47:44 +00:00
|
|
|
|
|
|
|
private:
|
2022-07-09 14:09:23 +00:00
|
|
|
/// Asynchronous job map for decompression: job ID - job object.
|
|
|
|
/// For each submission, push job ID && job object into this map;
|
|
|
|
/// For flush, pop out job ID && job object from this map. Use job ID to release job lock and use job object to check job status till complete.
|
2022-07-15 19:32:10 +00:00
|
|
|
std::map<UInt32, qpl_job *> decomp_async_job_map;
|
2022-06-08 15:47:44 +00:00
|
|
|
Poco::Logger * log;
|
|
|
|
};
|
2022-07-11 16:08:35 +00:00
|
|
|
|
2022-07-09 18:42:01 +00:00
|
|
|
class CompressionCodecDeflateQpl : public ICompressionCodec
|
2022-04-26 18:14:09 +00:00
|
|
|
{
|
|
|
|
public:
|
2022-07-09 18:42:01 +00:00
|
|
|
CompressionCodecDeflateQpl();
|
2022-04-26 18:14:09 +00:00
|
|
|
uint8_t getMethodByte() const override;
|
|
|
|
void updateHash(SipHash & hash) const override;
|
|
|
|
|
|
|
|
protected:
|
|
|
|
bool isCompression() const override
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
2022-07-07 18:14:47 +00:00
|
|
|
|
2022-04-26 18:14:09 +00:00
|
|
|
bool isGenericCompression() const override
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
2022-07-07 18:14:47 +00:00
|
|
|
|
2022-07-15 19:32:10 +00:00
|
|
|
UInt32 doCompressData(const char * source, UInt32 source_size, char * dest) const override;
|
|
|
|
void doDecompressData(const char * source, UInt32 source_size, char * dest, UInt32 uncompressed_size) const override;
|
2022-07-09 17:54:23 +00:00
|
|
|
///Flush result for previous asynchronous decompression requests on asynchronous mode.
|
2022-07-07 18:14:47 +00:00
|
|
|
void flushAsynchronousDecompressRequests() override;
|
2022-04-26 18:14:09 +00:00
|
|
|
|
|
|
|
private:
|
2022-07-15 19:32:10 +00:00
|
|
|
UInt32 getMaxCompressedDataSize(UInt32 uncompressed_size) const override;
|
2022-07-09 18:42:01 +00:00
|
|
|
std::unique_ptr<HardwareCodecDeflateQpl> hw_codec;
|
|
|
|
std::unique_ptr<SoftwareCodecDeflateQpl> sw_codec;
|
2022-04-26 18:14:09 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|