Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 61 additions & 8 deletions lib/src/util.dart
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,13 @@ void accumulate512(

/// Dart equivalent of the xxh3_accumulate function from XXH3. This function
/// performs [accumulate512] for each of the [stripes].
@pragma('vm:prefer-inline')
///
/// The loop body is a manually inlined [accumulate512]. The eight accumulator
/// lanes stay in unboxed local variables across stripes instead of going
/// through [acc] for every lane, which a call to [accumulate512] would require
/// since it can only update the lanes in memory. Not marked prefer-inline: it
/// runs once per block, and inlining a body this size exhausts the caller's
/// inlining budget, which leaves the typed data reads un-inlined.
void accumulate(
final Uint64List acc, {
required final ByteData input,
Expand All @@ -80,15 +86,62 @@ void accumulate(
final int inputOffset = 0,
final int secretOffset = 0,
}) {
int acc0 = acc[0];
int acc1 = acc[1];
int acc2 = acc[2];
int acc3 = acc[3];
int acc4 = acc[4];
int acc5 = acc[5];
int acc6 = acc[6];
int acc7 = acc[7];
int dataVal;
int dataKey;

for (int i = 0; i < stripes; i++) {
accumulate512(
acc,
input: input,
secret: secret,
inputOffset: (i * kStripeLength) + inputOffset,
secretOffset: (i * kSecretConsumeRate) + secretOffset,
);
final inOff = inputOffset + i * kStripeLength;
final secOff = secretOffset + i * kSecretConsumeRate;
dataVal = readLE64(input, inOff + 0);
dataKey = dataVal ^ readLE64(secret, secOff + 0);
acc1 += dataVal;
acc0 += (dataKey & 0xFFFFFFFF) * (dataKey >>> 32);
dataVal = readLE64(input, inOff + 8);
dataKey = dataVal ^ readLE64(secret, secOff + 8);
acc0 += dataVal;
acc1 += (dataKey & 0xFFFFFFFF) * (dataKey >>> 32);
dataVal = readLE64(input, inOff + 16);
dataKey = dataVal ^ readLE64(secret, secOff + 16);
acc3 += dataVal;
acc2 += (dataKey & 0xFFFFFFFF) * (dataKey >>> 32);
dataVal = readLE64(input, inOff + 24);
dataKey = dataVal ^ readLE64(secret, secOff + 24);
acc2 += dataVal;
acc3 += (dataKey & 0xFFFFFFFF) * (dataKey >>> 32);
dataVal = readLE64(input, inOff + 32);
dataKey = dataVal ^ readLE64(secret, secOff + 32);
acc5 += dataVal;
acc4 += (dataKey & 0xFFFFFFFF) * (dataKey >>> 32);
dataVal = readLE64(input, inOff + 40);
dataKey = dataVal ^ readLE64(secret, secOff + 40);
acc4 += dataVal;
acc5 += (dataKey & 0xFFFFFFFF) * (dataKey >>> 32);
dataVal = readLE64(input, inOff + 48);
dataKey = dataVal ^ readLE64(secret, secOff + 48);
acc7 += dataVal;
acc6 += (dataKey & 0xFFFFFFFF) * (dataKey >>> 32);
dataVal = readLE64(input, inOff + 56);
dataKey = dataVal ^ readLE64(secret, secOff + 56);
acc6 += dataVal;
acc7 += (dataKey & 0xFFFFFFFF) * (dataKey >>> 32);
}

acc[0] = acc0;
acc[1] = acc1;
acc[2] = acc2;
acc[3] = acc3;
acc[4] = acc4;
acc[5] = acc5;
acc[6] = acc6;
acc[7] = acc7;
}

/// Dart equivalent of the xxh3_avalanche.
Expand Down