make XXH3_state_t movable

also fix XXH3_copyState()
when copying a state initialized with a seed.

fix #365
This commit is contained in:
Yann Collet 2020-05-20 10:45:27 -07:00
parent d8bed9a54d
commit a97e8a88a2
2 changed files with 29 additions and 23 deletions

40
xxh3.h
View File

@ -1711,7 +1711,7 @@ XXH3_64bits_reset_internal(XXH3_state_t* statePtr,
statePtr->acc[7] = PRIME32_1;
statePtr->seed = seed;
XXH_ASSERT(secret != NULL);
statePtr->secret = secret;
statePtr->extSecret = secret;
XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN);
statePtr->secretLimit = (XXH32_hash_t)(secretSize - STRIPE_LEN);
statePtr->nbStripesPerBlock = statePtr->secretLimit / XXH_SECRET_CONSUME_RATE;
@ -1741,7 +1741,7 @@ XXH3_64bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed)
if (statePtr == NULL) return XXH_ERROR;
XXH3_64bits_reset_internal(statePtr, seed, kSecret, XXH_SECRET_DEFAULT_SIZE);
XXH3_initCustomSecret(statePtr->customSecret, seed);
statePtr->secret = statePtr->customSecret;
statePtr->extSecret = NULL;
return XXH_OK;
}
@ -1780,6 +1780,7 @@ XXH3_update(XXH3_state_t* state, const xxh_u8* input, size_t len, XXH3_accWidth_
#endif
{ const xxh_u8* const bEnd = input + len;
const void* const secret = (state->extSecret == NULL) ? state->customSecret : state->extSecret;
state->totalLen += len;
@ -1804,7 +1805,7 @@ XXH3_update(XXH3_state_t* state, const xxh_u8* input, size_t len, XXH3_accWidth_
XXH3_consumeStripes(state->acc,
&state->nbStripesSoFar, state->nbStripesPerBlock,
state->buffer, XXH3_INTERNALBUFFER_STRIPES,
state->secret, state->secretLimit,
secret, state->secretLimit,
accWidth);
state->bufferedSize = 0;
}
@ -1816,7 +1817,7 @@ XXH3_update(XXH3_state_t* state, const xxh_u8* input, size_t len, XXH3_accWidth_
XXH3_consumeStripes(state->acc,
&state->nbStripesSoFar, state->nbStripesPerBlock,
input, XXH3_INTERNALBUFFER_STRIPES,
state->secret, state->secretLimit,
secret, state->secretLimit,
accWidth);
input += XXH3_INTERNALBUFFER_SIZE;
} while (input<=limit);
@ -1839,7 +1840,10 @@ XXH3_64bits_update(XXH3_state_t* state, const void* input, size_t len)
XXH_FORCE_INLINE void
XXH3_digest_long (XXH64_hash_t* acc, const XXH3_state_t* state, XXH3_accWidth_e accWidth)
XXH3_digest_long (XXH64_hash_t* acc,
const XXH3_state_t* state,
const unsigned char* secret,
XXH3_accWidth_e accWidth)
{
/*
* Digest on a local copy. This way, the state remains unaltered, and it can
@ -1852,12 +1856,12 @@ XXH3_digest_long (XXH64_hash_t* acc, const XXH3_state_t* state, XXH3_accWidth_e
XXH3_consumeStripes(acc,
&nbStripesSoFar, state->nbStripesPerBlock,
state->buffer, totalNbStripes,
state->secret, state->secretLimit,
secret, state->secretLimit,
accWidth);
if (state->bufferedSize % STRIPE_LEN) { /* one last partial stripe */
XXH3_accumulate_512(acc,
state->buffer + state->bufferedSize - STRIPE_LEN,
state->secret + state->secretLimit - XXH_SECRET_LASTACC_START,
secret + state->secretLimit - XXH_SECRET_LASTACC_START,
accWidth);
}
} else { /* bufferedSize < STRIPE_LEN */
@ -1868,25 +1872,26 @@ XXH3_digest_long (XXH64_hash_t* acc, const XXH3_state_t* state, XXH3_accWidth_e
memcpy(lastStripe + catchupSize, state->buffer, state->bufferedSize);
XXH3_accumulate_512(acc,
lastStripe,
state->secret + state->secretLimit - XXH_SECRET_LASTACC_START,
secret + state->secretLimit - XXH_SECRET_LASTACC_START,
accWidth);
} }
}
XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_digest (const XXH3_state_t* state)
{
const unsigned char* const secret = (state->extSecret == NULL) ? state->customSecret : state->extSecret;
if (state->totalLen > XXH3_MIDSIZE_MAX) {
XXH_ALIGN(XXH_ACC_ALIGN) XXH64_hash_t acc[ACC_NB];
XXH3_digest_long(acc, state, XXH3_acc_64bits);
XXH3_digest_long(acc, state, secret, XXH3_acc_64bits);
return XXH3_mergeAccs(acc,
state->secret + XXH_SECRET_MERGEACCS_START,
secret + XXH_SECRET_MERGEACCS_START,
(xxh_u64)state->totalLen * PRIME64_1);
}
/* len <= XXH3_MIDSIZE_MAX: short code */
/* totalLen <= XXH3_MIDSIZE_MAX: digesting a short input */
if (state->seed)
return XXH3_64bits_withSeed(state->buffer, (size_t)state->totalLen, state->seed);
return XXH3_64bits_withSecret(state->buffer, (size_t)(state->totalLen),
state->secret, state->secretLimit + STRIPE_LEN);
secret, state->secretLimit + STRIPE_LEN);
}
/* ==========================================
@ -2298,7 +2303,7 @@ XXH3_128bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed)
if (statePtr == NULL) return XXH_ERROR;
XXH3_128bits_reset_internal(statePtr, seed, kSecret, XXH_SECRET_DEFAULT_SIZE);
XXH3_initCustomSecret(statePtr->customSecret, seed);
statePtr->secret = statePtr->customSecret;
statePtr->extSecret = NULL;
return XXH_OK;
}
@ -2310,16 +2315,17 @@ XXH3_128bits_update(XXH3_state_t* state, const void* input, size_t len)
XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_digest (const XXH3_state_t* state)
{
const unsigned char* const secret = (state->extSecret == NULL) ? state->customSecret : state->extSecret;
if (state->totalLen > XXH3_MIDSIZE_MAX) {
XXH_ALIGN(XXH_ACC_ALIGN) XXH64_hash_t acc[ACC_NB];
XXH3_digest_long(acc, state, XXH3_acc_128bits);
XXH3_digest_long(acc, state, secret, XXH3_acc_128bits);
XXH_ASSERT(state->secretLimit + STRIPE_LEN >= sizeof(acc) + XXH_SECRET_MERGEACCS_START);
{ XXH128_hash_t h128;
h128.low64 = XXH3_mergeAccs(acc,
state->secret + XXH_SECRET_MERGEACCS_START,
secret + XXH_SECRET_MERGEACCS_START,
(xxh_u64)state->totalLen * PRIME64_1);
h128.high64 = XXH3_mergeAccs(acc,
state->secret + state->secretLimit + STRIPE_LEN
secret + state->secretLimit + STRIPE_LEN
- sizeof(acc) - XXH_SECRET_MERGEACCS_START,
~((xxh_u64)state->totalLen * PRIME64_2));
return h128;
@ -2329,7 +2335,7 @@ XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_digest (const XXH3_state_t* state)
if (state->seed)
return XXH3_128bits_withSeed(state->buffer, (size_t)state->totalLen, state->seed);
return XXH3_128bits_withSecret(state->buffer, (size_t)(state->totalLen),
state->secret, state->secretLimit + STRIPE_LEN);
secret, state->secretLimit + STRIPE_LEN);
}
/* 128-bit utility functions */

View File

@ -551,12 +551,11 @@ XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_withSeed(const void* data, size_t len, X
typedef struct XXH3_state_s XXH3_state_t;
#define XXH3_SECRET_DEFAULT_SIZE 192 /* minimum XXH3_SECRET_SIZE_MIN */
#define XXH3_SECRET_DEFAULT_SIZE 192 /* >= XXH3_SECRET_SIZE_MIN */
#define XXH3_INTERNALBUFFER_SIZE 256
struct XXH3_state_s {
XXH_ALIGN_MEMBER(64, XXH64_hash_t acc[8]);
/* used to store a custom secret generated from the seed. Makes state larger.
* Design might change */
/* used to store a custom secret generated from a seed */
XXH_ALIGN_MEMBER(64, unsigned char customSecret[XXH3_SECRET_DEFAULT_SIZE]);
XXH_ALIGN_MEMBER(64, unsigned char buffer[XXH3_INTERNALBUFFER_SIZE]);
XXH32_hash_t bufferedSize;
@ -568,9 +567,10 @@ struct XXH3_state_s {
XXH64_hash_t totalLen;
XXH64_hash_t seed;
XXH64_hash_t reserved64;
/* note: there is some padding after due to alignment on 64 bytes */
const unsigned char* secret;
}; /* typedef'd to XXH3_state_t */
const unsigned char* extSecret; /* reference to external secret;
* if == NULL, use customSecret instead */
/* note: there is some padding at the end due to alignment on 64 bytes */
}; /* typedef'd to XXH3_state_t */
#undef XXH_ALIGN_MEMBER