@@ -13,119 +13,100 @@ type node struct {
13
13
next * node
14
14
}
15
15
16
- // HashMap is golang implementation of hashmap
16
+ // HashMap is a Golang implementation of a hashmap
17
17
type HashMap struct {
18
18
capacity uint64
19
19
size uint64
20
20
table []* node
21
21
}
22
22
23
- // New return new HashMap instance
24
- func New () * HashMap {
23
+ // DefaultNew returns a new HashMap instance with default values
24
+ func DefaultNew () * HashMap {
25
25
return & HashMap {
26
26
capacity : defaultCapacity ,
27
27
table : make ([]* node , defaultCapacity ),
28
28
}
29
29
}
30
30
31
- // Make creates a new HashMap instance with input size and capacity
32
- func Make (size , capacity uint64 ) HashMap {
33
- return HashMap {
31
+ // New creates a new HashMap instance with the specified size and capacity
32
+ func New (size , capacity uint64 ) * HashMap {
33
+ return & HashMap {
34
34
size : size ,
35
35
capacity : capacity ,
36
36
table : make ([]* node , capacity ),
37
37
}
38
38
}
39
39
40
- // Get returns value associated with given key
40
+ // Get returns the value associated with the given key
41
41
func (hm * HashMap ) Get (key any ) any {
42
- node := hm .getNodeByHash (hm .hash (key ))
43
-
42
+ node := hm .getNodeByKey (key )
44
43
if node != nil {
45
44
return node .value
46
45
}
47
-
48
46
return nil
49
47
}
50
48
51
- // Put puts new key value in hashmap
52
- func (hm * HashMap ) Put (key any , value any ) any {
53
- return hm .putValue (hm .hash (key ), key , value )
54
- }
55
-
56
- // Contains checks if given key is stored in hashmap
57
- func (hm * HashMap ) Contains (key any ) bool {
58
- node := hm .getNodeByHash (hm .hash (key ))
59
- return node != nil
60
- }
61
-
62
- func (hm * HashMap ) putValue (hash uint64 , key any , value any ) any {
63
- if hm .capacity == 0 {
64
- hm .capacity = defaultCapacity
65
- hm .table = make ([]* node , defaultCapacity )
66
- }
67
-
68
- node := hm .getNodeByHash (hash )
69
-
70
- if node == nil {
71
- hm .table [hash ] = newNode (key , value )
72
-
73
- } else if node .key == key {
74
- hm .table [hash ] = newNodeWithNext (key , value , node )
75
- return value
76
-
49
+ // Put inserts a new key-value pair into the hashmap
50
+ func (hm * HashMap ) Put (key , value any ) {
51
+ index := hm .hash (key )
52
+ if hm .table [index ] == nil {
53
+ hm .table [index ] = & node {key : key , value : value }
77
54
} else {
78
- hm .resize ()
79
- return hm .putValue (hash , key , value )
55
+ current := hm .table [index ]
56
+ for {
57
+ if current .key == key {
58
+ current .value = value
59
+ return
60
+ }
61
+ if current .next == nil {
62
+ break
63
+ }
64
+ current = current .next
65
+ }
66
+ current .next = & node {key : key , value : value }
80
67
}
81
-
82
68
hm .size ++
69
+ if float64 (hm .size )/ float64 (hm .capacity ) > 0.75 {
70
+ hm .resize ()
71
+ }
72
+ }
83
73
84
- return value
85
-
74
+ // Contains checks if the given key is stored in the hashmap
75
+ func (hm * HashMap ) Contains (key any ) bool {
76
+ return hm .getNodeByKey (key ) != nil
86
77
}
87
78
88
- func (hm * HashMap ) getNodeByHash (hash uint64 ) * node {
89
- return hm .table [hash ]
79
+ // getNodeByKey finds the node associated with the given key
80
+ func (hm * HashMap ) getNodeByKey (key any ) * node {
81
+ index := hm .hash (key )
82
+ current := hm .table [index ]
83
+ for current != nil {
84
+ if current .key == key {
85
+ return current
86
+ }
87
+ current = current .next
88
+ }
89
+ return nil
90
90
}
91
91
92
+ // resize doubles the capacity of the hashmap and rehashes all existing entries
92
93
func (hm * HashMap ) resize () {
94
+ oldTable := hm .table
93
95
hm .capacity <<= 1
94
-
95
- tempTable := hm .table
96
-
97
96
hm .table = make ([]* node , hm .capacity )
97
+ hm .size = 0
98
98
99
- for i := 0 ; i < len (tempTable ); i ++ {
100
- node := tempTable [i ]
101
- if node == nil {
102
- continue
99
+ for _ , head := range oldTable {
100
+ for current := head ; current != nil ; current = current .next {
101
+ hm .Put (current .key , current .value )
103
102
}
104
-
105
- hm .table [hm .hash (node .key )] = node
106
- }
107
- }
108
-
109
- func newNode (key any , value any ) * node {
110
- return & node {
111
- key : key ,
112
- value : value ,
113
- }
114
- }
115
-
116
- func newNodeWithNext (key any , value any , next * node ) * node {
117
- return & node {
118
- key : key ,
119
- value : value ,
120
- next : next ,
121
103
}
122
104
}
123
105
106
+ // hash generates a hash value for the given key
124
107
func (hm * HashMap ) hash (key any ) uint64 {
125
108
h := fnv .New64a ()
126
109
_ , _ = h .Write ([]byte (fmt .Sprintf ("%v" , key )))
127
-
128
110
hashValue := h .Sum64 ()
129
-
130
111
return (hm .capacity - 1 ) & (hashValue ^ (hashValue >> 16 ))
131
112
}
0 commit comments