31 # pragma warning(disable : 4127)
50 #define LZ4_STATIC_LINKING_ONLY
52 #define LZ4_HC_STATIC_LINKING_ONLY
133 const char*
src,
char*
dst,
136 int const acceleration = (pThis->
cLevel < 0) ? -pThis->
cLevel + 1 : 1;
142 const char*
src,
char*
dst,
150 const char*
src,
char*
dst,
153 int const acceleration = (pThis->
cLevel < 0) ? -pThis->
cLevel + 1 : 1;
159 const char*
src,
char*
dst,
218 #define LZ4_isError(errcode) (errcode==0)
224 #ifndef LZ4_GIT_COMMIT_STRING
225 # define LZ4_GIT_COMMIT_STRING ""
227 # define LZ4_GIT_COMMIT_STRING LZ4_EXPAND_AND_QUOTE(LZ4_GIT_COMMIT)
231 #define TIMELOOP_MICROSEC 1*1000000ULL
232 #define TIMELOOP_NANOSEC 1*1000000000ULL
233 #define ACTIVEPERIOD_MICROSEC 70*1000000ULL
234 #define COOLPERIOD_SEC 10
235 #define DECOMP_MULT 1
241 #define LZ4_MAX_DICT_SIZE (64 KB)
251 #define DISPLAY(...) fprintf(stderr, __VA_ARGS__)
252 #define DISPLAYLEVEL(l, ...) if (g_displayLevel>=l) { DISPLAY(__VA_ARGS__); }
255 #define DISPLAYUPDATE(l, ...) if (g_displayLevel>=l) { \
256 if ((clock() - g_time > refreshRate) || (g_displayLevel>=4)) \
257 { g_time = clock(); DISPLAY(__VA_ARGS__); \
258 if (g_displayLevel>=4) fflush(stdout); } }
269 #define DEBUGOUTPUT(...) if (DEBUG) DISPLAY(__VA_ARGS__);
270 #define EXM_THROW(error, ...) \
272 DEBUGOUTPUT("Error defined at %s, line %i : \n", __FILE__, __LINE__); \
273 DISPLAYLEVEL(1, "Error %i : ", error); \
274 DISPLAYLEVEL(1, __VA_ARGS__); \
275 DISPLAYLEVEL(1, "\n"); \
316 #define MIN(a,b) ((a)<(b) ? (a) : (b))
317 #define MAX(a,b) ((a)>(b) ? (a) : (b))
320 const char* displayName,
int cLevel,
321 const size_t* fileSizes,
U32 nbFiles,
322 const char* dictBuf,
int dictSize)
325 U32 const maxNbBlocks = (
U32) ((
srcSize + (blockSize-1)) / blockSize) + nbFiles;
328 void*
const compressedBuffer =
malloc(maxCompressedSize);
334 if (!compressedBuffer || !resultBuffer || !blockTable)
335 EXM_THROW(31,
"allocation error : not enough memory");
337 if (strlen(displayName)>17) displayName += strlen(displayName)-17;
344 {
const char* srcPtr = (
const char*)srcBuffer;
345 char* cPtr = (
char*)compressedBuffer;
346 char* resPtr = (
char*)resultBuffer;
348 for (nbBlocks=0, fileNb=0; fileNb<nbFiles; fileNb++) {
349 size_t remaining = fileSizes[fileNb];
350 U32 const nbBlocksforThisFile = (
U32)((remaining + (blockSize-1)) / blockSize);
351 U32 const blockEnd = nbBlocks + nbBlocksforThisFile;
352 for ( ; nbBlocks<blockEnd; nbBlocks++) {
353 size_t const thisBlockSize =
MIN(remaining, blockSize);
354 blockTable[nbBlocks].
srcPtr = srcPtr;
355 blockTable[nbBlocks].
cPtr = cPtr;
356 blockTable[nbBlocks].
resPtr = resPtr;
357 blockTable[nbBlocks].
srcSize = thisBlockSize;
359 srcPtr += thisBlockSize;
360 cPtr += blockTable[nbBlocks].
cRoom;
361 resPtr += thisBlockSize;
362 remaining -= thisBlockSize;
366 RDG_genBuffer(compressedBuffer, maxCompressedSize, 0.10, 0.50, 1);
369 {
U64 fastestC = (
U64)(-1LL), fastestD = (
U64)(-1LL);
375 U64 totalCTime=0, totalDTime=0;
376 U32 cCompleted=0, dCompleted=0;
378 const char*
const marks[
NB_MARKS] = {
" |",
" /",
" =",
"\\" };
385 while (!cCompleted || !dCompleted) {
395 if (!cCompleted)
memset(compressedBuffer, 0xE5, maxCompressedSize);
403 for (nbLoops=0; nbLoops < nbCompressionLoops; nbLoops++) {
406 for (blockNb=0; blockNb<nbBlocks; blockNb++) {
409 blockTable[blockNb].
srcPtr, blockTable[blockNb].
cPtr,
410 (
int)blockTable[blockNb].
srcSize, (
int)blockTable[blockNb].cRoom);
412 blockTable[blockNb].
cSize = rSize;
416 if (clockSpan < fastestC * nbCompressionLoops)
417 fastestC = clockSpan / nbCompressionLoops;
421 assert(nbCompressionLoops < 40000000);
422 nbCompressionLoops *= 100;
424 totalCTime += clockSpan;
425 cCompleted = totalCTime>maxTime;
429 {
U32 blockNb;
for (blockNb=0; blockNb<nbBlocks; blockNb++) cSize += blockTable[blockNb].cSize; }
431 ratio = (double)
srcSize / (
double)cSize;
433 DISPLAYLEVEL(2,
"%2s-%-17.17s :%10u ->%10u (%5.3f),%6.1f MB/s\r",
435 ((
double)
srcSize / fastestC) * 1000 );
437 (void)fastestD; (void)crcOrig;
448 for (nbLoops=0; nbLoops < nbDecodeLoops; nbLoops++) {
450 for (blockNb=0; blockNb<nbBlocks; blockNb++) {
452 blockTable[blockNb].cPtr, blockTable[blockNb].resPtr,
453 (
int)blockTable[blockNb].cSize, (
int)blockTable[blockNb].
srcSize,
456 DISPLAY(
"LZ4_decompress_safe_usingDict() failed on block %u \n", blockNb);
463 if (clockSpan < fastestD * nbDecodeLoops)
464 fastestD = clockSpan / nbDecodeLoops;
468 assert(nbDecodeLoops < 40000000);
469 nbDecodeLoops *= 100;
471 totalDTime += clockSpan;
476 DISPLAYLEVEL(2,
"%2s-%-17.17s :%10u ->%10u (%5.3f),%6.1f MB/s ,%6.1f MB/s\r",
478 ((
double)
srcSize / fastestC) * 1000,
479 ((
double)
srcSize / fastestD) * 1000);
483 if (crcOrig!=crcCheck) {
485 DISPLAY(
"\n!!! WARNING !!! %17s : Invalid Checksum : %x != %x \n", displayName, (
unsigned)crcOrig, (
unsigned)crcCheck);
487 if (((
const BYTE*)srcBuffer)[u] != ((
const BYTE*)resultBuffer)[u]) {
491 for (segNb = 0; segNb < nbBlocks; segNb++) {
492 if (bacc + blockTable[segNb].
srcSize > u)
break;
493 bacc += blockTable[segNb].
srcSize;
496 bNb =
pos / (128
KB);
497 DISPLAY(
"(block %u, sub %u, pos %u) \n", segNb, bNb,
pos);
501 DISPLAY(
"no difference detected\n");
509 double const cSpeed = ((double)
srcSize / fastestC) * 1000;
510 double const dSpeed = ((double)
srcSize / fastestD) * 1000;
514 DISPLAY(
"-%-3i%11i (%5.3f) %6.2f MB/s %6.1f MB/s %s\n",
cLevel, (
int)cSize, ratio, cSpeed, dSpeed, displayName);
522 free(compressedBuffer);
533 requiredMem = (((requiredMem >> 26) + 1) << 26);
534 requiredMem += 2*
step;
538 if (requiredMem >
step) requiredMem -=
step;
539 else requiredMem >>= 1;
540 testmem = (
BYTE*)
malloc ((
size_t)requiredMem);
545 if (requiredMem >
step) requiredMem -=
step;
546 else requiredMem >>= 1;
548 return (
size_t)requiredMem;
553 const char* displayName,
int cLevel,
int cLevelLast,
554 const size_t* fileSizes,
unsigned nbFiles,
559 const char* pch = strrchr(displayName,
'\\');
560 if (!pch) pch = strrchr(displayName,
'/');
561 if (pch) displayName = pch+1;
570 for (l=
cLevel; l <= cLevelLast; l++) {
584 const char** fileNamesTable,
unsigned nbFiles)
586 size_t pos = 0, totalSize = 0;
588 for (
n=0;
n<nbFiles;
n++) {
592 DISPLAYLEVEL(2,
"Ignoring %s directory... \n", fileNamesTable[
n]);
596 f = fopen(fileNamesTable[
n],
"rb");
597 if (
f==
NULL)
EXM_THROW(10,
"impossible to open file %s", fileNamesTable[
n]);
599 if (fileSize > bufferSize-
pos) {
600 fileSize = bufferSize-
pos;
603 {
size_t const readSize = fread(((
char*)
buffer)+
pos, 1, (
size_t)fileSize,
f);
604 if (readSize != (
size_t)fileSize)
EXM_THROW(11,
"could not read %s", fileNamesTable[
n]);
606 fileSizes[
n] = (
size_t)fileSize;
607 totalSize += (
size_t)fileSize;
611 if (totalSize == 0)
EXM_THROW(12,
"no data to bench");
615 int cLevel,
int cLevelLast,
620 size_t* fileSizes = (
size_t*)
malloc(nbFiles *
sizeof(
size_t));
622 char mfName[20] = {0};
624 if (!fileSizes)
EXM_THROW(12,
"not enough memory for fileSizes");
628 if (benchedSize==0)
EXM_THROW(12,
"not enough memory");
629 if ((
U64)benchedSize > totalSizeToLoad) benchedSize = (
size_t)totalSizeToLoad;
632 DISPLAY(
"File(s) bigger than LZ4's max input size; testing %u MB only...\n", (
U32)(benchedSize >> 20));
634 if (benchedSize < totalSizeToLoad)
635 DISPLAY(
"Not enough memory; testing %u MB only...\n", (
U32)(benchedSize >> 20));
637 srcBuffer =
malloc(benchedSize + !benchedSize);
638 if (!srcBuffer)
EXM_THROW(12,
"not enough memory");
641 BMK_loadFiles(srcBuffer, benchedSize, fileSizes, fileNamesTable, nbFiles);
644 snprintf (mfName,
sizeof(mfName),
" %u files", nbFiles);
645 {
const char* displayName = (nbFiles > 1) ? mfName : fileNamesTable[0];
647 displayName,
cLevel, cLevelLast,
662 size_t benchedSize = 10000000;
663 void*
const srcBuffer =
malloc(benchedSize);
666 if (!srcBuffer)
EXM_THROW(21,
"not enough memory");
669 RDG_genBuffer(srcBuffer, benchedSize, compressibility, 0.0, 0);
672 snprintf (
name,
sizeof(
name),
"Synthetic %2u%%", (
unsigned)(compressibility*100));
681 int cLevel,
int cLevelLast,
690 for (fileNb=0; fileNb<nbFiles; fileNb++)
698 int cLevel,
int cLevelLast,
699 const char* dictFileName)
713 if (!dictFileSize)
EXM_THROW(25,
"Dictionary error : could not stat dictionary file");
715 dictFile = fopen(dictFileName,
"rb");
716 if (!dictFile)
EXM_THROW(25,
"Dictionary error : could not open dictionary file");
721 EXM_THROW(25,
"Dictionary error : could not seek dictionary file");
730 EXM_THROW(25,
"Dictionary error : could not read dictionary file");
static void LZ4_buildCompressionParameters(struct compressionParameters *pParams, int cLevel, const char *dictBuf, int dictSize)
static void LZ4_compressCleanupNoStream(const struct compressionParameters *pThis)
static void LZ4_compressResetNoStream(const struct compressionParameters *pThis)
#define LZ4_GIT_COMMIT_STRING
static U32 g_displayLevel
static void LZ4_compressCleanupStream(const struct compressionParameters *pThis)
#define EXM_THROW(error,...)
static void LZ4_compressCleanupStreamHC(const struct compressionParameters *pThis)
static void LZ4_compressResetStreamHC(const struct compressionParameters *pThis)
#define DISPLAYUPDATE(l,...)
static void LZ4_compressInitStream(struct compressionParameters *pThis)
int BMK_benchFiles(const char **fileNamesTable, unsigned nbFiles, int cLevel, int cLevelLast, const char *dictFileName)
static void BMK_loadFiles(void *buffer, size_t bufferSize, size_t *fileSizes, const char **fileNamesTable, unsigned nbFiles)
void BMK_setBlockSize(size_t blockSize)
static const size_t maxMemory
void BMK_setBenchSeparately(int separate)
static size_t BMK_findMaxMem(U64 requiredMem)
static size_t g_blockSize
void BMK_setNotificationLevel(unsigned level)
#define ACTIVEPERIOD_MICROSEC
#define LZ4_isError(errcode)
static U32 g_compressibilityDefault
#define DISPLAYLEVEL(l,...)
static int LZ4_compressBlockStream(const struct compressionParameters *pThis, const char *src, char *dst, int srcSize, int dstSize)
static int LZ4_compressBlockNoStream(const struct compressionParameters *pThis, const char *src, char *dst, int srcSize, int dstSize)
static void LZ4_compressResetStream(const struct compressionParameters *pThis)
static int LZ4_compressBlockStreamHC(const struct compressionParameters *pThis, const char *src, char *dst, int srcSize, int dstSize)
int BMK_benchFilesSeparately(const char **fileNamesTable, unsigned nbFiles, int cLevel, int cLevelLast, const char *dictBuf, int dictSize)
static void LZ4_compressInitNoStream(struct compressionParameters *pThis)
#define LZ4_MAX_DICT_SIZE
static int BMK_benchMem(const void *srcBuffer, size_t srcSize, const char *displayName, int cLevel, const size_t *fileSizes, U32 nbFiles, const char *dictBuf, int dictSize)
static void BMK_syntheticTest(int cLevel, int cLevelLast, double compressibility, const char *dictBuf, int dictSize)
void BMK_setNbSeconds(unsigned nbSeconds)
void BMK_setAdditionalParam(int additionalParam)
static void BMK_benchFileTable(const char **fileNamesTable, unsigned nbFiles, int cLevel, int cLevelLast, const char *dictBuf, int dictSize)
static const clock_t refreshRate
static int LZ4_compressBlockNoStreamHC(const struct compressionParameters *pThis, const char *src, char *dst, int srcSize, int dstSize)
static void LZ4_compressInitStreamHC(struct compressionParameters *pThis)
static void BMK_benchCLevel(void *srcBuffer, size_t benchedSize, const char *displayName, int cLevel, int cLevelLast, const size_t *fileSizes, unsigned nbFiles, const char *dictBuf, int dictSize)
void RDG_genBuffer(void *buffer, size_t size, double matchProba, double litProba, unsigned seed)
static states step(struct re_guts *, sopno, sopno, states, int, states)
RZ_API void Ht_() free(HtName_(Ht) *ht)
return memset(p, 0, total)
void * malloc(size_t size)
XXH_PUBLIC_API unsigned long long XXH64(const void *input, size_t len, unsigned long long seed)
UTIL_STATIC U32 UTIL_isDirectory(const char *infilename)
UTIL_STATIC UTIL_time_t UTIL_getTime(void)
UTIL_STATIC U64 UTIL_getTotalFileSize(const char **fileNamesTable, unsigned nbFiles)
UTIL_STATIC U64 UTIL_clockSpanMicro(UTIL_time_t clockStart)
#define UTIL_sleepMilli(milli)
UTIL_STATIC U64 UTIL_getFileSize(const char *infilename)
UTIL_STATIC void UTIL_waitForNextTick(void)
#define SET_REALTIME_PRIORITY
UTIL_STATIC U64 UTIL_clockSpanNano(UTIL_time_t clockStart)
int LZ4_compressBound(int isize)
int LZ4_loadDict(LZ4_stream_t *LZ4_dict, const char *dictionary, int dictSize)
LZ4_stream_t * LZ4_createStream(void)
int LZ4_decompress_safe_usingDict(const char *source, char *dest, int compressedSize, int maxOutputSize, const char *dictStart, int dictSize)
void LZ4_resetStream_fast(LZ4_stream_t *ctx)
int LZ4_freeStream(LZ4_stream_t *LZ4_stream)
int LZ4_compress_fast(const char *source, char *dest, int inputSize, int maxOutputSize, int acceleration)
int LZ4_compress_fast_continue(LZ4_stream_t *LZ4_stream, const char *source, char *dest, int inputSize, int maxOutputSize, int acceleration)
void LZ4_attach_dictionary(LZ4_stream_t *workingStream, const LZ4_stream_t *dictionaryStream)
#define LZ4_VERSION_STRING
#define LZ4_MAX_INPUT_SIZE
void LZ4_attach_HC_dictionary(LZ4_streamHC_t *working_stream, const LZ4_streamHC_t *dictionary_stream)
void LZ4_resetStreamHC_fast(LZ4_streamHC_t *LZ4_streamHCPtr, int compressionLevel)
int LZ4_freeStreamHC(LZ4_streamHC_t *LZ4_streamHCPtr)
int LZ4_compress_HC_continue(LZ4_streamHC_t *LZ4_streamHCPtr, const char *src, char *dst, int srcSize, int dstCapacity)
int LZ4_compress_HC(const char *src, char *dst, int srcSize, int dstCapacity, int compressionLevel)
LZ4_streamHC_t * LZ4_createStreamHC(void)
int LZ4_loadDictHC(LZ4_streamHC_t *LZ4_streamHCPtr, const char *dictionary, int dictSize)
assert(limit<=UINT32_MAX/2)
int(* blockFunction)(const struct compressionParameters *pThis, const char *src, char *dst, int srcSize, int dstSize)
LZ4_streamHC_t * LZ4_streamHC
LZ4_stream_t * LZ4_dictStream
LZ4_streamHC_t * LZ4_dictStreamHC
void(* resetFunction)(const struct compressionParameters *pThis)
LZ4_stream_t * LZ4_stream
void(* initFunction)(struct compressionParameters *pThis)
void(* cleanupFunction)(const struct compressionParameters *pThis)
Miscellaneous utility functions.