修改为简单的数据组织
This commit is contained in:
parent
9350dbbd44
commit
d6d4b89dc6
|
@ -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
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
|
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
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)
|
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()
|
||||||
|
|
||||||
|
|
|
@ -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
|
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) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user