go 实现hashtable

const (
	dicthtDefaultSize rune = 1 << 6

	dicthtDefaultSizeMask = dicthtDefaultSize - 1
)

//节点用双链表
type DictEntry struct {
	Key  string
	Val  interface{}
	Pre  *DictEntry
	Next *DictEntry
}

type Dictht struct {
	Table    map[rune]*DictEntry //节点map
	Size     rune                //桶大小
	SizeMask rune                //掩码
	Used     int                 //已使用空间
}

type Dict struct {
	Ht [2]*Dictht //1,2号dict

	Rehashdx int //rehash signal
}

func NewTable() *Dict {
	size := dicthtDefaultSize

	ht1 := &Dictht{
		Table:    make(map[rune]*DictEntry, size),
		Size:     size,
		SizeMask: dicthtDefaultSizeMask,
		Used:     0,
	}
	ht2 := ht1
	return &Dict{
		Ht:       [2]*Dictht{ht1, ht2},
		Rehashdx: 0,
	}
}

func (dict *Dict) Put(key string, value interface{}) {

	if dict.Rehashdx == 0 {
		//use dict[0] as main operation
		dict.Ht[0].Put(key, value)
	}
}

func (dict *Dict) Get(key string) interface{} {
	if dict.Rehashdx == 0 {
		//use dict[0] as main operation

		return dict.Ht[0].Get(key)
	}
	return nil
}

func (dictht *Dictht) Get(key string) interface{} {
	//get data from bucket
	entry := &DictEntry{
		Key:  key,
		Pre:  nil,
		Next: nil,
	}

	if item, ok := dictht.Table[dictht.GetDicthtIndex(key)]; ok {
		if getEntry, ok := item.FindDictEntry(entry); ok {
			return getEntry.Val
		}
	}
	return nil
}
func (dictht *Dictht) Put(key string, value interface{}) {

	//find bucket
	entry := &DictEntry{
		Key:  key,
		Val:  value,
		Pre:  nil,
		Next: nil,
	}
	if item, ok := dictht.Table[dictht.GetDicthtIndex(key)]; ok {
		if _, ok := item.FindDictEntry(entry); ok {
			item.AddDictEntry(entry)
		}
	} else {
		dictht.Table[dictht.GetDicthtIndex(key)] = entry
		dictht.Table[dictht.GetDicthtIndex(key)].AddDictEntry(entry)
	}
}

func (entry *DictEntry) AddDictEntry(dictEntry *DictEntry) {
	head := entry
	if head == nil {
		entry = dictEntry
		return
	}

	for head.Next != nil {
		head = head.Next
	}

	head.Next = dictEntry
	dictEntry.Pre = head
	return
}

func (entry *DictEntry) FindDictEntry(dictEntry *DictEntry) (*DictEntry, bool) {

	head := entry

	if head == nil {
		return nil, false
	}

	for head.Next != nil {
		if head.Key == dictEntry.Key {
			return head, true
		}
		head = head.Next
	}

	return nil, false
}

//print dict data
func (dict *Dict) Print() {

}

/*func (table *HashTable) Get(key int) *Node {

}

func (table *HashTable) Delete(node *Node) {

}

func (table *HashTable) Increase(size int) {

}*/

//time33 hash function
func (dictht *Dictht) GetDicthtIndex(key string) rune {
	hash := int32(5381)
	kLen := len([]byte(key))
	for i := 0; i < kLen; i++ {
		hash = 1<<5 + 1 + int32([]byte(key)[i])
	}
	return hash & dictht.SizeMask
}

func main() {
	table := internal.NewTable()

	table.Put("hello", "world")

	table.Put("3243", "34321321")

	table.Put("hello2", "3433")

	fmt.Println(table.Get("hello2"))
}

复制代码