mirror of
https://github.com/duke-git/lancet.git
synced 2026-03-01 00:35:28 +08:00
Compare commits
5 Commits
9094cb29bf
...
4eeeabb227
| Author | SHA1 | Date | |
|---|---|---|---|
| 4eeeabb227 | |||
| b3437fdddf | |||
| 312dcab369 | |||
| 0cb89f4f46 | |||
| a2dec87995 |
@@ -41,7 +41,7 @@ func NewHashMapWithCapacity(size, capacity uint64) *HashMap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get return the value of given key in hash map
|
// Get return the value of given key in hashmap
|
||||||
func (hm *HashMap) Get(key any) any {
|
func (hm *HashMap) Get(key any) any {
|
||||||
hashValue := hm.hash(key)
|
hashValue := hm.hash(key)
|
||||||
node := hm.table[hashValue]
|
node := hm.table[hashValue]
|
||||||
@@ -52,6 +52,65 @@ func (hm *HashMap) Get(key any) any {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Put new key value in hashmap
|
||||||
|
func (hm *HashMap) Put(key any, value any) any {
|
||||||
|
return hm.putValue(hm.hash(key), key, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (hm *HashMap) putValue(hash uint64, key, value any) any {
|
||||||
|
if hm.capacity == 0 {
|
||||||
|
hm.capacity = defaultMapCapacity
|
||||||
|
hm.table = make([]*mapNode, defaultMapCapacity)
|
||||||
|
}
|
||||||
|
|
||||||
|
node := hm.table[hash]
|
||||||
|
if node == nil {
|
||||||
|
hm.table[hash] = newMapNode(key, value)
|
||||||
|
} else if node.key == key {
|
||||||
|
hm.table[hash] = newMapNodeWithNext(key, value, node)
|
||||||
|
return value
|
||||||
|
} else {
|
||||||
|
hm.resize()
|
||||||
|
return hm.putValue(hash, value, value)
|
||||||
|
}
|
||||||
|
hm.size++
|
||||||
|
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete item by given key in hashmap
|
||||||
|
func (hm *HashMap) Delete(key any) {
|
||||||
|
hash := hm.hash(key)
|
||||||
|
node := hm.table[hash]
|
||||||
|
if node == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
hm.table = append(hm.table[:hash], hm.table[hash+1:]...)
|
||||||
|
hm.size--
|
||||||
|
}
|
||||||
|
|
||||||
|
// Contains checks if given key is in hashmap or not
|
||||||
|
func (hm *HashMap) Contains(key any) bool {
|
||||||
|
node := hm.table[hm.hash(key)]
|
||||||
|
return node != nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (hm *HashMap) resize() {
|
||||||
|
hm.capacity <<= 1
|
||||||
|
|
||||||
|
tempTable := hm.table
|
||||||
|
|
||||||
|
for i := 0; i < len(tempTable); i++ {
|
||||||
|
node := tempTable[i]
|
||||||
|
if node == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
hm.table[hm.hash(node.key)] = node
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (hm *HashMap) hash(key any) uint64 {
|
func (hm *HashMap) hash(key any) uint64 {
|
||||||
h := fnv.New64a()
|
h := fnv.New64a()
|
||||||
_, _ = h.Write([]byte(fmt.Sprintf("%v", key)))
|
_, _ = h.Write([]byte(fmt.Sprintf("%v", key)))
|
||||||
@@ -61,9 +120,17 @@ func (hm *HashMap) hash(key any) uint64 {
|
|||||||
return (hm.capacity - 1) & (hashValue ^ (hashValue >> 16))
|
return (hm.capacity - 1) & (hashValue ^ (hashValue >> 16))
|
||||||
}
|
}
|
||||||
|
|
||||||
func newMapNode(key any, value any) *mapNode {
|
func newMapNode(key, value any) *mapNode {
|
||||||
return &mapNode{
|
return &mapNode{
|
||||||
key: key,
|
key: key,
|
||||||
value: value,
|
value: value,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newMapNodeWithNext(key, value any, next *mapNode) *mapNode {
|
||||||
|
return &mapNode{
|
||||||
|
key: key,
|
||||||
|
value: value,
|
||||||
|
next: next,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package datastructure
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/duke-git/lancet/v2/internal"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestHashMap_PutAndGet(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestHashMap_PutAndGet")
|
||||||
|
|
||||||
|
hm := NewHashMap()
|
||||||
|
|
||||||
|
hm.Put("abc", 3)
|
||||||
|
assert.Equal(3, hm.Get("abc"))
|
||||||
|
assert.IsNil(hm.Get("abcd"))
|
||||||
|
|
||||||
|
hm.Put("abc", 4)
|
||||||
|
assert.Equal(4, hm.Get("abc"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHashMap_Delete(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestHashMap_Delete")
|
||||||
|
|
||||||
|
hm := NewHashMap()
|
||||||
|
|
||||||
|
hm.Put("abc", 3)
|
||||||
|
assert.Equal(3, hm.Get("abc"))
|
||||||
|
|
||||||
|
hm.Delete("abc")
|
||||||
|
assert.IsNil(hm.Get("abc"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHashMap_Contains(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestHashMap_Contains")
|
||||||
|
|
||||||
|
hm := NewHashMap()
|
||||||
|
assert.Equal(false, hm.Contains("abc"))
|
||||||
|
|
||||||
|
hm.Put("abc", 3)
|
||||||
|
assert.Equal(true, hm.Contains("abc"))
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user