-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhashtable.go
More file actions
executable file
·99 lines (64 loc) · 1.49 KB
/
hashtable.go
File metadata and controls
executable file
·99 lines (64 loc) · 1.49 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
package main
import "fmt"
const (
INITIAL_SIZE = 1024
)
type KeyVal struct {
key string
val interface{}
}
type HashTable struct {
buckets []*SingleList
}
func (this *HashTable) Put(key string, value interface{}) {
bucket := this.buckets[elfHash(key, INITIAL_SIZE)]
bucket.Push(&KeyVal{key, value})
}
func (this *HashTable) Get(key string) (interface{}) {
bucket := this.buckets[elfHash(key, INITIAL_SIZE)]
for i := 0; i < bucket.Length(); i++ {
keyval := bucket.Get(i).(*KeyVal)
if keyval.key == key {
return keyval.val
}
}
return nil
}
func (this *HashTable) Stats() string {
out := "Hash Table Buckets:"
for i := 0; i < INITIAL_SIZE; i++ {
if this.buckets[i].Length() > 0 {
out = fmt.Sprintf("%s %d(%d)", out, i, this.buckets[i].Length())
}
}
return out
}
func (this *HashTable) Length() int {
length := 0
for i := 0; i < INITIAL_SIZE; i++ {
if this.buckets[i].Length() > 0 {
length += 1
}
}
return length
}
func NewHashTable() *HashTable {
table := HashTable{make([]*SingleList, INITIAL_SIZE, INITIAL_SIZE)}
for i := 0; i < INITIAL_SIZE; i++ {
table.buckets[i] = NewLinkedList()
}
return &table
}
// this is a hash function that was (is?) used in unix.
func elfHash(toHash string, max int) int {
hashValue := 0
for i := 0; i < len(toHash); i++ {
hashValue = (hashValue << 4) + int(toHash[i])
hiBits := hashValue & 0xF0000000
if hiBits != 0 {
hashValue ^= hiBits >> 24
}
hashValue &= ^hiBits
}
return hashValue % max
}