github.com/Nigel2392/go-datastructures@v1.1.5/hashmap/hashmap_test.go (about) 1 package hashmap_test 2 3 import ( 4 "strconv" 5 "testing" 6 "time" 7 8 "github.com/Nigel2392/go-datastructures" 9 "github.com/Nigel2392/go-datastructures/hashmap" 10 ) 11 12 type stringHasher string // implements Hasher 13 14 func (s stringHasher) Hash() uint64 { 15 // return the key as a uint64 16 return datastructures.FastStrHash(s) 17 } 18 19 func (s stringHasher) Equals(other stringHasher) bool { 20 return s == other //datastructures.FastStrCmp(s, other) 21 } 22 23 func TestHashMap(t *testing.T) { 24 var ( 25 stringHasherKeys = [...]stringHasher{ 26 "a", "b", "c", "d", "e", "f", "g", "ab", "bc", 27 "cd", "de", "ef", "fg", "sun", "sunny", "flower", "flow", "flight", "flights", "mango", 28 } 29 ) 30 31 var hashTable = hashmap.Map[stringHasher, string]() 32 for _, v := range stringHasherKeys { 33 hashTable.Set(v, string(v)) 34 } 35 36 for _, v := range stringHasherKeys { 37 if val, ok := hashTable.Get(v); !ok || val != string(v) { 38 t.Fatalf("key: %s, value: %s", v, val) 39 } 40 } 41 42 t.Logf("%#v", hashTable) 43 44 for _, v := range stringHasherKeys { 45 if !hashTable.Delete(v) { 46 t.Fatalf("couldn't delete key: %s, value: %s\n%#v", v, v, hashTable) 47 } 48 } 49 50 if hashTable.Len() != 0 { 51 t.Fatalf("Size: %d", hashTable.Len()) 52 } 53 54 for _, v := range stringHasherKeys { 55 if _, ok := hashTable.Get(v); ok { 56 t.Fatalf("key: %s, value: %s", v, v) 57 } 58 } 59 60 hashTable.Range(func(key stringHasher, value string) bool { 61 t.Fatalf("key: %s, value: %s", key, value) 62 return false 63 }) 64 65 t.Logf("%#v", hashTable) 66 67 for _, v := range stringHasherKeys { 68 hashTable.Set(v, string(v)) 69 } 70 71 if hashTable.Len() != len(stringHasherKeys) { 72 t.Fatalf("Size: %d", hashTable.Len()) 73 } 74 75 for _, v := range stringHasherKeys { 76 var val, found = hashTable.Pop(v) 77 if !found || val != string(v) { 78 t.Fatalf("key: %s, value: %s", v, val) 79 } 80 } 81 82 if hashTable.Len() != 0 { 83 t.Fatalf("Size: %d", hashTable.Len()) 84 } 85 86 t.Logf("%#v", hashTable) 87 88 for _, v := range stringHasherKeys { 89 hashTable.Set(v, string(v)) 90 } 91 92 if hashTable.Len() != len(stringHasherKeys) { 93 t.Fatalf("Size: %d", hashTable.Len()) 94 } 95 96 hashTable.Clear() 97 98 if hashTable.Len() != 0 { 99 t.Fatalf("Size: %d after clear", hashTable.Len()) 100 } 101 102 t.Logf("%#v", hashTable) 103 104 for _, v := range stringHasherKeys { 105 hashTable.Set(v, string(v)) 106 } 107 108 if hashTable.Len() != len(stringHasherKeys) { 109 t.Fatalf("Size: %d after set", hashTable.Len()) 110 } 111 112 hashTable.DeleteIf(func(key stringHasher, value string) bool { 113 return true 114 }) 115 116 if hashTable.Len() != 0 { 117 t.Fatalf("Size after DeleteIf: %d", hashTable.Len()) 118 } 119 120 t.Logf("%#v", hashTable) 121 122 } 123 124 var ( 125 SmallArrayKeys = [256]stringHasher{} 126 127 MediumArrayKeys = [256 * 256]stringHasher{} 128 129 LargeArrayKeys = [256 * 256 * 256]stringHasher{} 130 ) 131 132 func initArrays() { 133 var currentTimeUnix = time.Now().UnixNano() 134 for i := 0; i < len(LargeArrayKeys); i++ { 135 var key = stringHasher("key" + strconv.FormatInt(int64(i)+currentTimeUnix, 10)) 136 if i < len(SmallArrayKeys) { 137 SmallArrayKeys[i] = key 138 } 139 if i < len(MediumArrayKeys) { 140 MediumArrayKeys[i] = key 141 } 142 LargeArrayKeys[i] = key 143 } 144 } 145 146 func BenchmarkHashMap_SetSmall(b *testing.B) { 147 b.StopTimer() 148 initArrays() 149 var hashTable = hashmap.Map[stringHasher, string](len(SmallArrayKeys)) 150 for _, v := range SmallArrayKeys { 151 hashTable.Set(v, string(v)) 152 } 153 b.Logf("Starting benchmark with %d items", len(SmallArrayKeys)) 154 var lastKey stringHasher = SmallArrayKeys[len(SmallArrayKeys)-1] 155 b.StartTimer() 156 for i := 0; i < b.N; i++ { 157 if val, ok := hashTable.Get(lastKey); !ok || val != string(lastKey) { 158 b.Fatalf("key: %s, value: %s", lastKey, val) 159 } 160 } 161 } 162 func BenchmarkHashMap_SetMedium(b *testing.B) { 163 b.StopTimer() 164 initArrays() 165 var hashTable = hashmap.Map[stringHasher, string](len(MediumArrayKeys)) 166 for _, v := range MediumArrayKeys { 167 hashTable.Set(v, string(v)) 168 } 169 b.Logf("Starting benchmark with %d items", len(MediumArrayKeys)) 170 var lastKey stringHasher = MediumArrayKeys[len(MediumArrayKeys)-1] 171 b.StartTimer() 172 for i := 0; i < b.N; i++ { 173 if val, ok := hashTable.Get(lastKey); !ok || val != string(lastKey) { 174 b.Fatalf("key: %s, value: %s", lastKey, val) 175 } 176 } 177 } 178 179 func BenchmarkHashMap_SetLarge(b *testing.B) { 180 b.StopTimer() 181 initArrays() 182 var hashTable = hashmap.Map[stringHasher, string](len(LargeArrayKeys)) 183 for _, v := range LargeArrayKeys { 184 hashTable.Set(v, string(v)) 185 } 186 b.Logf("Starting benchmark with %d items", len(LargeArrayKeys)) 187 var lastKey stringHasher = LargeArrayKeys[len(LargeArrayKeys)-1] 188 b.StartTimer() 189 for i := 0; i < b.N; i++ { 190 if val, ok := hashTable.Get(lastKey); !ok || val != string(lastKey) { 191 b.Fatalf("key: %s, value: %s", lastKey, val) 192 } 193 } 194 } 195 196 func BenchmarkSTDMap_Large(b *testing.B) { 197 b.StopTimer() 198 var hashTable = make(map[stringHasher]string, len(LargeArrayKeys)) 199 for _, v := range LargeArrayKeys { 200 hashTable[v] = string(v) 201 } 202 b.Logf("Starting benchmark with %d items", len(LargeArrayKeys)) 203 var lastKey stringHasher = LargeArrayKeys[len(LargeArrayKeys)-1] 204 b.StartTimer() 205 for i := 0; i < b.N; i++ { 206 if val, ok := hashTable[lastKey]; !ok || val != string(lastKey) { 207 b.Fatalf("key: %s, value: %s", lastKey, val) 208 } 209 } 210 }