86 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			86 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package hashmap
 | |
| 
 | |
| import (
 | |
| 	"474420502.top/eson/structure/compare"
 | |
| 
 | |
| 	"474420502.top/eson/structure/sparse_array/array3"
 | |
| )
 | |
| 
 | |
| type HashCode func(key interface{}) uint
 | |
| 
 | |
| type HashMap struct {
 | |
| 	growfactor uint
 | |
| 	table      *array3.Array3
 | |
| 
 | |
| 	GetHash HashCode
 | |
| 	Compare compare.Compare
 | |
| 	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
 | |
| 	hm.table = array3.NewWithCap(hm.growfactor<<2, hm.growfactor<<2, hm.growfactor<<2)
 | |
| 	return hm
 | |
| }
 | |
| 
 | |
| func (hm *HashMap) Put(key, value interface{}) {
 | |
| 	hash := hm.GetHash(key)
 | |
| 	// log.Println(hm.table.Cap())
 | |
| 	index := hash % hm.table.Cap()
 | |
| 	n, _ := hm.table.GetOrSet(index, func(data []interface{}, index uint) {
 | |
| 		data[index] = avlNew(hm.Compare)
 | |
| 		// data[index] = &Bucket{}
 | |
| 	})
 | |
| 
 | |
| 	// bucket := n.(*Bucket)
 | |
| 	// cur := bucket.head
 | |
| 
 | |
| 	// if cur != nil {
 | |
| 	// 	for cur.Next != nil {
 | |
| 	// 		if hm.Compare(key, cur.Key) == 0 {
 | |
| 	// 			cur.Key = key
 | |
| 	// 			cur.Value = value
 | |
| 	// 			return
 | |
| 	// 		}
 | |
| 	// 		cur = cur.Next
 | |
| 	// 	}
 | |
| 	// } else {
 | |
| 	// 	bucket.head = &bNode{Value: value, Key: key}
 | |
| 	// 	bucket.size++
 | |
| 	// 	hm.size++
 | |
| 	// 	return
 | |
| 	// }
 | |
| 
 | |
| 	// bn := &bNode{Value: value, Key: key}
 | |
| 	// hm.size++
 | |
| 	// bucket.size++
 | |
| 
 | |
| 	// bn.Next = bucket.head
 | |
| 	// bucket.head = bn
 | |
| 
 | |
| 	bucket := n.(*avlTree)
 | |
| 	if bucket.Put(key, value) {
 | |
| 		hm.size++
 | |
| 	}
 | |
| }
 |