package hashmap import ( "474420502.top/eson/structure/compare" ) type HashCode func(key interface{}) uint type HashMap struct { growfactor uint slimmingfactor uint table *Table GetHash HashCode Compare compare.Compare growsize uint size uint } func HashInt(key interface{}) uint { thekey := uint(key.(int)) hbit := thekey & 0xffffffff lbit := (thekey & 0xffffffff00000000) >> 32 return lbit ^ hbit } func New(hcode HashCode, comp compare.Compare) *HashMap { hm := &HashMap{} hm.growfactor = 2 hm.GetHash = hcode hm.Compare = comp // initcap := uint(8) hm.table = newTable() hm.countNextGrow() return hm } func (hm *HashMap) countNextGrow() { hm.growsize = hm.table.Cap() << 1 } 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) i := 0 hm.table.Traversal(func(cur *avlTree) { if cur != nil { cur.Traversal(func(node *avlNode) bool { nodelist[i] = node i++ return true }) cur.Clear() } }) var hash, index uint for _, node := range nodelist { hash = hm.GetHash(node.key) index = hash % hm.table.cap //bkt := newtable[index] bkt := hm.table.GetWithNilSet(index, func(data []*avlTree, idx uint) { data[idx] = avlNew(hm.Compare) }) node.clearAttr() bkt.PutNode(node) } hm.countNextGrow() } } func (hm *HashMap) Put(key, value interface{}) { hash := hm.GetHash(key) tlen := hm.table.Cap() index := hash % tlen bkt := hm.table.GetWithNilSet(index, func(data []*avlTree, idx uint) { data[idx] = avlNew(hm.Compare) }) if bkt.Put(key, value) { hm.size++ hm.grow() } } func (hm *HashMap) Get(key interface{}) (interface{}, bool) { hash := hm.GetHash(key) tlen := hm.table.Cap() index := hash % tlen bkt := hm.table.Get(index) if bkt != nil { return bkt.Get(key) } return nil, false }