修改为简单的数据组织
This commit is contained in:
parent
9350dbbd44
commit
d6d4b89dc6
|
@ -12,6 +12,13 @@ type avlNode struct {
|
|||
key, value interface{}
|
||||
}
|
||||
|
||||
func (n *avlNode) clearAttr() {
|
||||
n.parent = nil
|
||||
n.children[0] = nil
|
||||
n.children[1] = nil
|
||||
n.height = 0
|
||||
}
|
||||
|
||||
type avlTree struct {
|
||||
root *avlNode
|
||||
size int
|
||||
|
|
18
hashmap/bucket.go
Normal file
18
hashmap/bucket.go
Normal 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})
|
||||
}
|
|
@ -12,10 +12,8 @@ type HashMap struct {
|
|||
|
||||
table *Table
|
||||
|
||||
GetHash HashCode
|
||||
Compare compare.Compare
|
||||
|
||||
pool *nodePool
|
||||
GetHash HashCode
|
||||
Compare compare.Compare
|
||||
growsize uint
|
||||
size uint
|
||||
}
|
||||
|
@ -32,7 +30,6 @@ func New(hcode HashCode, comp compare.Compare) *HashMap {
|
|||
hm.growfactor = 2
|
||||
hm.GetHash = hcode
|
||||
hm.Compare = comp
|
||||
hm.pool = newNodePool()
|
||||
// initcap := uint(8)
|
||||
hm.table = newTable()
|
||||
hm.countNextGrow()
|
||||
|
@ -43,23 +40,20 @@ func (hm *HashMap) countNextGrow() {
|
|||
hm.growsize = hm.table.Cap() << 1
|
||||
}
|
||||
|
||||
var growcount = 0
|
||||
|
||||
func (hm *HashMap) grow() {
|
||||
if hm.size >= hm.growsize {
|
||||
|
||||
newsize := hm.size << 1
|
||||
// newtable := make([]*avlTree, newsize, newsize)
|
||||
hm.table.Grow(int(newsize - hm.size))
|
||||
nodelist := make([]*avlNode, hm.size, hm.size)
|
||||
nodelist := make([]bucketNode, hm.size, hm.size)
|
||||
i := 0
|
||||
hm.table.Traversal(func(cur *avlTree) {
|
||||
hm.table.Traversal(func(cur *bucketNode) {
|
||||
if cur != nil {
|
||||
cur.Traversal(func(node *avlNode) bool {
|
||||
if node != nil {
|
||||
nodelist[i] = node
|
||||
i++
|
||||
}
|
||||
return true
|
||||
})
|
||||
cur.Clear()
|
||||
nodelist[i] = cur
|
||||
i++
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -79,8 +73,8 @@ func (hm *HashMap) grow() {
|
|||
}
|
||||
|
||||
func (hm *HashMap) Put(key, value interface{}) {
|
||||
hash := hm.GetHash(key)
|
||||
|
||||
hash := hm.GetHash(key)
|
||||
tlen := hm.table.Cap()
|
||||
index := hash % tlen
|
||||
|
||||
|
|
63
hashmap/hashmap2
Normal file
63
hashmap/hashmap2
Normal 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
|
||||
}
|
|
@ -31,6 +31,9 @@ func TestCount(t *testing.T) {
|
|||
hm.Put(i, i)
|
||||
}
|
||||
|
||||
for i := 0; i < 100000; i++ {
|
||||
hm.Put(i, i)
|
||||
}
|
||||
// t.Error(hm.Get(4))
|
||||
}
|
||||
|
||||
|
@ -57,10 +60,11 @@ func BenchmarkPut(b *testing.B) {
|
|||
l := loadTestData()
|
||||
hm := New(HashInt, compare.Int)
|
||||
b.N = len(l) * executeCount
|
||||
for i := 0; i < len(l); i++ {
|
||||
v := l[i]
|
||||
hm.Put(v, v)
|
||||
}
|
||||
|
||||
// for i := 0; i < len(l); i++ {
|
||||
// v := l[i]
|
||||
// hm.Put(v, v)
|
||||
// }
|
||||
|
||||
b.StartTimer()
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -8,13 +8,13 @@ type Table struct {
|
|||
size uint
|
||||
growsize uint
|
||||
|
||||
data []*avlTree
|
||||
data []hmBucket
|
||||
cap uint
|
||||
}
|
||||
|
||||
func newTable() *Table {
|
||||
table := &Table{}
|
||||
table.data = make([]*avlTree, 16, 16)
|
||||
table.data = make([]hmBucket, 16, 16)
|
||||
table.countCap()
|
||||
return table
|
||||
}
|
||||
|
@ -27,30 +27,28 @@ func (t *Table) Cap() uint {
|
|||
return t.cap
|
||||
}
|
||||
|
||||
func (t *Table) Traversal(every func(node *avlTree)) {
|
||||
for _, z := range t.data {
|
||||
every(z)
|
||||
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([]*avlTree, zsize, zsize)
|
||||
temp := make([]hmBucket, zsize, zsize)
|
||||
copy(temp, t.data)
|
||||
t.data = temp
|
||||
t.countCap()
|
||||
}
|
||||
|
||||
func (t *Table) Get(idx uint) *avlTree {
|
||||
return t.data[idx]
|
||||
func (t *Table) Get(idx uint) *hmBucket {
|
||||
return &(t.data[idx])
|
||||
}
|
||||
|
||||
func (t *Table) GetWithNilSet(idx uint, DoSetValue func([]*avlTree, uint)) *avlTree {
|
||||
|
||||
if t.data[idx] == nil {
|
||||
DoSetValue(t.data, idx)
|
||||
}
|
||||
return t.data[idx]
|
||||
func (t *Table) GetWithNilSet(idx uint, DoSetValue func([]*avlTree, uint)) *hmBucket {
|
||||
return &(t.data[idx])
|
||||
}
|
||||
|
||||
// func (arr *Table) Get(idx int) (interface{}, bool) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user