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-09 18:42:01 +00:00
/// DeflateQplJobHWPool is resource pool for provide the job objects which is required to save context infomation during offload asynchronous compression to IAA.
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
///Submit job request to the IAA hardware. 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
} ;
}