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 ( ) ;
~ DeflateQplJobHWPool ( ) ;
2022-04-26 18:14:09 +00:00
2022-07-09 18:57:38 +00:00
qpl_job * acquireJob ( uint32_t * job_id ) ;
2022-07-11 16:08:35 +00:00
static qpl_job * releaseJob ( uint32_t job_id ) ;
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-07-11 16:08:35 +00:00
static constexpr auto MAX_HW_JOB_NUMBER = 1024 ;
2022-04-26 18:14:09 +00:00
private :
2022-07-11 16:08:35 +00:00
static bool tryLockJob ( size_t index ) ;
2022-04-26 18:14:09 +00:00
2022-07-11 16:08:35 +00:00
static void unLockJob ( uint32_t index ) { hw_job_ptr_locks [ index ] . store ( false ) ; }
2022-07-08 16:09:58 +00:00
2022-07-07 21:13:20 +00:00
class ReleaseJobObjectGuard
2022-04-26 18:14:09 +00:00
{
uint32_t index ;
ReleaseJobObjectGuard ( ) = delete ;
public :
2022-07-09 18:57:38 +00:00
ReleaseJobObjectGuard ( const uint32_t index_ ) : index ( index_ ) { }
2022-07-09 21:17:18 +00:00
~ ReleaseJobObjectGuard ( ) { hw_job_ptr_locks [ index ] . store ( false ) ; }
2022-04-26 18:14:09 +00:00
} ;
2022-07-09 18:57:38 +00:00
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-06-08 15:47:44 +00:00
uint32_t doCompressData ( const char * source , uint32_t source_size , char * dest , uint32_t dest_size ) ;
void doDecompressData ( const char * source , uint32_t source_size , char * dest , uint32_t uncompressed_size ) ;
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.
static constexpr int32_t RET_ERROR = - 1 ;
2022-07-09 18:42:01 +00:00
HardwareCodecDeflateQpl ( ) ;
~ HardwareCodecDeflateQpl ( ) ;
2022-07-09 15:12:41 +00:00
int32_t doCompressData ( const char * source , uint32_t source_size , char * dest , uint32_t dest_size ) const ;
2022-07-11 16:08:35 +00:00
int32_t doDecompressDataAsynchronous ( const char * source , uint32_t source_size , char * dest , uint32_t uncompressed_size ) ;
2022-07-09 17:54:23 +00:00
/// Flush result for previous asynchronous decompression requests.Must be used following with 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-08 16:20:24 +00:00
std : : map < uint32_t , 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-04-26 18:14:09 +00:00
uint32_t doCompressData ( const char * source , uint32_t source_size , char * dest ) const override ;
void doDecompressData ( const char * source , uint32_t source_size , char * dest , uint32_t 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 :
uint32_t getMaxCompressedDataSize ( uint32_t 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
} ;
}