diff options
author | Yaniv Kaul <ykaul@redhat.com> | 2018-07-21 12:05:30 +0300 |
---|---|---|
committer | Kotresh HR <khiremat@redhat.com> | 2018-08-16 04:06:13 +0000 |
commit | 4fe662be4143629e405b1718836be6c990fcebbb (patch) | |
tree | 0f6268b4b9b84c92f8b648fe2fa54ffafb32d9d9 /contrib/xxhash/xxhsum.c | |
parent | 4d1ea415f5346b24c13810aab18a24256fb2b41a (diff) |
contrib/xxhash: update to latest xxHash (0.6.5)
Update to latest xxHash, which is supposed to faster with small keys.
Specifically, updated to 3064d42e7d74b0921bdd1818395d9cb37bb8976a,
which is a bit higher than 0.6.5.
Compiled hopefully with namespace (XXH_NAMESPACE=GF_),
which allows to use XXH() funcs with no fear they'll 'leak'
from our library.
Only compile tested!
xxhsum is modified to display messages which was conflicting
with regression tests (TAP harness). So modified the
gfid2path_fuse.t and gfid2path_nfs.t to adhere to that.
updates: bz#1193929
Signed-off-by: Yaniv Kaul <ykaul@redhat.com>
Change-Id: I35cea5cc93f338c1023ac2c9bc6d7d13225a967b
Diffstat (limited to 'contrib/xxhash/xxhsum.c')
-rw-r--r-- | contrib/xxhash/xxhsum.c | 353 |
1 files changed, 208 insertions, 145 deletions
diff --git a/contrib/xxhash/xxhsum.c b/contrib/xxhash/xxhsum.c index 6cb54386093..69931f727f0 100644 --- a/contrib/xxhash/xxhsum.c +++ b/contrib/xxhash/xxhsum.c @@ -32,8 +32,8 @@ #define XXHASH_C_2097394837 /* ************************************ -* Compiler Options -**************************************/ + * Compiler Options + **************************************/ /* MS Visual */ #if defined(_MSC_VER) || defined(_WIN32) # define _CRT_SECURE_NO_WARNINGS /* removes visual warnings */ @@ -46,28 +46,26 @@ /* ************************************ -* Includes -**************************************/ -#include <stdlib.h> /* malloc */ -#include <stdio.h> /* fprintf, fopen, ftello64, fread, stdin, stdout; when present : _fileno */ + * Includes + **************************************/ +#include <stdlib.h> /* malloc, calloc, free, exit */ +#include <stdio.h> /* fprintf, fopen, ftello64, fread, stdin, stdout, _fileno (when present) */ #include <string.h> /* strcmp */ -#include <sys/types.h> /* stat64 */ -#include <sys/stat.h> /* stat64 */ +#include <sys/types.h> /* stat, stat64, _stat64 */ +#include <sys/stat.h> /* stat, stat64, _stat64 */ #include <time.h> /* clock_t, clock, CLOCKS_PER_SEC */ +#include <assert.h> /* assert */ #define XXH_STATIC_LINKING_ONLY /* *_state_t */ #include "xxhash.h" -/*-************************************ -* OS-Specific Includes -**************************************/ +/* ************************************ + * OS-Specific Includes + **************************************/ #if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) # include <fcntl.h> /* _O_BINARY */ # include <io.h> /* _setmode, _isatty */ -# ifdef __MINGW32__ - int _fileno(FILE *stream); /* MINGW somehow forgets to include this windows declaration into <stdio.h> */ -# endif # define SET_BINARY_MODE(file) _setmode(_fileno(file), _O_BINARY) # define IS_CONSOLE(stdStream) _isatty(_fileno(stdStream)) #else @@ -110,8 +108,8 @@ static unsigned BMK_isLittleEndian(void) /* ************************************* -* Constants -***************************************/ + * Constants + ***************************************/ #define LIB_VERSION XXH_VERSION_MAJOR.XXH_VERSION_MINOR.XXH_VERSION_RELEASE #define QUOTE(str) #str #define EXPAND_AND_QUOTE(str) QUOTE(str) @@ -121,18 +119,20 @@ static const char g_lename[] = "little endian"; static const char g_bename[] = "big endian"; #define ENDIAN_NAME (BMK_isLittleEndian() ? g_lename : g_bename) static const char author[] = "Yann Collet"; -#define WELCOME_MESSAGE(exename) "%s %s (%i-bits %s), by %s \n", exename, PROGRAM_VERSION, g_nbBits, ENDIAN_NAME, author +#define WELCOME_MESSAGE(exename) "%s %s (%i-bits %s), by %s \n", \ + exename, PROGRAM_VERSION, g_nbBits, ENDIAN_NAME, author + +#define KB *( 1<<10) +#define MB *( 1<<20) +#define GB *(1U<<30) +static size_t XXH_DEFAULT_SAMPLE_SIZE = 100 KB; #define NBLOOPS 3 /* Default number of benchmark iterations */ #define TIMELOOP_S 1 #define TIMELOOP (TIMELOOP_S * CLOCKS_PER_SEC) /* Minimum timing per iteration */ #define XXHSUM32_DEFAULT_SEED 0 /* Default seed for algo_xxh32 */ #define XXHSUM64_DEFAULT_SEED 0 /* Default seed for algo_xxh64 */ -#define KB *( 1<<10) -#define MB *( 1<<20) -#define GB *(1U<<30) - #define MAX_MEM (2 GB - 64 MB) static const char stdinName[] = "-"; @@ -141,31 +141,30 @@ static const algoType g_defaultAlgo = algo_xxh64; /* required within main() & /* <16 hex char> <SPC> <SPC> <filename> <'\0'> * '4096' is typical Linux PATH_MAX configuration. */ -#define DEFAULT_LINE_LENGTH (sizeof(GF_XXH64_hash_t) * 2 + 2 + 4096 + 1) +#define DEFAULT_LINE_LENGTH (sizeof(XXH64_hash_t) * 2 + 2 + 4096 + 1) /* Maximum acceptable line length. */ #define MAX_LINE_LENGTH (32 KB) /* ************************************ -* Display macros -**************************************/ -#define DISPLAY(...) /*fprintf(stderr, __VA_ARGS__)*/ + * Display macros + **************************************/ +#define DISPLAY(...) fprintf(stderr, __VA_ARGS__) #define DISPLAYRESULT(...) fprintf(stdout, __VA_ARGS__) -#define DISPLAYLEVEL(l, ...) /*if (g_displayLevel>=l) DISPLAY(__VA_ARGS__);*/ -static U32 g_displayLevel = 1; +#define DISPLAYLEVEL(l, ...) do { if (g_displayLevel>=l) DISPLAY(__VA_ARGS__); } while (0) +static int g_displayLevel = 2; /* ************************************ -* Local variables -**************************************/ -static size_t g_sampleSize = 100 KB; + * Local variables + **************************************/ static U32 g_nbIterations = NBLOOPS; /* ************************************ -* Benchmark Functions -**************************************/ + * Benchmark Functions + **************************************/ static clock_t BMK_clockSpan( clock_t start ) { return clock() - start; /* works even if overflow; Typical max span ~ 30 mn */ @@ -212,59 +211,80 @@ static U64 BMK_GetFileSize(const char* infilename) typedef U32 (*hashFunction)(const void* buffer, size_t bufferSize, U32 seed); -static U32 localXXH32(const void* buffer, size_t bufferSize, U32 seed) { return GF_XXH32(buffer, bufferSize, seed); } +static U32 localXXH32(const void* buffer, size_t bufferSize, U32 seed) { return XXH32(buffer, bufferSize, seed); } -static U32 localXXH64(const void* buffer, size_t bufferSize, U32 seed) { return (U32)GF_XXH64(buffer, bufferSize, seed); } +static U32 localXXH64(const void* buffer, size_t bufferSize, U32 seed) { return (U32)XXH64(buffer, bufferSize, seed); } static void BMK_benchHash(hashFunction h, const char* hName, const void* buffer, size_t bufferSize) { - static const U32 nbh_perloop = 100; + U32 nbh_perIteration = ((300 MB) / (bufferSize+1)) + 1; /* first loop conservatively aims for 300 MB/s */ U32 iterationNb; double fastestH = 100000000.; - DISPLAY("\r%79s\r", ""); /* Clean display line */ + DISPLAYLEVEL(2, "\r%70s\r", ""); /* Clean display line */ if (g_nbIterations<1) g_nbIterations=1; for (iterationNb = 1; iterationNb <= g_nbIterations; iterationNb++) { - U32 nbHashes = 0, r=0; + U32 r=0; clock_t cStart; - DISPLAY("%1i-%-17.17s : %10u ->\r", iterationNb, hName, (U32)bufferSize); + DISPLAYLEVEL(2, "%1i-%-17.17s : %10u ->\r", iterationNb, hName, (U32)bufferSize); cStart = clock(); while (clock() == cStart); /* starts clock() at its exact beginning */ cStart = clock(); - while (BMK_clockSpan(cStart) < TIMELOOP) { - U32 i; - for (i=0; i<nbh_perloop; i++) + { U32 i; + for (i=0; i<nbh_perIteration; i++) r += h(buffer, bufferSize, i); - nbHashes += nbh_perloop; } - if (r==0) DISPLAY(".\r"); /* need to do something with r to avoid compiler optimizing away the hash function */ - { double const timeS = ((double)BMK_clockSpan(cStart) / CLOCKS_PER_SEC) / nbHashes; + if (r==0) DISPLAYLEVEL(3,".\r"); /* do something with r to avoid compiler "optimizing" away hash function */ + { double const timeS = ((double)BMK_clockSpan(cStart) / CLOCKS_PER_SEC) / nbh_perIteration; if (timeS < fastestH) fastestH = timeS; - DISPLAY("%1i-%-17.17s : %10u -> %7.1f MB/s\r", iterationNb, hName, (U32)bufferSize, ((double)bufferSize / (1<<20)) / fastestH ); + DISPLAYLEVEL(2, "%1i-%-17.17s : %10u -> %8.0f it/s (%7.1f MB/s) \r", + iterationNb, hName, (U32)bufferSize, + (double)1 / fastestH, + ((double)bufferSize / (1<<20)) / fastestH ); } + assert(fastestH > 1./2000000000); /* avoid U32 overflow */ + nbh_perIteration = (U32)(1 / fastestH) + 1; /* adjust nbh_perIteration to last roughtly one second */ } - DISPLAY("%-19.19s : %10u -> %7.1f MB/s \n", hName, (U32)bufferSize, ((double)bufferSize / (1<<20)) / fastestH); + DISPLAYLEVEL(1, "%-19.19s : %10u -> %8.0f it/s (%7.1f MB/s) \n", hName, (U32)bufferSize, + (double)1 / fastestH, + ((double)bufferSize / (1<<20)) / fastestH); + if (g_displayLevel<1) + DISPLAYLEVEL(0, "%u, ", (U32)((double)1 / fastestH)); } -/* Note : buffer is supposed malloc'ed, hence aligned */ -static void BMK_benchMem(const void* buffer, size_t bufferSize) +/* BMK_benchMem(): + * specificTest : 0 == run all tests, 1+ run only specific test + * buffer : is supposed 8-bytes aligned (if malloc'ed, it should be) + * the real allocated size of buffer is supposed to be >= (bufferSize+3). + * @return : 0 on success, 1 if error (invalid mode selected) */ +static int BMK_benchMem(const void* buffer, size_t bufferSize, U32 specificTest) { + assert((((size_t)buffer) & 8) == 0); /* ensure alignment */ + /* XXH32 bench */ - BMK_benchHash(localXXH32, "XXH32", buffer, bufferSize); + if ((specificTest==0) | (specificTest==1)) + BMK_benchHash(localXXH32, "XXH32", buffer, bufferSize); /* Bench XXH32 on Unaligned input */ - if (bufferSize>1) - BMK_benchHash(localXXH32, "XXH32 unaligned", ((const char*)buffer)+1, bufferSize-1); + if ((specificTest==0) | (specificTest==2)) + BMK_benchHash(localXXH32, "XXH32 unaligned", ((const char*)buffer)+1, bufferSize); /* Bench XXH64 */ - BMK_benchHash(localXXH64, "XXH64", buffer, bufferSize); + if ((specificTest==0) | (specificTest==3)) + BMK_benchHash(localXXH64, "XXH64", buffer, bufferSize); /* Bench XXH64 on Unaligned input */ - if (bufferSize>1) - BMK_benchHash(localXXH64, "XXH64 unaligned", ((const char*)buffer)+1, bufferSize-1); + if ((specificTest==0) | (specificTest==4)) + BMK_benchHash(localXXH64, "XXH64 unaligned", ((const char*)buffer)+3, bufferSize); + + if (specificTest > 4) { + DISPLAY("benchmark mode invalid \n"); + return 1; + } + return 0; } @@ -279,19 +299,21 @@ static size_t BMK_selectBenchedSize(const char* fileName) } -static int BMK_benchFiles(const char** fileNamesTable, int nbFiles) +static int BMK_benchFiles(const char** fileNamesTable, int nbFiles, U32 specificTest) { + int result = 0; int fileIdx; + for (fileIdx=0; fileIdx<nbFiles; fileIdx++) { const char* const inFileName = fileNamesTable[fileIdx]; FILE* const inFile = fopen( inFileName, "rb" ); size_t const benchedSize = BMK_selectBenchedSize(inFileName); - char* const buffer = (char*)malloc(benchedSize+16); - void* const alignedBuffer = (buffer+15) - (((size_t)(buffer+15)) & 0xF); /* align on next 16 bytes boundaries */ + char* const buffer = (char*)calloc(benchedSize+16+3, 1); + void* const alignedBuffer = (buffer+15) - (((size_t)(buffer+15)) & 0xF); /* align on next 16 bytes */ /* Checks */ if ((inFile==NULL) || (inFileName==NULL)) { - DISPLAY( "Pb opening %s\n", inFileName); + DISPLAY("Pb opening %s\n", inFileName); free(buffer); return 11; } @@ -302,7 +324,7 @@ static int BMK_benchFiles(const char** fileNamesTable, int nbFiles) } /* Fill input buffer */ - DISPLAY("\nLoading %s... \n", inFileName); + DISPLAYLEVEL(1, "\rLoading %s... \n", inFileName); { size_t const readSize = fread(alignedBuffer, 1, benchedSize, inFile); fclose(inFile); if(readSize != benchedSize) { @@ -312,39 +334,47 @@ static int BMK_benchFiles(const char** fileNamesTable, int nbFiles) } } /* bench */ - BMK_benchMem(alignedBuffer, benchedSize); + result |= BMK_benchMem(alignedBuffer, benchedSize, specificTest); free(buffer); } - return 0; + return result; } -static int BMK_benchInternal(void) +static int BMK_benchInternal(size_t keySize, int specificTest) { - size_t const benchedSize = g_sampleSize; - void* const buffer = malloc(benchedSize); + void* const buffer = calloc(keySize+16+3, 1); + void* const alignedBuffer = ((char*)buffer+15) - (((size_t)((char*)buffer+15)) & 0xF); /* align on next 16 bytes */ if(!buffer) { DISPLAY("\nError: not enough memory!\n"); return 12; } /* bench */ - DISPLAY("\rSample of %u KB... \n", (U32)(benchedSize >> 10)); - BMK_benchMem(buffer, benchedSize); + DISPLAYLEVEL(1, "Sample of "); + if (keySize > 10 KB) { + DISPLAYLEVEL(1, "%u KB", (U32)(keySize >> 10)); + } else { + DISPLAYLEVEL(1, "%u bytes", (U32)keySize); + } + DISPLAYLEVEL(1, "... \n"); - free(buffer); - return 0; + { int const result = BMK_benchMem(alignedBuffer, keySize, specificTest); + free(buffer); + return result; + } } static void BMK_checkResult(U32 r1, U32 r2) { static int nbTests = 1; - if (r1==r2) DISPLAY("\rTest%3i : %08X == %08X ok ", nbTests, r1, r2); - else { + if (r1==r2) { + DISPLAYLEVEL(3, "\rTest%3i : %08X == %08X ok ", nbTests, r1, r2); + } else { DISPLAY("\rERROR : Test%3i : %08X <> %08X !!!!! \n", nbTests, r1, r2); exit(1); } @@ -356,7 +386,7 @@ static void BMK_checkResult64(U64 r1, U64 r2) { static int nbTests = 1; if (r1!=r2) { - DISPLAY("\rERROR : Test%3i : 64-bits values non equals !!!!! \n", nbTests); + DISPLAY("\rERROR : Test%3i : 64-bit values non equals !!!!! \n", nbTests); DISPLAY("\r %08X%08X != %08X%08X \n", (U32)(r1>>32), (U32)r1, (U32)(r2>>32), (U32)r2); exit(1); } @@ -366,42 +396,44 @@ static void BMK_checkResult64(U64 r1, U64 r2) static void BMK_testSequence64(void* sentence, size_t len, U64 seed, U64 Nresult) { - GF_XXH64_state_t state; + XXH64_state_t state; U64 Dresult; size_t pos; - Dresult = GF_XXH64(sentence, len, seed); + Dresult = XXH64(sentence, len, seed); BMK_checkResult64(Dresult, Nresult); - GF_XXH64_reset(&state, seed); - GF_XXH64_update(&state, sentence, len); - Dresult = GF_XXH64_digest(&state); + XXH64_reset(&state, seed); + XXH64_update(&state, sentence, len); + Dresult = XXH64_digest(&state); BMK_checkResult64(Dresult, Nresult); - GF_XXH64_reset(&state, seed); - for (pos=0; pos<len; pos++) GF_XXH64_update(&state, ((char*)sentence)+pos, 1); - Dresult = GF_XXH64_digest(&state); + XXH64_reset(&state, seed); + for (pos=0; pos<len; pos++) + XXH64_update(&state, ((char*)sentence)+pos, 1); + Dresult = XXH64_digest(&state); BMK_checkResult64(Dresult, Nresult); } static void BMK_testSequence(const void* sequence, size_t len, U32 seed, U32 Nresult) { - GF_XXH32_state_t state; + XXH32_state_t state; U32 Dresult; size_t pos; - Dresult = GF_XXH32(sequence, len, seed); + Dresult = XXH32(sequence, len, seed); BMK_checkResult(Dresult, Nresult); - GF_XXH32_reset(&state, seed); - GF_XXH32_update(&state, sequence, len); - Dresult = GF_XXH32_digest(&state); + XXH32_reset(&state, seed); + XXH32_update(&state, sequence, len); + Dresult = XXH32_digest(&state); BMK_checkResult(Dresult, Nresult); - GF_XXH32_reset(&state, seed); - for (pos=0; pos<len; pos++) GF_XXH32_update(&state, ((const char*)sequence)+pos, 1); - Dresult = GF_XXH32_digest(&state); + XXH32_reset(&state, seed); + for (pos=0; pos<len; pos++) + XXH32_update(&state, ((const char*)sequence)+pos, 1); + Dresult = XXH32_digest(&state); BMK_checkResult(Dresult, Nresult); } @@ -437,8 +469,8 @@ static void BMK_sanityCheck(void) BMK_testSequence64(sanityBuffer, SANITY_BUFFER_SIZE, 0, 0x0EAB543384F878ADULL); BMK_testSequence64(sanityBuffer, SANITY_BUFFER_SIZE, prime, 0xCAA65939306F1E21ULL); - DISPLAY("\r%79s\r", ""); /* Clean display line */ - DISPLAYLEVEL(2, "Sanity check -- all tests ok\n"); + DISPLAYLEVEL(3, "\r%70s\r", ""); /* Clean display line */ + DISPLAYLEVEL(3, "Sanity check -- all tests ok\n"); } @@ -464,13 +496,13 @@ static void BMK_display_BigEndian(const void* ptr, size_t length) static void BMK_hashStream(void* xxhHashValue, const algoType hashType, FILE* inFile, void* buffer, size_t blockSize) { - GF_XXH64_state_t state64; - GF_XXH32_state_t state32; + XXH64_state_t state64; + XXH32_state_t state32; size_t readSize; /* Init */ - GF_XXH32_reset(&state32, XXHSUM32_DEFAULT_SEED); - GF_XXH64_reset(&state64, XXHSUM64_DEFAULT_SEED); + XXH32_reset(&state32, XXHSUM32_DEFAULT_SEED); + XXH64_reset(&state64, XXHSUM64_DEFAULT_SEED); /* Load file & update hash */ readSize = 1; @@ -479,10 +511,10 @@ static void BMK_hashStream(void* xxhHashValue, const algoType hashType, FILE* in switch(hashType) { case algo_xxh32: - GF_XXH32_update(&state32, buffer, readSize); + XXH32_update(&state32, buffer, readSize); break; case algo_xxh64: - GF_XXH64_update(&state64, buffer, readSize); + XXH64_update(&state64, buffer, readSize); break; default: break; @@ -492,12 +524,12 @@ static void BMK_hashStream(void* xxhHashValue, const algoType hashType, FILE* in switch(hashType) { case algo_xxh32: - { U32 const h32 = GF_XXH32_digest(&state32); + { U32 const h32 = XXH32_digest(&state32); memcpy(xxhHashValue, &h32, sizeof(h32)); break; } case algo_xxh64: - { U64 const h64 = GF_XXH64_digest(&state64); + { U64 const h64 = XXH64_digest(&state64); memcpy(xxhHashValue, &h64, sizeof(h64)); break; } @@ -542,45 +574,46 @@ static int BMK_hash(const char* fileName, /* loading notification */ { const size_t fileNameSize = strlen(fileName); const char* const fileNameEnd = fileName + fileNameSize; - const size_t maxInfoFilenameSize = fileNameSize > 30 ? 30 : fileNameSize; - size_t infoFilenameSize = 1; - while ( (infoFilenameSize < maxInfoFilenameSize) - &&(fileNameEnd[-1-infoFilenameSize] != '/') - &&(fileNameEnd[-1-infoFilenameSize] != '\\') ) + const int maxInfoFilenameSize = (int)(fileNameSize > 30 ? 30 : fileNameSize); + int infoFilenameSize = 1; + while ((infoFilenameSize < maxInfoFilenameSize) + && (fileNameEnd[-1-infoFilenameSize] != '/') + && (fileNameEnd[-1-infoFilenameSize] != '\\') ) infoFilenameSize++; - DISPLAY("\nLoading %s... \n", fileNameEnd - infoFilenameSize); - } + DISPLAY("\rLoading %s... \r", fileNameEnd - infoFilenameSize); - /* Load file & update hash */ - switch(hashType) - { - case algo_xxh32: - BMK_hashStream(&h32, algo_xxh32, inFile, buffer, blockSize); - break; - case algo_xxh64: - BMK_hashStream(&h64, algo_xxh64, inFile, buffer, blockSize); - break; - default: - break; - } + /* Load file & update hash */ + switch(hashType) + { + case algo_xxh32: + BMK_hashStream(&h32, algo_xxh32, inFile, buffer, blockSize); + break; + case algo_xxh64: + BMK_hashStream(&h64, algo_xxh64, inFile, buffer, blockSize); + break; + default: + break; + } - fclose(inFile); - free(buffer); + fclose(inFile); + free(buffer); + DISPLAY("%s \r", fileNameEnd - infoFilenameSize); /* erase line */ + } /* display Hash */ switch(hashType) { case algo_xxh32: - { GF_XXH32_canonical_t hcbe32; - GF_XXH32_canonicalFromHash(&hcbe32, h32); + { XXH32_canonical_t hcbe32; + XXH32_canonicalFromHash(&hcbe32, h32); displayEndianess==big_endian ? BMK_display_BigEndian(&hcbe32, sizeof(hcbe32)) : BMK_display_LittleEndian(&hcbe32, sizeof(hcbe32)); DISPLAYRESULT(" %s\n", fileName); break; } case algo_xxh64: - { GF_XXH64_canonical_t hcbe64; - GF_XXH64_canonicalFromHash(&hcbe64, h64); + { XXH64_canonical_t hcbe64; + XXH64_canonicalFromHash(&hcbe64, h64); displayEndianess==big_endian ? BMK_display_BigEndian(&hcbe64, sizeof(hcbe64)) : BMK_display_LittleEndian(&hcbe64, sizeof(hcbe64)); DISPLAYRESULT(" %s\n", fileName); @@ -634,8 +667,8 @@ typedef enum { } LineStatus; typedef union { - GF_XXH32_canonical_t xxh32; - GF_XXH64_canonical_t xxh64; + XXH32_canonical_t xxh32; + XXH64_canonical_t xxh64; } Canonical; typedef struct { @@ -680,10 +713,12 @@ static GetLineResult getLine(char** lineBuf, int* lineMax, FILE* inFile) GetLineResult result = GetLine_ok; int len = 0; - if (*lineBuf == NULL || *lineMax < 1) { - *lineMax = DEFAULT_LINE_LENGTH; - *lineBuf = (char*) realloc(*lineBuf, *lineMax); + if ((*lineBuf == NULL) || (*lineMax<1)) { + free(*lineBuf); /* in case it's != NULL */ + *lineMax = 0; + *lineBuf = (char*)malloc(DEFAULT_LINE_LENGTH); if(*lineBuf == NULL) return GetLine_outOfMemory; + *lineMax = DEFAULT_LINE_LENGTH; } for (;;) { @@ -788,7 +823,7 @@ static ParseLineResult parseLine(ParsedLine* parsedLine, const char* line) switch (firstSpace - line) { case 8: - { GF_XXH32_canonical_t* xxh32c = &parsedLine->canonical.xxh32; + { XXH32_canonical_t* xxh32c = &parsedLine->canonical.xxh32; if (canonicalFromString(xxh32c->digest, sizeof(xxh32c->digest), line) != CanonicalFromString_ok) { return ParseLine_invalidFormat; @@ -798,7 +833,7 @@ static ParseLineResult parseLine(ParsedLine* parsedLine, const char* line) } case 16: - { GF_XXH64_canonical_t* xxh64c = &parsedLine->canonical.xxh64; + { XXH64_canonical_t* xxh64c = &parsedLine->canonical.xxh64; if (canonicalFromString(xxh64c->digest, sizeof(xxh64c->digest), line) != CanonicalFromString_ok) { return ParseLine_invalidFormat; @@ -905,17 +940,17 @@ static void parseFile1(ParseFileArg* parseFileArg) switch (parsedLine.xxhBits) { case 32: - { GF_XXH32_hash_t xxh; + { XXH32_hash_t xxh; BMK_hashStream(&xxh, algo_xxh32, fp, parseFileArg->blockBuf, parseFileArg->blockSize); - if (xxh == GF_XXH32_hashFromCanonical(&parsedLine.canonical.xxh32)) { + if (xxh == XXH32_hashFromCanonical(&parsedLine.canonical.xxh32)) { lineStatus = LineStatus_hashOk; } } break; case 64: - { GF_XXH64_hash_t xxh; + { XXH64_hash_t xxh; BMK_hashStream(&xxh, algo_xxh64, fp, parseFileArg->blockBuf, parseFileArg->blockSize); - if (xxh == GF_XXH64_hashFromCanonical(&parsedLine.canonical.xxh64)) { + if (xxh == XXH64_hashFromCanonical(&parsedLine.canonical.xxh64)) { lineStatus = LineStatus_hashOk; } } break; @@ -1122,10 +1157,30 @@ static int badusage(const char* exename) return 1; } +/*! readU32FromChar() : + @return : unsigned integer value read from input in `char` format, + 0 is no figure at *stringPtr position. + Interprets K, KB, KiB, M, MB and MiB suffix. + Modifies `*stringPtr`, advancing it to position where reading stopped. + Note : function result can overflow if digit string > MAX_UINT */ +static unsigned readU32FromChar(const char** stringPtr) +{ + unsigned result = 0; + while ((**stringPtr >='0') && (**stringPtr <='9')) + result *= 10, result += **stringPtr - '0', (*stringPtr)++ ; + if ((**stringPtr=='K') || (**stringPtr=='M')) { + result <<= 10; + if (**stringPtr=='M') result <<= 10; + (*stringPtr)++ ; + if (**stringPtr=='i') (*stringPtr)++; + if (**stringPtr=='B') (*stringPtr)++; + } + return result; +} int main(int argc, const char** argv) { - int i, filenamesStart=0; + int i, filenamesStart = 0; const char* const exename = argv[0]; U32 benchmarkMode = 0; U32 fileCheckMode = 0; @@ -1133,7 +1188,9 @@ int main(int argc, const char** argv) U32 statusOnly = 0; U32 warn = 0; U32 quiet = 0; - algoType algo = g_defaultAlgo; + U32 specificTest = 0; + size_t keySize = XXH_DEFAULT_SAMPLE_SIZE; + algoType algo = g_defaultAlgo; endianess displayEndianess = big_endian; /* special case : xxh32sum default to 32 bits checksum */ @@ -1193,21 +1250,26 @@ int main(int argc, const char** argv) /* Trigger benchmark mode */ case 'b': argument++; - benchmarkMode=1; + benchmarkMode = 1; + specificTest = readU32FromChar(&argument); /* select one specific test (hidden option) */ break; /* Modify Nb Iterations (benchmark only) */ case 'i': - g_nbIterations = argument[1] - '0'; - argument+=2; + argument++; + g_nbIterations = readU32FromChar(&argument); break; /* Modify Block size (benchmark only) */ case 'B': argument++; - g_sampleSize = 0; - while (argument[0]>='0' && argument[0]<='9') - g_sampleSize *= 10, g_sampleSize += argument[0]-'0', argument++; + keySize = readU32FromChar(&argument); + break; + + /* Modify verbosity of benchmark output (hidden option) */ + case 'q': + argument++; + g_displayLevel--; break; default: @@ -1218,10 +1280,10 @@ int main(int argc, const char** argv) /* Check benchmark mode */ if (benchmarkMode) { - DISPLAY( WELCOME_MESSAGE(exename) ); + DISPLAYLEVEL(2, WELCOME_MESSAGE(exename) ); BMK_sanityCheck(); - if (filenamesStart==0) return BMK_benchInternal(); - return BMK_benchFiles(argv+filenamesStart, argc-filenamesStart); + if (filenamesStart==0) return BMK_benchInternal(keySize, specificTest); + return BMK_benchFiles(argv+filenamesStart, argc-filenamesStart, specificTest); } /* Check if input is defined as console; trigger an error in this case */ @@ -1229,7 +1291,8 @@ int main(int argc, const char** argv) if (filenamesStart==0) filenamesStart = argc; if (fileCheckMode) { - return checkFiles(argv+filenamesStart, argc-filenamesStart, displayEndianess, strictMode, statusOnly, warn, quiet); + return checkFiles(argv+filenamesStart, argc-filenamesStart, + displayEndianess, strictMode, statusOnly, warn, quiet); } else { return BMK_hashFiles(argv+filenamesStart, argc-filenamesStart, algo, displayEndianess); } |