-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathHashMap.as
More file actions
140 lines (113 loc) · 3.31 KB
/
HashMap.as
File metadata and controls
140 lines (113 loc) · 3.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// angelscript dictionaries in sven lag like shit when they have a lot of keys,
// even when not accessing them. They just generate lag without being used somehow.
// So, this is a temporary replacement.
/*
tts: Total collisions: 40415
tts: Buckets filled: 77100 / 131072 (58%)
tts: Average bucket depth: 1.524189
tts: Max bucket depth: 7
*/
uint64 hash_SDBM(string key)
{
uint64 hash = 0;
for (uint c = 0; c < key.Length(); c++)
hash = key[c] + (hash << 6) + (hash << 16) - hash;
return hash;
}
/*
tts: Total collisions: 39905
tts: Buckets filled: 77610 / 131072 (59%)
tts: Average bucket depth: 1.514173
tts: Max bucket depth: 7
*/
uint64 hash_FNV1a(string key)
{
uint64 hash = 14695981039346656037;
for (uint c = 0; c < key.Length(); c++) {
hash = (hash * 1099511628211) ^ key[c];
}
return hash;
}
/*
tts: Total collisions: 40066
tts: Buckets filled: 77449 / 131072 (59%)
tts: Average bucket depth: 1.517321
tts: Max bucket depth: 7
*/
uint hash_CRC32b(string key) {
int j;
uint byte, crc, mask;
crc = 0xFFFFFFFF;
for (uint i = 0; i < key.Length(); i++) {
byte = key[i]; // Get next byte.
crc = crc ^ byte;
for (j = 7; j >= 0; j--) { // Do eight times.
mask = -(crc & 1);
crc = (crc >> 1) ^ (0xEDB88320 & mask);
}
}
return ~crc;
}
class HashMapEntryArrayUint8 {
string key;
array<uint8> value;
HashMapEntryArrayUint8() {}
HashMapEntryArrayUint8(string key, array<uint8> value) {
this.key = key;
this.value = value;
}
}
class HashMapArrayUint8
{
array<array<HashMapEntryArrayUint8>> buckets;
HashMapArrayUint8(int size) {
buckets.resize(size);
}
array<uint8> get(string key) {
int idx = hash_FNV1a(key) % buckets.size();
for (uint i = 0; i < buckets[idx].size(); i++) {
if (buckets[idx][i].key == key) {
return buckets[idx][i].value;
}
}
return array<uint8>();
}
void put(string key, array<uint8> value) {
int idx = hash_FNV1a(key) % buckets.size();
for (uint i = 0; i < buckets[idx].size(); i++) {
if (buckets[idx][i].key == key) {
buckets[idx][i].value = value;
return;
}
}
buckets[idx].insertLast(HashMapEntryArrayUint8(key, value));
}
bool exists(string key) {
int idx = hash_FNV1a(key) % buckets.size();
for (uint i = 0; i < buckets[idx].size(); i++) {
if (buckets[idx][i].key == key) {
return true;
}
}
return false;
}
void stats() {
int total_collisions = 0;
float avg_bucket_depth = 0;
int total_filled_buckets = 0;
uint max_bucket_depth = 0;
for (uint i = 0; i < buckets.size(); i++) {
if (buckets[i].size() > 0) {
total_collisions += buckets[i].size()-1;
total_filled_buckets += 1;
avg_bucket_depth += buckets[i].size();
max_bucket_depth = Math.max(max_bucket_depth, buckets[i].size());
}
}
float bucket_filled_percent = float(total_filled_buckets) / buckets.size();
println("Total collisions: " + total_collisions);
println("Buckets filled: " + total_filled_buckets + " / " + buckets.size() + " (" + int(bucket_filled_percent*100) + "%%)");
println("Average bucket depth: " + (avg_bucket_depth / float(total_filled_buckets)));
println("Max bucket depth: " + max_bucket_depth);
}
}