hashmap so bad
This commit is contained in:
parent
5f47199d08
commit
36743be520
|
@ -16,7 +16,7 @@ const NumberMax = 50000000
|
|||
|
||||
func TestSave(t *testing.T) {
|
||||
|
||||
f, err := os.OpenFile("../l.log", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
|
||||
f, err := os.OpenFile("l.log", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
|
|
|
@ -2,19 +2,21 @@ package hashmap
|
|||
|
||||
import (
|
||||
"474420502.top/eson/structure/compare"
|
||||
|
||||
"474420502.top/eson/structure/sparse_array/array3"
|
||||
)
|
||||
|
||||
type HashCode func(key interface{}) uint
|
||||
|
||||
type HashMap struct {
|
||||
growfactor uint
|
||||
table *array3.Array3
|
||||
growfactor uint
|
||||
slimmingfactor uint
|
||||
|
||||
table []interface{}
|
||||
|
||||
GetHash HashCode
|
||||
Compare compare.Compare
|
||||
size uint
|
||||
|
||||
growsize uint
|
||||
size uint
|
||||
}
|
||||
|
||||
type bNode struct {
|
||||
|
@ -39,47 +41,126 @@ func New(hcode HashCode, comp compare.Compare) *HashMap {
|
|||
hm.growfactor = 2
|
||||
hm.GetHash = hcode
|
||||
hm.Compare = comp
|
||||
hm.table = array3.NewWithCap(hm.growfactor<<2, hm.growfactor<<2, hm.growfactor<<2)
|
||||
initcap := uint(8)
|
||||
hm.table = make([]interface{}, initcap, initcap)
|
||||
hm.growsize = initcap - initcap>>2
|
||||
return hm
|
||||
}
|
||||
|
||||
func (hm *HashMap) grow() {
|
||||
if hm.size >= hm.growsize {
|
||||
newsize := hm.size << 1
|
||||
newtable := make([]interface{}, newsize, newsize)
|
||||
hm.growsize = newsize - newsize>>2
|
||||
hm.size = 0
|
||||
|
||||
for _, v := range hm.table {
|
||||
if v != nil {
|
||||
bucket := v.(*Bucket)
|
||||
cur := bucket.head
|
||||
hash := hm.GetHash(cur.Key)
|
||||
index := hash % newsize
|
||||
var bkt *Bucket
|
||||
n := newtable[index]
|
||||
|
||||
if n == nil {
|
||||
bkt = &Bucket{size: 1}
|
||||
newtable[index] = bkt
|
||||
bkt.head = &bNode{Value: cur.Value, Key: cur.Key}
|
||||
hm.size++
|
||||
cur = cur.Next
|
||||
} else {
|
||||
bkt = n.(*Bucket)
|
||||
}
|
||||
|
||||
for ; cur != nil; cur = cur.Next {
|
||||
bn := &bNode{Value: cur.Value, Key: cur.Key}
|
||||
hm.size++
|
||||
bkt.size++
|
||||
bn.Next = bkt.head
|
||||
bkt.head = bn
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
hm.table = newtable
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (hm *HashMap) Put(key, value interface{}) {
|
||||
hash := hm.GetHash(key)
|
||||
// log.Println(hm.table.Cap())
|
||||
index := hash % hm.table.Cap()
|
||||
n, _ := hm.table.GetOrSet(index, func(data []interface{}, index uint) {
|
||||
data[index] = avlNew(hm.Compare)
|
||||
// data[index] = &Bucket{}
|
||||
})
|
||||
|
||||
// bucket := n.(*Bucket)
|
||||
// cur := bucket.head
|
||||
tlen := uint(len(hm.table))
|
||||
index := hash % tlen
|
||||
n := hm.table[index]
|
||||
|
||||
// if cur != nil {
|
||||
// for cur.Next != nil {
|
||||
// if hm.Compare(key, cur.Key) == 0 {
|
||||
// cur.Key = key
|
||||
// cur.Value = value
|
||||
// return
|
||||
// }
|
||||
// cur = cur.Next
|
||||
// }
|
||||
// } else {
|
||||
// bucket.head = &bNode{Value: value, Key: key}
|
||||
// bucket.size++
|
||||
// hm.size++
|
||||
// return
|
||||
// if n == nil {
|
||||
// n = avlNew(hm.Compare)
|
||||
// hm.table[index] = n
|
||||
// }
|
||||
|
||||
// bn := &bNode{Value: value, Key: key}
|
||||
// hm.size++
|
||||
// bucket.size++
|
||||
// bucket := n.(*avlTree)
|
||||
// if bucket.Put(key, value) {
|
||||
// hm.size++
|
||||
|
||||
// bn.Next = bucket.head
|
||||
// bucket.head = bn
|
||||
// if hm.size >= hm.growsize {
|
||||
// newsize := hm.size << 1
|
||||
// newtable := make([]interface{}, newsize, newsize)
|
||||
// hm.growsize = newsize - newsize>>2
|
||||
|
||||
bucket := n.(*avlTree)
|
||||
if bucket.Put(key, value) {
|
||||
// for _, v := range hm.table {
|
||||
// if v != nil {
|
||||
// cur := v.(*avlTree)
|
||||
// cur.Traversal(func(k, v interface{}) bool {
|
||||
// hash := hm.GetHash(k)
|
||||
// index := hash % newsize
|
||||
// n := newtable[index]
|
||||
// if n == nil {
|
||||
// n = avlNew(hm.Compare)
|
||||
// newtable[index] = n
|
||||
// }
|
||||
// bucket := n.(*avlTree)
|
||||
// bucket.Put(k, v)
|
||||
// return true
|
||||
// })
|
||||
|
||||
// }
|
||||
// }
|
||||
|
||||
// hm.table = newtable
|
||||
|
||||
// }
|
||||
// }
|
||||
|
||||
if n == nil {
|
||||
nbucket := &Bucket{size: 1}
|
||||
hm.table[index] = nbucket
|
||||
nbucket.head = &bNode{Value: value, Key: key}
|
||||
hm.size++
|
||||
|
||||
hm.grow()
|
||||
return
|
||||
}
|
||||
|
||||
bkt := n.(*Bucket)
|
||||
cur := bkt.head
|
||||
|
||||
for cur.Next != nil {
|
||||
if hm.Compare(key, cur.Key) == 0 {
|
||||
cur.Key = key
|
||||
cur.Value = value
|
||||
return
|
||||
}
|
||||
cur = cur.Next
|
||||
}
|
||||
|
||||
bn := &bNode{Value: value, Key: key}
|
||||
hm.size++
|
||||
bkt.size++
|
||||
|
||||
bn.Next = bkt.head
|
||||
bkt.head = bn
|
||||
|
||||
hm.grow()
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
func TestCount(t *testing.T) {
|
||||
hm := New(HashInt, compare.Int)
|
||||
|
||||
for i := 0; i < 1000000; i++ {
|
||||
for i := 0; i < 1000; i++ {
|
||||
hm.Put(i, i)
|
||||
}
|
||||
}
|
||||
|
@ -32,18 +32,18 @@ func bToMb(b uint64) uint64 {
|
|||
|
||||
func BenchmarkCount(b *testing.B) {
|
||||
hm := New(HashInt, compare.Int)
|
||||
b.N = 10000
|
||||
b.N = 100000
|
||||
for i := 0; i < b.N; i++ {
|
||||
hm.Put(i, i)
|
||||
}
|
||||
|
||||
b.Log(hm.table.Cap(), hm.size)
|
||||
b.Log(len(hm.table), hm.size)
|
||||
PrintMemUsage()
|
||||
}
|
||||
|
||||
func BenchmarkGoCount(b *testing.B) {
|
||||
m := make(map[int]int)
|
||||
b.N = 10000
|
||||
b.N = 100000
|
||||
for i := 0; i < b.N; i++ {
|
||||
m[i] = i
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user