Skip to content

Commit 5ba244d

Browse files
authored
Merge pull request #99 from OttoCoddo/main
Add some hashes
2 parents 7a7feec + 3e94261 commit 5ba244d

File tree

2 files changed

+276
-3
lines changed

2 files changed

+276
-3
lines changed

entries/ocoddo/src/Project1.lpr

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@
2121
UThread,
2222
UThreadGroup,
2323
UThreadHelp,
24-
UxxHash,
25-
UxxHashLibraryStatic;
24+
UHashes;
2625

2726
const
2827
MaxCount: UPS = 48 * 1024;
@@ -32,6 +31,7 @@
3231
JumperCount: UPS;
3332
PartSize: UPS;
3433
ProcessorCount: U8;
34+
HashKind: U8;
3535

3636
type
3737
THash = U32;
@@ -88,7 +88,16 @@ TStationSummary = record
8888
I: Ind;
8989
JN: TJumper;
9090
begin
91-
H := XXH3_64bits(P + NS, NE - NS + 1) shr 32; //Good quality, no repeat for this dataset
91+
//Perfect quality, no repeat for this dataset
92+
case HashKind of
93+
0: H := xxHash32C(P + NS, NE - NS + 1);
94+
1: H := FNV1a32(P + NS, NE - NS + 1);
95+
2: H := FNV1a32Custom(P + NS, NE - NS + 1);
96+
3: H := crc32csse42(0, P + NS, NE - NS + 1);
97+
4: H := crc32c(P + NS, NE - NS + 1);
98+
5: H := crc32c2(P + NS, NE - NS + 1);
99+
6: H := xxHash(PByte(P + NS), NE - NS + 1);
100+
end;
92101
I := H and (JumperCount - 1); //Index in Jumpers
93102

94103
with ACoordinator do
@@ -398,6 +407,7 @@ TStationSummary = record
398407
ProcessorCount := LogicalProcessorCount;
399408
JumperCount := 256 * 1024;
400409
PartSize := 192 * 1024 - ReadMargin;
410+
HashKind := 0;
401411

402412
for I := 0 to High(Parameters) do
403413
begin
@@ -410,6 +420,8 @@ TStationSummary = record
410420
PartSize := (V * 1024) - ReadMargin
411421
else if N = 'processor-count' then
412422
ProcessorCount := V
423+
else if N = 'hash-kind' then
424+
HashKind := V
413425
else if N = 'help' then
414426
begin
415427
WriteHelp;

entries/ocoddo/src/UHashes.pas

Lines changed: 261 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,261 @@
1+
unit UHashes;
2+
3+
{$I SCL.inc}
4+
5+
interface
6+
7+
uses
8+
UNumber, UString, UxxHash, UxxHashLibraryStatic;
9+
10+
function xxHash32C(P: PChar; L: NChar): U32; inline;
11+
function FNV1a32(P: PChar; L: NChar): U32; inline;
12+
function FNV1a32Custom(P: PChar; L: NChar): U32; inline;
13+
function crc32csse42(crc: cardinal; buf: PAnsiChar; len: cardinal): cardinal;
14+
function crc32c(P: PChar; L: U32): U32;
15+
function crc32c2(P: PChar; L: U32): U32;
16+
function xxHash(P: PByte; L: U32): U32; inline;
17+
18+
implementation
19+
20+
function xxHash32C(P: PChar; L: NChar): U32;
21+
begin
22+
Result := XXH3_64bits(P, L) shr 32;
23+
end;
24+
25+
function FNV1a32(P: PChar; L: NChar): U32;
26+
var
27+
C: Ind;
28+
begin
29+
Result := 2166136261;
30+
for C := 0 to L - 1 do
31+
Result := (Result xor U8(P[C])) * 16777619;
32+
end;
33+
34+
function FNV1a32Custom(P: PChar; L: NChar): U32;
35+
begin
36+
Result := 2166136261;
37+
while L >= 4 do
38+
begin
39+
Result := (Result xor PU32(P)^) * 16777619;
40+
P += 3;
41+
L -= 3;
42+
end;
43+
while L >= 2 do
44+
begin
45+
Result := (Result xor PU16(P)^) * 16777619;
46+
P += 2;
47+
L -= 2;
48+
end;
49+
if L = 1 then
50+
Result := (Result xor PU8(P)^) * 16777619;
51+
end;
52+
53+
//From the great tiny mORMot
54+
function crc32csse42(crc: cardinal; buf: PAnsiChar; len: cardinal): cardinal; nostackframe; assembler;
55+
asm
56+
mov eax, crc
57+
test len, len
58+
jz @z
59+
test buf, buf
60+
jz @z
61+
not eax
62+
mov ecx, len
63+
shr len, 3
64+
jnz @by8 // no read alignment care here - but in crypto.core
65+
@0:
66+
test cl, 4
67+
jz @4
68+
crc32 eax, dword ptr [buf]
69+
add buf, 4
70+
@4:
71+
test cl, 2
72+
jz @2
73+
crc32 eax, word ptr [buf]
74+
add buf, 2
75+
@2:
76+
test cl, 1
77+
jz @1
78+
crc32 eax, byte ptr [buf]
79+
@1:
80+
not eax
81+
@z:
82+
ret
83+
align 16
84+
@by8:
85+
crc32 rax, qword ptr [buf] // hash 8 bytes per loop
86+
add buf, 8
87+
sub len, 1
88+
jnz @by8
89+
jmp @0
90+
end;
91+
92+
function crc32c(P: PChar; L: U32): U32; nostackframe; assembler;
93+
asm
94+
MOV EDX, EDX
95+
LEA R9, [RCX + 8]
96+
LEA R8, [RCX+RDX]
97+
CMP R8, R9
98+
JB @L7
99+
MOV RCX, R9
100+
XOR EAX, EAX
101+
@L3:
102+
CRC32 RAX, QWORD PTR [RCX - 8]
103+
ADD RCX, 8
104+
CMP R8, RCX
105+
JNB @L3
106+
SUB RDX, 8
107+
AND RDX, -8
108+
LEA RCX, [R9+RDX]
109+
@L2:
110+
LEA RDX, [RCX + 4]
111+
CMP R8, RDX
112+
JB @L4
113+
CRC32 EAX, DWORD PTR [RCX]
114+
MOV RCX, RDX
115+
@L4:
116+
CMP RCX, R8
117+
JNB @L1
118+
@L6:
119+
CRC32 EAX, BYTE PTR [RCX]
120+
INC RCX
121+
CMP R8, RCX
122+
JNE @L6
123+
@L1:
124+
RET
125+
@L7:
126+
XOR EAX, EAX
127+
JMP @L2
128+
end;
129+
130+
function crc32c2(P: PChar; L: U32): U32; nostackframe; assembler;
131+
asm
132+
mov r8d, edx
133+
and r8d, 3
134+
xor eax, eax
135+
cmp r8d, 1
136+
je @LBB0_5
137+
cmp r8d, 2
138+
je @LBB0_4
139+
cmp r8d, 3
140+
jne @LBB0_6
141+
xor eax, eax
142+
crc32 eax, word ptr [rcx]
143+
crc32 eax, byte ptr [rcx + 2]
144+
add rcx, 3
145+
cmp edx, 4
146+
jae @LBB0_7
147+
jmp @LBB0_13
148+
@LBB0_5:
149+
crc32 eax, byte ptr [rcx]
150+
inc rcx
151+
@LBB0_6:
152+
cmp edx, 4
153+
jae @LBB0_7
154+
jmp @LBB0_13
155+
@LBB0_4:
156+
crc32 eax, word ptr [rcx]
157+
add rcx, 2
158+
cmp edx, 4
159+
jb @LBB0_13
160+
@LBB0_7:
161+
shr edx, 2
162+
lea r8d, [rdx - 1]
163+
cmp r8d, 7
164+
jb @LBB0_10
165+
mov r8d, edx
166+
and r8d, -8
167+
@LBB0_9:
168+
crc32 eax, dword ptr [rcx]
169+
crc32 eax, dword ptr [rcx + 4]
170+
crc32 eax, dword ptr [rcx + 8]
171+
crc32 eax, dword ptr [rcx + 12]
172+
crc32 eax, dword ptr [rcx + 16]
173+
crc32 eax, dword ptr [rcx + 20]
174+
crc32 eax, dword ptr [rcx + 24]
175+
crc32 eax, dword ptr [rcx + 28]
176+
add rcx, 32
177+
add r8d, -8
178+
jne @LBB0_9
179+
@LBB0_10:
180+
test dl, 7
181+
je @LBB0_13
182+
and edx, 7
183+
xor r8d, r8d
184+
@LBB0_12:
185+
crc32 eax, dword ptr [rcx + 4*r8]
186+
inc r8
187+
cmp edx, r8d
188+
jne @LBB0_12
189+
@LBB0_13:
190+
ret
191+
end;
192+
193+
const
194+
Prime1 = 2654435761;
195+
Prime2 = 2246822519;
196+
Prime3 = 3266489917;
197+
Prime4 = 668265263;
198+
Prime5 = 374761393;
199+
200+
function xxHashStep(V, D: U32): U32; inline;
201+
begin
202+
V := V + (D * Prime2);
203+
V := (V shl 13) or (V shr (32 - 13));
204+
V := V * Prime1;
205+
Result := V;
206+
end;
207+
208+
function xxHash(P: PByte; L: U32): U32;
209+
var
210+
I, J: Ind;
211+
V1, V2, V3, V4: U32;
212+
begin
213+
if L >= 16 then
214+
begin
215+
V1 := Prime1 + Prime2;
216+
V2 := Prime2;
217+
V3 := 0;
218+
V4 := Prime1;
219+
220+
for I := 0 to (L shr 4) - 1 do
221+
begin
222+
V1 := xxHashStep(V1, PU32(P)[0]);
223+
V2 := xxHashStep(V2, PU32(P)[1]);
224+
V3 := xxHashStep(V3, PU32(P)[2]);
225+
V4 := xxHashStep(V4, PU32(P)[3]);
226+
P += 16;
227+
end;
228+
229+
Result := ((V1 shl 1) or (V1 shr (32 - 1))) + ((V2 shl 7) or (V2 shr (32 - 7))) +
230+
((V3 shl 12) or (V3 shr (32 - 12))) + ((V4 shl 18) or (V4 shr (32 - 18)));
231+
L := L and 15;
232+
end
233+
else
234+
Result := Prime5;
235+
236+
Result += L;
237+
238+
while L >= 4 do
239+
begin
240+
Result += PU32(P)^ * Prime3;
241+
Result := ((Result shl 17) or (Result shr (32 - 17))) * Prime4;
242+
P += 4;
243+
L -= 4;
244+
end;
245+
246+
while L > 0 do
247+
begin
248+
Result += P^ * Prime5;
249+
Result := ((Result shl 11) or (Result shr (32 - 11))) * Prime1;
250+
P += 1;
251+
L -= 1;
252+
end;
253+
254+
Result := Result xor (Result shr 15);
255+
Result := Result * Prime2;
256+
Result := Result xor (Result shr 13);
257+
Result := Result * Prime3;
258+
Result := Result xor (Result shr 16);
259+
end;
260+
261+
end.

0 commit comments

Comments
 (0)