handling 16 at once (#704)

This commit is contained in:
Artsiom Korzun 2024-02-01 11:14:31 +01:00 committed by GitHub
parent 9e2199a5d7
commit da26f61137
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -39,6 +39,8 @@ public class CalculateAverage_artsiomkorzun {
private static final long LINE_PATTERN = 0x0A0A0A0A0A0A0A0AL; private static final long LINE_PATTERN = 0x0A0A0A0A0A0A0A0AL;
private static final long DOT_BITS = 0x10101000; private static final long DOT_BITS = 0x10101000;
private static final long MAGIC_MULTIPLIER = (100 * 0x1000000 + 10 * 0x10000 + 1); private static final long MAGIC_MULTIPLIER = (100 * 0x1000000 + 10 * 0x10000 + 1);
private static final long[] WORD_MASK = { 0, 0, 0, 0, 0, 0, 0, 0, -1 };
private static final int[] LENGTH_MASK = { 0, 0, 0, 0, 0, 0, 0, 0, -1 };
private static final Unsafe UNSAFE; private static final Unsafe UNSAFE;
@ -190,12 +192,6 @@ public class CalculateAverage_artsiomkorzun {
UNSAFE.setMemory(pointer, SIZE, (byte) 0); UNSAFE.setMemory(pointer, SIZE, (byte) 0);
} }
public long find(long word, long hash) {
long address = pointer + offset(hash);
long w = word(address + 24);
return (w == word) ? address : 0;
}
public long find(long word1, long word2, long hash) { public long find(long word1, long word2, long hash) {
long address = pointer + offset(hash); long address = pointer + offset(hash);
long w1 = word(address + 24); long w1 = word(address + 24);
@ -393,14 +389,20 @@ public class CalculateAverage_artsiomkorzun {
long word1 = word(chunk1.position); long word1 = word(chunk1.position);
long word2 = word(chunk2.position); long word2 = word(chunk2.position);
long word3 = word(chunk3.position); long word3 = word(chunk3.position);
long word4 = word(chunk1.position + 8);
long word5 = word(chunk2.position + 8);
long word6 = word(chunk3.position + 8);
long separator1 = separator(word1); long separator1 = separator(word1);
long separator2 = separator(word2); long separator2 = separator(word2);
long separator3 = separator(word3); long separator3 = separator(word3);
long separator4 = separator(word4);
long separator5 = separator(word5);
long separator6 = separator(word6);
long pointer1 = find(aggregates, chunk1, word1, separator1); long pointer1 = find(aggregates, chunk1, word1, word4, separator1, separator4);
long pointer2 = find(aggregates, chunk2, word2, separator2); long pointer2 = find(aggregates, chunk2, word2, word5, separator2, separator5);
long pointer3 = find(aggregates, chunk3, word3, separator3); long pointer3 = find(aggregates, chunk3, word3, word6, separator3, separator6);
long value1 = value(chunk1); long value1 = value(chunk1);
long value2 = value(chunk2); long value2 = value(chunk2);
@ -413,26 +415,41 @@ public class CalculateAverage_artsiomkorzun {
while (chunk1.has()) { while (chunk1.has()) {
long word1 = word(chunk1.position); long word1 = word(chunk1.position);
long word2 = word(chunk1.position + 8);
long separator1 = separator(word1); long separator1 = separator(word1);
long pointer1 = find(aggregates, chunk1, word1, separator1); long separator2 = separator(word2);
long value1 = value(chunk1);
Aggregates.update(pointer1, value1); long pointer = find(aggregates, chunk1, word1, word2, separator1, separator2);
long value = value(chunk1);
Aggregates.update(pointer, value);
} }
while (chunk2.has()) { while (chunk2.has()) {
long word2 = word(chunk2.position); long word1 = word(chunk2.position);
long word2 = word(chunk2.position + 8);
long separator1 = separator(word1);
long separator2 = separator(word2); long separator2 = separator(word2);
long pointer2 = find(aggregates, chunk2, word2, separator2);
long value2 = value(chunk2); long pointer = find(aggregates, chunk2, word1, word2, separator1, separator2);
Aggregates.update(pointer2, value2); long value = value(chunk2);
Aggregates.update(pointer, value);
} }
while (chunk3.has()) { while (chunk3.has()) {
long word3 = word(chunk3.position); long word1 = word(chunk3.position);
long separator3 = separator(word3); long word2 = word(chunk3.position + 8);
long pointer3 = find(aggregates, chunk3, word3, separator3);
long value3 = value(chunk3); long separator1 = separator(word1);
Aggregates.update(pointer3, value3); long separator2 = separator(word2);
long pointer = find(aggregates, chunk3, word1, word2, separator1, separator2);
long value = value(chunk3);
Aggregates.update(pointer, value);
} }
} }
@ -456,48 +473,39 @@ public class CalculateAverage_artsiomkorzun {
continue; continue;
} }
return position + (Long.numberOfTrailingZeros(line) >>> 3) + 1; return position + length(line) + 1;
} }
} }
private static long find(Aggregates aggregates, Chunk chunk, long word, long separator) { private static long find(Aggregates aggregates, Chunk chunk, long word1, long word2, long separator1, long separator2) {
boolean small = (separator1 | separator2) != 0;
long start = chunk.position; long start = chunk.position;
long hash; long hash;
long word;
if (separator != 0) { if (small) {
word = mask(word, separator); int length1 = length(separator1);
hash = mix(word); int length2 = length(separator2);
word1 = mask(word1, separator1);
word2 = mask(word2 & WORD_MASK[length1], separator2);
hash = mix(word1 ^ word2);
chunk.position += length(separator); chunk.position += length1 + (length2 & LENGTH_MASK[length1]) + 1;
long pointer = aggregates.find(word, hash); long pointer = aggregates.find(word1, word2, hash);
if (pointer != 0) { if (pointer != 0) {
return pointer; return pointer;
} }
}
else {
long word0 = word;
word = word(start + 8);
separator = separator(word);
if (separator != 0) { word = (separator1 == 0) ? word2 : word1;
word = mask(word, separator);
hash = mix(word ^ word0);
chunk.position += length(separator) + 8;
long pointer = aggregates.find(word0, word, hash);
if (pointer != 0) {
return pointer;
}
} }
else { else {
chunk.position += 16; chunk.position += 16;
hash = word ^ word0; hash = word1 ^ word2;
while (true) { while (true) {
word = word(chunk.position); word = word(chunk.position);
separator = separator(word); long separator = separator(word);
if (separator == 0) { if (separator == 0) {
chunk.position += 8; chunk.position += 8;
@ -507,11 +515,10 @@ public class CalculateAverage_artsiomkorzun {
word = mask(word, separator); word = mask(word, separator);
hash = mix(hash ^ word); hash = mix(hash ^ word);
chunk.position += length(separator); chunk.position += length(separator) + 1;
break; break;
} }
} }
}
long length = chunk.position - start; long length = chunk.position - start;
return aggregates.put(start, word, length, hash); return aggregates.put(start, word, length, hash);
@ -535,8 +542,8 @@ public class CalculateAverage_artsiomkorzun {
return word & mask; return word & mask;
} }
private static long length(long separator) { private static int length(long separator) {
return (Long.numberOfTrailingZeros(separator) >>> 3) + 1; return Long.numberOfTrailingZeros(separator) >>> 3;
} }
private static long mix(long x) { private static long mix(long x) {