Skip to content

Commit

Permalink
Implement hash function MultiplyRotateR.
Browse files Browse the repository at this point in the history
  • Loading branch information
tpn committed Feb 17, 2020
1 parent d4c92f3 commit 13569cf
Show file tree
Hide file tree
Showing 10 changed files with 196 additions and 0 deletions.
5 changes: 5 additions & 0 deletions include/PerfectHash.h
Original file line number Diff line number Diff line change
Expand Up @@ -1948,6 +1948,11 @@ IsValidSeedMasks(
6, \
DECL_SEED_MASKS(0, 0, 0x1f1f1f1f, 0, 0, 0x1f1f1f1f, 0, 0) \
) \
ENTRY( \
MultiplyRotateR, \
3, \
DECL_SEED_MASKS(0, 0, 0x1f1f, 0, 0, 0, 0, 0) \
) \
LAST_ENTRY(Scratch, 3, NO_SEED_MASKS)

#define PERFECT_HASH_HASH_FUNCTION_TABLE_ENTRY(ENTRY) \
Expand Down
1 change: 1 addition & 0 deletions include/PerfectHashErrors.h
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ Module Name:
// 18 ShiftMultiplyXorShift (3)
// 19 ShiftMultiplyXorShift2 (6)
// 20 RotateMultiplyXorRotate2 (6)
// 21 MultiplyRotateR (3)
//
// N.B. The lowest latency hash functions with good solving ability, in order of
// ascending latency, are: Crc32RotateX, Crc32RotateXY, Crc32RotateWXYZ.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@

DECLARE_INDEX_ROUTINE()
{
CPHINDEX Index;
CPHDKEY Vertex1;
CPHDKEY Vertex2;
CPHDKEY MaskedLow;
CPHDKEY MaskedHigh;
CPHDKEY DownsizedKey;

DownsizedKey = DOWNSIZE_KEY(Key);

Vertex1 = DownsizedKey * SEED1;
Vertex1 = _rotr(Vertex1, SEED3_BYTE1);

Vertex2 = DownsizedKey * SEED2;
Vertex2 = _rotr(Vertex2, SEED3_BYTE2);

MaskedLow = Vertex1 & HASH_MASK;
MaskedHigh = Vertex2 & HASH_MASK;

Vertex1 = TABLE_DATA[MaskedLow];
Vertex2 = TABLE_DATA[MaskedHigh];

Index = (CPHINDEX)((Vertex1 + Vertex2) & INDEX_MASK);

return Index;
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
//
// Auto-generated.
//

DECLSPEC_ALIGN(16)
const CHAR CompiledPerfectHashTableChm01IndexMultiplyRotateRAndCSourceRawCStr[] =
"\n"
"//\n"
"// Begin CompiledPerfectHashTableChm01IndexMultiplyRotateRAnd.c.\n"
"//\n"
"\n"
"\n"
"DECLARE_INDEX_ROUTINE()\n"
"{\n"
" CPHINDEX Index;\n"
" CPHDKEY Vertex1;\n"
" CPHDKEY Vertex2;\n"
" CPHDKEY MaskedLow;\n"
" CPHDKEY MaskedHigh;\n"
" CPHDKEY DownsizedKey;\n"
"\n"
" DownsizedKey = DOWNSIZE_KEY(Key);\n"
"\n"
" Vertex1 = DownsizedKey * SEED1;\n"
" Vertex1 = _rotr(Vertex1, SEED3_BYTE1);\n"
"\n"
" Vertex2 = DownsizedKey * SEED2;\n"
" Vertex2 = _rotr(Vertex2, SEED3_BYTE2);\n"
"\n"
" MaskedLow = Vertex1 & HASH_MASK;\n"
" MaskedHigh = Vertex2 & HASH_MASK;\n"
"\n"
" Vertex1 = TABLE_DATA[MaskedLow];\n"
" Vertex2 = TABLE_DATA[MaskedHigh];\n"
"\n"
" Index = (CPHINDEX)((Vertex1 + Vertex2) & INDEX_MASK);\n"
"\n"
" return Index;\n"
"}\n"
"\n"
"\n"
"//\n"
"// End CompiledPerfectHashTableChm01IndexMultiplyRotateRAnd.c.\n"
"//\n"
"\n"
;

const STRING CompiledPerfectHashTableChm01IndexMultiplyRotateRAndCSourceRawCString = {
sizeof(CompiledPerfectHashTableChm01IndexMultiplyRotateRAndCSourceRawCStr) - sizeof(CHAR),
sizeof(CompiledPerfectHashTableChm01IndexMultiplyRotateRAndCSourceRawCStr),
#ifdef _WIN64
0,
#endif
(PCHAR)&CompiledPerfectHashTableChm01IndexMultiplyRotateRAndCSourceRawCStr,
};

#ifndef RawCString
#define RawCString (&CompiledPerfectHashTableChm01IndexMultiplyRotateRAndCSourceRawCString)
#endif
1 change: 1 addition & 0 deletions src/PerfectHash/CompiledPerfectHashTableIndexRoutines.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "CompiledPerfectHashTableChm01IndexShiftMultiplyXorShiftAnd_CSource_RawCString.h"
#include "CompiledPerfectHashTableChm01IndexShiftMultiplyXorShift2And_CSource_RawCString.h"
#include "CompiledPerfectHashTableChm01IndexRotateMultiplyXorRotate2And_CSource_RawCString.h"
#include "CompiledPerfectHashTableChm01IndexMultiplyRotateRAnd_CSource_RawCString.h"

//
// Keep this last.
Expand Down
1 change: 1 addition & 0 deletions src/PerfectHash/PerfectHash.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@
<ClInclude Include="CompiledPerfectHashTableChm01IndexShiftMultiplyXorShiftAnd_CSource_RawCString.h" />
<ClInclude Include="CompiledPerfectHashTableChm01IndexShiftMultiplyXorShift2And_CSource_RawCString.h" />
<ClInclude Include="CompiledPerfectHashTableChm01IndexRotateMultiplyXorRotate2And_CSource_RawCString.h" />
<ClInclude Include="CompiledPerfectHashTableChm01IndexMultiplyRotateRAnd_CSource_RawCString.h" />
<ClInclude Include="CompiledPerfectHashTableIndexRoutines.h" />
<ClInclude Include="CompiledPerfectHashTableRoutinesPost_CSource_RawCString.h" />
<ClInclude Include="CompiledPerfectHashTableRoutinesPre_CSource_RawCString.h" />
Expand Down
3 changes: 3 additions & 0 deletions src/PerfectHash/PerfectHash.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,9 @@
<ClInclude Include="CompiledPerfectHashTableChm01IndexShiftMultiplyXorShift2And_CSource_RawCString.h">
<Filter>Private Header Files %28Auto-Generated%29</Filter>
</ClInclude>
<ClInclude Include="CompiledPerfectHashTableChm01IndexMultiplyRotateRAnd_CSource_RawCString.h">
<Filter>Private Header Files %28Auto-Generated%29</Filter>
</ClInclude>
<ClInclude Include="ExtractArg.h">
<Filter>Private Header Files</Filter>
</ClInclude>
Expand Down
1 change: 1 addition & 0 deletions src/PerfectHash/PerfectHashErrors.mc
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ Hash Functions:
18 ShiftMultiplyXorShift (3)
19 ShiftMultiplyXorShift2 (6)
20 RotateMultiplyXorRotate2 (6)
21 MultiplyRotateR (3)
N.B. The lowest latency hash functions with good solving ability, in order of
ascending latency, are: Crc32RotateX, Crc32RotateXY, Crc32RotateWXYZ.
Expand Down
Binary file modified src/PerfectHash/PerfectHashErrors_English.bin
Binary file not shown.
96 changes: 96 additions & 0 deletions src/PerfectHash/PerfectHashTableHash.c
Original file line number Diff line number Diff line change
Expand Up @@ -2286,4 +2286,100 @@ PerfectHashTableHashShiftMultiplyXorShift2(
);
}

_Use_decl_annotations_
HRESULT
PerfectHashTableSeededHashMultiplyRotateR(
PPERFECT_HASH_TABLE Table,
ULONG Key,
ULONG NumberOfSeeds,
PULONG Seeds,
PULONGLONG Hash
)
/*++
Routine Description:
Performs a multiply then right rotate.
Arguments:
Table - Supplies a pointer to the table for which the hash is being created.
Key - Supplies the input value to hash.
NumberOfSeeds - Supplies the number of elements in the Seeds array.
Seeds - Supplies an array of ULONG seed values.
Hash - Receives two 32-bit hashes merged into a 64-bit value.
Return Value:
S_OK on success. If the two 32-bit hash values are identical, E_FAIL.
--*/
{
ULONG Seed1;
ULONG Seed2;
ULONG_BYTES Seed3;
ULONG Vertex1;
ULONG Vertex2;
ULONG DownsizedKey;
ULARGE_INTEGER Result;

UNREFERENCED_PARAMETER(Table);

ASSERT(NumberOfSeeds >= 3);
UNREFERENCED_PARAMETER(NumberOfSeeds);

//
// Initialize aliases.
//

Seed1 = Seeds[0];
Seed2 = Seeds[1];
Seed3.AsULong = Seeds[2];
DownsizedKey = Key;

//
// Calculate the individual hash parts.
//

Vertex1 = DownsizedKey * SEED1;
Vertex1 = _rotr(Vertex1, SEED3_BYTE1);

Vertex2 = DownsizedKey * SEED2;
Vertex2 = _rotr(Vertex2, SEED3_BYTE2);

if (Vertex1 == Vertex2) {
return E_FAIL;
}

Result.LowPart = Vertex1;
Result.HighPart = Vertex2;

*Hash = Result.QuadPart;

return S_OK;
}

_Use_decl_annotations_
HRESULT
PerfectHashTableHashMultiplyRotateR(
PPERFECT_HASH_TABLE Table,
ULONG Key,
PULONGLONG Hash
)
{
PTABLE_INFO_ON_DISK TableInfo = Table->TableInfoOnDisk;

return PerfectHashTableSeededHashMultiplyRotateR(
Table,
Key,
TableInfo->NumberOfSeeds,
&TableInfo->FirstSeed,
Hash
);
}

// vim:set ts=8 sw=4 sts=4 tw=80 expandtab :

0 comments on commit 13569cf

Please sign in to comment.