package hashmap import ( "474420502.top/eson/structure/compare" ) type HashCode func(key interface{}) uint type HashMap struct { growfactor uint slimmingfactor uint table []interface{} GetHash HashCode Compare compare.Compare growsize uint size uint } type bNode struct { Next *bNode Key, Value interface{} } type Bucket struct { size uint head *bNode } 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 = make([]interface{}, initcap, initcap) hm.growsize = initcap - initcap>>2 return hm } func (hm *HashMap) grow() { if hm.size >= hm.growsize { newsize := hm.size << 1 newtable := make([]interface{}, newsize, newsize) hm.growsize = newsize - newsize>>2 hm.size = 0 for _, v := range hm.table { if v != nil { bucket := v.(*Bucket) cur := bucket.head hash := hm.GetHash(cur.Key) index := hash % newsize var bkt *Bucket n := newtable[index] if n == nil { bkt = &Bucket{size: 1} newtable[index] = bkt bkt.head = &bNode{Value: cur.Value, Key: cur.Key} hm.size++ cur = cur.Next } else { bkt = n.(*Bucket) } for ; cur != nil; cur = cur.Next { bn := &bNode{Value: cur.Value, Key: cur.Key} hm.size++ bkt.size++ bn.Next = bkt.head bkt.head = bn } } hm.table = newtable } } } func (hm *HashMap) Put(key, value interface{}) { hash := hm.GetHash(key) tlen := uint(len(hm.table)) index := hash % tlen n := hm.table[index] // if n == nil { // n = avlNew(hm.Compare) // hm.table[index] = n // } // bucket := n.(*avlTree) // if bucket.Put(key, value) { // hm.size++ // if hm.size >= hm.growsize { // newsize := hm.size << 1 // newtable := make([]interface{}, newsize, newsize) // hm.growsize = newsize - newsize>>2 // for _, v := range hm.table { // if v != nil { // cur := v.(*avlTree) // cur.Traversal(func(k, v interface{}) bool { // hash := hm.GetHash(k) // index := hash % newsize // n := newtable[index] // if n == nil { // n = avlNew(hm.Compare) // newtable[index] = n // } // bucket := n.(*avlTree) // bucket.Put(k, v) // return true // }) // } // } // hm.table = newtable // } // } if n == nil { nbucket := &Bucket{size: 1} hm.table[index] = nbucket nbucket.head = &bNode{Value: value, Key: key} hm.size++ hm.grow() return } bkt := n.(*Bucket) cur := bkt.head for cur.Next != nil { if hm.Compare(key, cur.Key) == 0 { cur.Key = key cur.Value = value return } cur = cur.Next } bn := &bNode{Value: value, Key: key} hm.size++ bkt.size++ bn.Next = bkt.head bkt.head = bn hm.grow() }