修改为简单的数据组织

This commit is contained in:
eson 2019-05-06 17:01:18 +08:00
parent 9350dbbd44
commit d6d4b89dc6
7 changed files with 118 additions and 95 deletions

View File

@ -12,6 +12,13 @@ type avlNode struct {
key, value interface{} key, value interface{}
} }
func (n *avlNode) clearAttr() {
n.parent = nil
n.children[0] = nil
n.children[1] = nil
n.height = 0
}
type avlTree struct { type avlTree struct {
root *avlNode root *avlNode
size int size int

18
hashmap/bucket.go Normal file
View File

@ -0,0 +1,18 @@
package hashmap
type hmBucket struct {
data []bucketNode
}
type bucketNode struct {
hash uint
key, value interface{}
}
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})
}

View File

@ -12,10 +12,8 @@ type HashMap struct {
table *Table table *Table
GetHash HashCode GetHash HashCode
Compare compare.Compare Compare compare.Compare
pool *nodePool
growsize uint growsize uint
size uint size uint
} }
@ -32,7 +30,6 @@ func New(hcode HashCode, comp compare.Compare) *HashMap {
hm.growfactor = 2 hm.growfactor = 2
hm.GetHash = hcode hm.GetHash = hcode
hm.Compare = comp hm.Compare = comp
hm.pool = newNodePool()
// initcap := uint(8) // initcap := uint(8)
hm.table = newTable() hm.table = newTable()
hm.countNextGrow() hm.countNextGrow()
@ -43,23 +40,20 @@ func (hm *HashMap) countNextGrow() {
hm.growsize = hm.table.Cap() << 1 hm.growsize = hm.table.Cap() << 1
} }
var growcount = 0
func (hm *HashMap) grow() { func (hm *HashMap) grow() {
if hm.size >= hm.growsize { if hm.size >= hm.growsize {
newsize := hm.size << 1 newsize := hm.size << 1
// newtable := make([]*avlTree, newsize, newsize) // newtable := make([]*avlTree, newsize, newsize)
hm.table.Grow(int(newsize - hm.size)) hm.table.Grow(int(newsize - hm.size))
nodelist := make([]*avlNode, hm.size, hm.size) nodelist := make([]bucketNode, hm.size, hm.size)
i := 0 i := 0
hm.table.Traversal(func(cur *avlTree) { hm.table.Traversal(func(cur *bucketNode) {
if cur != nil { if cur != nil {
cur.Traversal(func(node *avlNode) bool { nodelist[i] = cur
if node != nil { i++
nodelist[i] = node
i++
}
return true
})
cur.Clear()
} }
}) })
@ -79,8 +73,8 @@ func (hm *HashMap) grow() {
} }
func (hm *HashMap) Put(key, value interface{}) { func (hm *HashMap) Put(key, value interface{}) {
hash := hm.GetHash(key)
hash := hm.GetHash(key)
tlen := hm.table.Cap() tlen := hm.table.Cap()
index := hash % tlen index := hash % tlen

63
hashmap/hashmap2 Normal file
View File

@ -0,0 +1,63 @@
package hashmap
import "fmt"
type HashMap struct {
hm map[interface{}]interface{}
}
// New instantiates a hash map.
func New() *HashMap {
return &HashMap{hm: make(map[interface{}]interface{})}
}
// Put inserts element into the map.
func (hm *HashMap) Put(key interface{}, value interface{}) {
hm.hm[key] = value
}
func (hm *HashMap) Get(key interface{}) (value interface{}, isfound bool) {
value, isfound = hm.hm[key]
return
}
func (hm *HashMap) Remove(key interface{}) {
delete(hm.hm, key)
}
func (hm *HashMap) Empty() bool {
return len(hm.hm) == 0
}
func (hm *HashMap) Size() int {
return len(hm.hm)
}
func (hm *HashMap) Keys() []interface{} {
keys := make([]interface{}, len(hm.hm))
count := 0
for key := range hm.hm {
keys[count] = key
count++
}
return keys
}
func (hm *HashMap) Values() []interface{} {
values := make([]interface{}, len(hm.hm))
count := 0
for _, value := range hm.hm {
values[count] = value
count++
}
return values
}
func (hm *HashMap) Clear() {
hm.hm = make(map[interface{}]interface{})
}
func (hm *HashMap) String() string {
str := fmt.Sprintf("%v", hm.hm)
return str
}

View File

@ -31,6 +31,9 @@ func TestCount(t *testing.T) {
hm.Put(i, i) hm.Put(i, i)
} }
for i := 0; i < 100000; i++ {
hm.Put(i, i)
}
// t.Error(hm.Get(4)) // t.Error(hm.Get(4))
} }
@ -57,10 +60,11 @@ func BenchmarkPut(b *testing.B) {
l := loadTestData() l := loadTestData()
hm := New(HashInt, compare.Int) hm := New(HashInt, compare.Int)
b.N = len(l) * executeCount b.N = len(l) * executeCount
for i := 0; i < len(l); i++ {
v := l[i] // for i := 0; i < len(l); i++ {
hm.Put(v, v) // v := l[i]
} // hm.Put(v, v)
// }
b.StartTimer() b.StartTimer()

View File

@ -1,61 +0,0 @@
package hashmap
import (
"474420502.top/eson/structure/lastack"
)
type nodePool struct {
cache *lastack.Stack
data []avlNode
size int
growSize int
slimmingSize int
}
func newNodePool() *nodePool {
p := &nodePool{}
p.cache = lastack.New()
p.data = make([]avlNode, 16, 16)
p.countNextGrow()
return p
}
func (pool *nodePool) Get() *avlNode {
if !pool.cache.Empty() {
v, _ := pool.cache.Pop()
return v.(*avlNode)
}
pool.Grow()
cur := &pool.data[pool.size]
pool.size++
return cur
}
func (pool *nodePool) Recycling(n *avlNode) {
pool.cache.Push(n)
}
func (pool *nodePool) Grow() {
if pool.size >= len(pool.data) {
growsize := pool.size << 1
temp := make([]avlNode, growsize, growsize)
copy(temp, pool.data)
pool.data = temp
pool.countNextGrow()
}
}
func (pool *nodePool) slimming() {
if pool.size <= pool.slimmingSize {
growsize := len(pool.data) - pool.slimmingSize<<1
temp := make([]avlNode, growsize, growsize)
copy(temp, pool.data)
pool.data = temp
pool.countNextGrow()
}
}
func (pool *nodePool) countNextGrow() {
pool.growSize = len(pool.data)
pool.slimmingSize = pool.growSize << 1
}

View File

@ -8,13 +8,13 @@ type Table struct {
size uint size uint
growsize uint growsize uint
data []*avlTree data []hmBucket
cap uint cap uint
} }
func newTable() *Table { func newTable() *Table {
table := &Table{} table := &Table{}
table.data = make([]*avlTree, 16, 16) table.data = make([]hmBucket, 16, 16)
table.countCap() table.countCap()
return table return table
} }
@ -27,30 +27,28 @@ func (t *Table) Cap() uint {
return t.cap return t.cap
} }
func (t *Table) Traversal(every func(node *avlTree)) { func (t *Table) Traversal(every func(bnode *bucketNode)) {
for _, z := range t.data { for _, btk := range t.data {
every(z) for _, v := range btk.data {
every(&v)
}
} }
} }
func (t *Table) Grow(size int) { func (t *Table) Grow(size int) {
zsize := len(t.data) + size zsize := len(t.data) + size
temp := make([]*avlTree, zsize, zsize) temp := make([]hmBucket, zsize, zsize)
copy(temp, t.data) copy(temp, t.data)
t.data = temp t.data = temp
t.countCap() t.countCap()
} }
func (t *Table) Get(idx uint) *avlTree { func (t *Table) Get(idx uint) *hmBucket {
return t.data[idx] return &(t.data[idx])
} }
func (t *Table) GetWithNilSet(idx uint, DoSetValue func([]*avlTree, uint)) *avlTree { func (t *Table) GetWithNilSet(idx uint, DoSetValue func([]*avlTree, uint)) *hmBucket {
return &(t.data[idx])
if t.data[idx] == nil {
DoSetValue(t.data, idx)
}
return t.data[idx]
} }
// func (arr *Table) Get(idx int) (interface{}, bool) { // func (arr *Table) Get(idx int) (interface{}, bool) {