@@ -37,15 +37,21 @@ package _Impl
37
37
38
38
[ct] let hashSeed: UInt32 = -1
39
39
40
- /// FNV hash generator
41
- fun doHash(key: StringRef, start: UInt32): UInt32
42
- var hash = start
43
- for i = 0..key.size()
44
- hash = (hash !^! UInt32(Int8(key(i)))) * 0x01000193U;
45
- //cout << "Hash(" << key << ", " << start << ")=" << hash << "\n";
46
- return hash;
47
- fun doHash(value, start: UInt32): UInt32
48
- return (start !^! value) * 0x01000193U;
40
+ /// FNV hash generator
41
+ fun _doHash(key: StringRef, start: UInt32): UInt32
42
+ var hash = start
43
+ for i = 0..key.size()
44
+ hash = (hash !^! UInt32(Int8(key(i)))) * 0x01000193U;
45
+ //cout << "Hash(" << key << ", " << start << ")=" << hash << "\n";
46
+ return hash;
47
+ fun _doHash(value, start: UInt32): UInt32
48
+ return (start !^! value) * 0x01000193U;
49
+
50
+ fun _hashMod(key: StringRef, start: UInt32, numBuckets: Int): Int
51
+ return Int(_doHash(key, start) % UInt32(numBuckets))
52
+
53
+ fun _hashMod(value, start: UInt32, numBuckets: Int): Int
54
+ return Int(_doHash(value, start) % UInt32(numBuckets))
49
55
50
56
datatype MinPerfHash
51
57
displacements: Array(Int)
@@ -71,7 +77,7 @@ fun ctor(this: !MinPerfHash, keys: !Vector(String), extraSpace: Float)
71
77
// Split the keys into buckets
72
78
for key: @AnyType = keys.all()
73
79
//cout << "Key: " << key.asStringRef() << "\n";
74
- let pos = Int(_Impl.doHash( key.asStringRef(), _Impl.hashSeed)) % numBuckets
80
+ let pos = _hashMod( key.asStringRef(), _Impl.hashSeed, numBuckets)
75
81
keysToBuckets(pos).pushBack(key.asStringRef())
76
82
77
83
// Sort the buckets in failing order according to their size
@@ -95,7 +101,7 @@ fun ctor(this: !MinPerfHash, keys: !Vector(String), extraSpace: Float)
95
101
// keys in this bucket without conflicts with keys from previous buckets.
96
102
var item = 0
97
103
while item < bucket.size()
98
- let slot: Int = Int(_Impl.doHash( bucket(item), UInt32(d))) % numValues
104
+ let slot = _hashMod( bucket(item), UInt32(d), numValues)
99
105
let slotAlreadyUsed = !find(slots.all(), slot).isEmpty()
100
106
++numOp
101
107
if ( placedKeys.testBit(slot) || slotAlreadyUsed )
@@ -113,7 +119,7 @@ fun ctor(this: !MinPerfHash, keys: !Vector(String), extraSpace: Float)
113
119
// This is guaranteed to finish quickly
114
120
115
121
// We found a displacement that works for the current bucket (it doesn't yield overlaps with previous buckets)
116
- displacements(Int(_Impl.doHash( bucket(0), _Impl.hashSeed)) % numBuckets) = d
122
+ displacements(_hashMod( bucket(0), _Impl.hashSeed, numBuckets) ) = d
117
123
for i=0..bucket.size()
118
124
placedKeys.setBit(slots(i));
119
125
@@ -130,7 +136,7 @@ fun ctor(this: !MinPerfHash, keys: !Vector(String), extraSpace: Float)
130
136
++emptySlot;
131
137
132
138
// We subtract one to ensure it's negative even if the zero-th slot was used.
133
- displacements(Int(_Impl.doHash( bucket(0), _Impl.hashSeed)) % numBuckets) = -emptySlot-1
139
+ displacements(_hashMod( bucket(0), _Impl.hashSeed, numBuckets) ) = -emptySlot-1
134
140
placedKeys.setBit(emptySlot)
135
141
136
142
//_dumpBuckets("buckets final, ", keysToBuckets);
@@ -146,9 +152,9 @@ fun ctorFromCt(this: !MinPerfHash, src: MinPerfHash ct)
146
152
147
153
fun search(this: !MinPerfHash, key: StringRef): Int
148
154
// Get the displacement from the table...
149
- let d = displacements(Int(_Impl.doHash( key, _Impl.hashSeed)) % displacements.size())
155
+ let d = displacements(_hashMod( key, _Impl.hashSeed, displacements.size() ))
150
156
// If the displacement is negative, directly return; otherwise compute the final hash
151
- return ife(d<0, Int(-d-1), Int(_Impl.doHash( key, UInt32(d))) % numValues)
157
+ return ife(d<0, Int(-d-1), _hashMod( key, UInt32(d), numValues) )
152
158
153
159
fun ()(this: !MinPerfHash, key: StringRef) = this.search(key)
154
160
0 commit comments