From 48f48fe78228103623156e1cac06ba986cc46072 Mon Sep 17 00:00:00 2001 From: eson <474420502@qq.com> Date: Mon, 6 May 2019 18:40:09 +0800 Subject: [PATCH] =?UTF-8?q?=E8=BF=98=E9=9C=80=E8=A6=81=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hashmap/bucket.go | 62 +++++++++++++++++++++++++++++++++++++++-- hashmap/hashmap.go | 44 +++++++++++++---------------- hashmap/hashmap_test.go | 2 +- hashmap/table.go | 10 +------ 4 files changed, 80 insertions(+), 38 deletions(-) diff --git a/hashmap/bucket.go b/hashmap/bucket.go index 7433a4a..5c58eb2 100644 --- a/hashmap/bucket.go +++ b/hashmap/bucket.go @@ -1,7 +1,12 @@ package hashmap +import ( + "474420502.top/eson/structure/compare" +) + type hmBucket struct { - data []bucketNode + size uint + data []*bucketNode } type bucketNode struct { @@ -13,6 +18,57 @@ func newBucket() *hmBucket { return &hmBucket{} } -func (bkt *hmBucket) Add(hash uint, k, v interface{}) { - bkt.data = append(bkt.data, bucketNode{key: k, value: v, hash: hash}) +func (bkt *hmBucket) Get(key interface{}, Compare compare.Compare) interface{} { + // bkt.data + for _, n := range bkt.data { + if Compare(n.key, key) == 0 { + return n.value + } + } + return nil +} + +func (bkt *hmBucket) Add(hash uint, k, v interface{}, Compare compare.Compare) { + + for i := uint(0); i < bkt.size; i++ { + n := bkt.data[i] + if Compare(n.key, k) == 0 { + n.hash = hash + n.key = k + n.value = v + return + } + } + + bkt.size++ + if bkt.size < uint(len(bkt.data)) { + n := bkt.data[bkt.size] + n.hash = hash + n.key = k + n.value = v + return + } + + bkt.data = append(bkt.data, &bucketNode{key: k, value: v, hash: hash}) +} + +func (bkt *hmBucket) AddNode(node *bucketNode, Compare compare.Compare) { + + for i := uint(0); i < bkt.size; i++ { + n := bkt.data[i] + if Compare(n.key, node.key) == 0 { + n.hash = node.hash + n.key = node.key + n.value = node.value + panic(123) + return + } + } + + bkt.size++ + if bkt.size < uint(len(bkt.data)) { + bkt.data[bkt.size] = node + return + } + bkt.data = append(bkt.data, node) } diff --git a/hashmap/hashmap.go b/hashmap/hashmap.go index 8d54761..3567850 100644 --- a/hashmap/hashmap.go +++ b/hashmap/hashmap.go @@ -48,24 +48,25 @@ func (hm *HashMap) grow() { newsize := hm.size << 1 // newtable := make([]*avlTree, newsize, newsize) hm.table.Grow(int(newsize - hm.size)) - nodelist := make([]bucketNode, hm.size, hm.size) - i := 0 - hm.table.Traversal(func(cur *bucketNode) { - if cur != nil { - nodelist[i] = cur - i++ - } - }) + nodelist := make([]*bucketNode, hm.size, hm.size) + + var count = 0 + for i := 0; i < len(hm.table.data); i++ { + curbkt := hm.table.data[i] + tnodelist := curbkt.data + for _, n := range tnodelist { + nodelist[count] = n + count++ + } + curbkt.size = 0 + } - var hash, index uint for _, node := range nodelist { - hash = hm.GetHash(node.key) - index = hash % hm.table.cap + index := node.hash % hm.table.cap //bkt := newtable[index] - bkt := hm.table.GetWithNilSet(index, func(data []*avlTree, idx uint) { - data[idx] = avlNew(hm.Compare) - }) - bkt.PutNode(node) + hm.table.data[index].AddNode(node, hm.Compare) + // bkt.data + // bkt.PutNode(node) } hm.countNextGrow() @@ -78,15 +79,8 @@ func (hm *HashMap) Put(key, value interface{}) { tlen := hm.table.Cap() index := hash % tlen - bkt := hm.table.GetWithNilSet(index, func(data []*avlTree, idx uint) { - data[idx] = avlNew(hm.Compare) - }) - - n := &avlNode{key: key, value: value} - if bkt.PutNode(n) { - hm.size++ - hm.grow() - } + bkt := hm.table.GetWithNilSet(index) + bkt.Add(hash, key, value, hm.Compare) } func (hm *HashMap) Get(key interface{}) (interface{}, bool) { @@ -97,7 +91,7 @@ func (hm *HashMap) Get(key interface{}) (interface{}, bool) { bkt := hm.table.Get(index) if bkt != nil { - return bkt.Get(key) + return bkt.Get(key, hm.Compare), true } return nil, false } diff --git a/hashmap/hashmap_test.go b/hashmap/hashmap_test.go index bfbee1d..b9e42cf 100644 --- a/hashmap/hashmap_test.go +++ b/hashmap/hashmap_test.go @@ -51,7 +51,7 @@ func bToMb(b uint64) uint64 { return b / 1024 / 1024 } -var executeCount = 5 +var executeCount = 1 var compareSize = 100000 func BenchmarkPut(b *testing.B) { diff --git a/hashmap/table.go b/hashmap/table.go index 7e3dead..493ebf0 100644 --- a/hashmap/table.go +++ b/hashmap/table.go @@ -27,14 +27,6 @@ func (t *Table) Cap() uint { return t.cap } -func (t *Table) Traversal(every func(bnode *bucketNode)) { - for _, btk := range t.data { - for _, v := range btk.data { - every(&v) - } - } -} - func (t *Table) Grow(size int) { zsize := len(t.data) + size temp := make([]hmBucket, zsize, zsize) @@ -47,7 +39,7 @@ func (t *Table) Get(idx uint) *hmBucket { return &(t.data[idx]) } -func (t *Table) GetWithNilSet(idx uint, DoSetValue func([]*avlTree, uint)) *hmBucket { +func (t *Table) GetWithNilSet(idx uint) *hmBucket { return &(t.data[idx]) }