Files
go-pkg/maps/hash.go
pyihe a20ace4425 feature(maps): HashTable
add HashTable
2021-07-05 20:54:48 +08:00

269 lines
5.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package maps
import "sync"
type (
// fields key, value形式一对一
fields map[interface{}]interface{}
// kv keyvalue形式一对多一个key对应多个键值对
kv map[interface{}]fields
// HashTable 不带锁的Hash表
HashTable struct {
mu sync.RWMutex
values kv
}
)
// init 初始化values
func (h *HashTable) init() {
if h.values == nil {
h.values = make(kv)
}
}
// existKey 判断key是否存在
func (h *HashTable) existKey(key interface{}) bool {
_, exist := h.values[key]
return exist
}
// UnsafeHSet 不加锁的Set
func (h *HashTable) UnsafeHSet(key, field, value interface{}) int {
h.init()
if !h.existKey(key) {
h.values[key] = make(fields)
}
h.values[key][field] = value
return len(h.values[key])
}
// HSet 将key下的field字段设置为value如果key下已经存在field字段直接覆盖旧值返回key下的field数量
func (h *HashTable) HSet(key, field, value interface{}) int {
h.mu.Lock()
defer h.mu.Unlock()
return h.UnsafeHSet(key, field, value)
}
func (h *HashTable) UnsafeHSetNX(key, field, value interface{}) (ok bool) {
h.init()
if !h.existKey(key) {
h.values[key] = make(fields)
}
if _, exist := h.values[key][field]; !exist {
h.values[key][field] = value
ok = true
}
return false
}
// HSetNX 与HSet功能相同不过只有当key下不存在field字段时才执行set操作
func (h *HashTable) HSetNX(key, field, value interface{}) bool {
h.mu.Lock()
defer h.mu.Unlock()
return h.UnsafeHSetNX(key, field, value)
}
func (h *HashTable) UnsafeHGet(key, field interface{}) interface{} {
if len(h.values) == 0 {
return nil
} else {
if !h.existKey(key) {
return nil
}
return h.values[key][field]
}
}
// HGet 返回key下field字段对应的值
func (h *HashTable) HGet(key, field interface{}) interface{} {
h.mu.RLock()
defer h.mu.RUnlock()
return h.UnsafeHGet(key, field)
}
func (h *HashTable) UnsafeHDel(key, field interface{}) bool {
if len(h.values) == 0 {
return false
}
if !h.existKey(key) {
return false
}
if _, ok := h.values[key][field]; ok {
delete(h.values[key], field)
return true
}
return false
}
// HDel 删除key下指定的field字段返回field是否存在
func (h *HashTable) HDel(key, field interface{}) bool {
h.mu.Lock()
defer h.mu.Unlock()
return h.UnsafeHDel(key, field)
}
func (h *HashTable) UnsafeHExists(key, field interface{}) (exist bool) {
if len(h.values) == 0 {
return false
}
if !h.existKey(key) {
return false
}
_, exist = h.values[key][field]
return
}
// HExists 判断是key是否存在field字段
func (h *HashTable) HExists(key, field interface{}) bool {
h.mu.RLock()
defer h.mu.RUnlock()
return h.UnsafeHExists(key, field)
}
func (h *HashTable) UnsafeHLen(key interface{}) int {
if len(h.values) == 0 {
return 0
} else {
return len(h.values[key])
}
}
// HLen 返回key对应的字段数量
func (h *HashTable) HLen(key interface{}) int {
h.mu.RLock()
defer h.mu.RUnlock()
return h.UnsafeHLen(key)
}
func (h *HashTable) UnsafeHGetAll(key interface{}) (values []interface{}) {
if len(h.values) == 0 {
return
}
if !h.existKey(key) {
return
}
for field, value := range h.values[key] {
values = append(values, field, value)
}
return
}
// HGetAll 获取key下所有的field-value值对
func (h *HashTable) HGetAll(key interface{}) (values []interface{}) {
h.mu.RLock()
defer h.mu.RUnlock()
return h.UnsafeHGetAll(key)
}
func (h *HashTable) UnsafeHKeys() (keys []interface{}) {
if len(h.values) == 0 {
return
}
for k := range h.values {
keys = append(keys, k)
}
return
}
// HKeys 返回所有的key
func (h *HashTable) HKeys() (keys []interface{}) {
h.mu.RLock()
defer h.mu.RUnlock()
return h.UnsafeHKeys()
}
func (h *HashTable) UnsafeHFields(key interface{}) (fields []interface{}) {
if len(h.values) == 0 {
return
}
if !h.existKey(key) {
return
}
for field := range h.values[key] {
fields = append(fields, field)
}
return
}
func (h *HashTable) HFields(key interface{}) (fields []interface{}) {
h.mu.RLock()
defer h.mu.RUnlock()
return h.UnsafeHFields(key)
}
func (h *HashTable) UnsafeHValues(key interface{}) (values []interface{}) {
if len(h.values) == 0 {
return
}
if !h.existKey(key) {
return
}
for _, v := range h.values[key] {
values = append(values, v)
}
return
}
// HValues 返回key包含的所有字段对应的值
func (h *HashTable) HValues(key interface{}) (values []interface{}) {
h.mu.RLock()
defer h.mu.RUnlock()
return h.UnsafeHValues(key)
}
func (h *HashTable) UnsafeRangeKeys(fn func(key, field, value interface{}) bool) {
if len(h.values) == 0 {
return
}
for key, fvs := range h.values {
for field, value := range fvs {
if fn(key, field, value) {
return
}
}
}
}
func (h *HashTable) RLockRangeKeys(fn func(key, field, value interface{}) bool) {
h.mu.RLock()
defer h.mu.RUnlock()
h.UnsafeRangeKeys(fn)
}
func (h *HashTable) LockRangeKeys(fn func(key, field, value interface{}) bool) {
h.mu.Lock()
defer h.mu.Unlock()
h.UnsafeRangeKeys(fn)
}
func (h *HashTable) UnsafeRangeFields(key interface{}, fn func(field, value interface{}) bool) {
if len(h.values) == 0 {
return
}
if !h.existKey(key) {
return
}
for field, value := range h.values[key] {
if fn(field, value) {
return
}
}
}
func (h *HashTable) LockRangeFields(key interface{}, fn func(field, value interface{}) bool) {
h.mu.Lock()
defer h.mu.Unlock()
h.UnsafeRangeFields(key, fn)
}
func (h *HashTable) RLockRangeFields(key interface{}, fn func(field, value interface{}) bool) {
h.mu.RLock()
defer h.mu.RUnlock()
h.UnsafeRangeFields(key, fn)
}