Files
gf/g/container/gmap/gmap_string_interface_map.go

261 lines
6.1 KiB
Go
Raw Normal View History

// Copyright 2017 gf Author(https://github.com/gogf/gf). All Rights Reserved.
2017-12-29 16:03:30 +08:00
//
// This Source Code Form is subject to the terms of the MIT License.
2019-02-01 17:30:23 +08:00
// If a copy of the MIT was not distributed with gm file,
// You can obtain one at https://github.com/gogf/gf.
2017-12-29 16:03:30 +08:00
//
2017-12-31 18:19:58 +08:00
2017-11-23 10:21:28 +08:00
package gmap
import (
"github.com/gogf/gf/g/internal/rwmutex"
"github.com/gogf/gf/g/util/gconv"
2017-11-23 10:21:28 +08:00
)
type StringInterfaceMap struct {
mu *rwmutex.RWMutex
m map[string]interface{}
2017-11-23 10:21:28 +08:00
}
func NewStringInterfaceMap(unsafe...bool) *StringInterfaceMap {
2017-11-23 10:21:28 +08:00
return &StringInterfaceMap{
m : make(map[string]interface{}),
mu : rwmutex.New(unsafe...),
2017-11-23 10:21:28 +08:00
}
}
2019-02-01 22:25:58 +08:00
func NewStringInterfaceMapFrom(m map[string]interface{}, unsafe...bool) *StringInterfaceMap {
return &StringInterfaceMap{
m : m,
mu : rwmutex.New(unsafe...),
}
}
func NewStringInterfaceMapFromArray(keys []string, values []interface{}, unsafe...bool) *StringInterfaceMap {
m := make(map[string]interface{})
l := len(values)
for i, k := range keys {
if i < l {
m[k] = values[i]
} else {
m[k] = interface{}(nil)
}
}
return &StringInterfaceMap{
m : m,
mu : rwmutex.New(unsafe...),
}
}
// 给定回调函数对原始内容进行遍历回调函数返回true表示继续遍历否则停止遍历
2019-02-01 17:30:23 +08:00
func (gm *StringInterfaceMap) Iterator(f func (k string, v interface{}) bool) {
gm.mu.RLock()
defer gm.mu.RUnlock()
for k, v := range gm.m {
2018-04-11 16:06:45 +08:00
if !f(k, v) {
break
}
}
}
2019-02-01 22:25:58 +08:00
// 哈希表克隆.
func (gm *StringInterfaceMap) Clone() *StringInterfaceMap {
return NewStringInterfaceMapFrom(gm.Map(), !gm.mu.IsSafe())
}
// 返回当前哈希表的数据Map.
func (gm *StringInterfaceMap) Map() map[string]interface{} {
2017-11-23 10:21:28 +08:00
m := make(map[string]interface{})
2019-02-01 17:30:23 +08:00
gm.mu.RLock()
for k, v := range gm.m {
2017-11-23 10:21:28 +08:00
m[k] = v
}
2019-02-01 17:30:23 +08:00
gm.mu.RUnlock()
return m
2017-11-23 10:21:28 +08:00
}
// 设置键值对
2019-02-01 17:30:23 +08:00
func (gm *StringInterfaceMap) Set(key string, val interface{}) {
gm.mu.Lock()
gm.m[key] = val
gm.mu.Unlock()
2017-11-23 10:21:28 +08:00
}
// 批量设置键值对
2019-02-01 17:30:23 +08:00
func (gm *StringInterfaceMap) BatchSet(m map[string]interface{}) {
gm.mu.Lock()
2017-11-23 10:21:28 +08:00
for k, v := range m {
2019-02-01 17:30:23 +08:00
gm.m[k] = v
2017-11-23 10:21:28 +08:00
}
2019-02-01 17:30:23 +08:00
gm.mu.Unlock()
2017-11-23 10:21:28 +08:00
}
// 获取键值
2019-02-01 17:30:23 +08:00
func (gm *StringInterfaceMap) Get(key string) interface{} {
gm.mu.RLock()
val, _ := gm.m[key]
gm.mu.RUnlock()
2017-11-23 10:21:28 +08:00
return val
}
// 设置kv缓存键值对内部会对键名的存在性使用写锁进行二次检索确认如果存在则不再写入返回键名对应的键值。
// 在高并发下有用,防止数据写入的并发逻辑错误。
2019-02-01 17:30:23 +08:00
func (gm *StringInterfaceMap) doSetWithLockCheck(key string, value interface{}) interface{} {
gm.mu.Lock()
defer gm.mu.Unlock()
if v, ok := gm.m[key]; ok {
return v
}
if f, ok := value.(func() interface {}); ok {
value = f()
}
2019-02-01 17:30:23 +08:00
gm.m[key] = value
return value
}
// 当键名存在时返回其键值,否则写入指定的键值
2019-02-01 17:30:23 +08:00
func (gm *StringInterfaceMap) GetOrSet(key string, value interface{}) interface{} {
if v := gm.Get(key); v == nil {
return gm.doSetWithLockCheck(key, value)
} else {
return v
}
}
// 当键名存在时返回其键值,否则写入指定的键值,键值由指定的函数生成
2019-02-01 17:30:23 +08:00
func (gm *StringInterfaceMap) GetOrSetFunc(key string, f func() interface{}) interface{} {
if v := gm.Get(key); v == nil {
return gm.doSetWithLockCheck(key, f())
} else {
return v
}
}
// 与GetOrSetFunc不同的是f是在写锁机制内执行
2019-02-01 17:30:23 +08:00
func (gm *StringInterfaceMap) GetOrSetFuncLock(key string, f func() interface{}) interface{} {
if v := gm.Get(key); v == nil {
return gm.doSetWithLockCheck(key, f)
} else {
return v
}
}
// 当键名不存在时写入并返回true否则返回false。
2019-02-01 17:30:23 +08:00
func (gm *StringInterfaceMap) SetIfNotExist(key string, value interface{}) bool {
if !gm.Contains(key) {
gm.doSetWithLockCheck(key, value)
return true
}
return false
2018-09-17 18:43:59 +08:00
}
2017-11-23 10:21:28 +08:00
// 批量删除键值对
2019-02-01 17:30:23 +08:00
func (gm *StringInterfaceMap) BatchRemove(keys []string) {
gm.mu.Lock()
2017-11-23 10:21:28 +08:00
for _, key := range keys {
2019-02-01 17:30:23 +08:00
delete(gm.m, key)
2017-11-23 10:21:28 +08:00
}
2019-02-01 17:30:23 +08:00
gm.mu.Unlock()
2017-11-23 10:21:28 +08:00
}
// 返回对应的键值,并删除该键值
2019-02-01 17:30:23 +08:00
func (gm *StringInterfaceMap) Remove(key string) interface{} {
gm.mu.Lock()
val, exists := gm.m[key]
2017-11-23 10:21:28 +08:00
if exists {
2019-02-01 17:30:23 +08:00
delete(gm.m, key)
2017-11-23 10:21:28 +08:00
}
2019-02-01 17:30:23 +08:00
gm.mu.Unlock()
2017-11-23 10:21:28 +08:00
return val
}
// 返回键列表
2019-02-01 17:30:23 +08:00
func (gm *StringInterfaceMap) Keys() []string {
gm.mu.RLock()
2017-11-23 10:21:28 +08:00
keys := make([]string, 0)
2019-02-01 17:30:23 +08:00
for key, _ := range gm.m {
2017-11-23 10:21:28 +08:00
keys = append(keys, key)
}
2019-02-01 17:30:23 +08:00
gm.mu.RUnlock()
2017-11-23 10:21:28 +08:00
return keys
}
// 返回值列表(注意是随机排序)
2019-02-01 17:30:23 +08:00
func (gm *StringInterfaceMap) Values() []interface{} {
gm.mu.RLock()
2017-11-23 10:21:28 +08:00
vals := make([]interface{}, 0)
2019-02-01 17:30:23 +08:00
for _, val := range gm.m {
2017-11-23 10:21:28 +08:00
vals = append(vals, val)
}
2019-02-01 17:30:23 +08:00
gm.mu.RUnlock()
2017-11-23 10:21:28 +08:00
return vals
}
// 是否存在某个键
2019-02-01 17:30:23 +08:00
func (gm *StringInterfaceMap) Contains(key string) bool {
gm.mu.RLock()
_, exists := gm.m[key]
gm.mu.RUnlock()
2017-11-23 10:21:28 +08:00
return exists
}
// 哈希表大小
2019-02-01 17:30:23 +08:00
func (gm *StringInterfaceMap) Size() int {
gm.mu.RLock()
length := len(gm.m)
gm.mu.RUnlock()
2018-03-29 13:46:05 +08:00
return length
2017-11-23 10:21:28 +08:00
}
// 哈希表是否为空
2019-02-01 17:30:23 +08:00
func (gm *StringInterfaceMap) IsEmpty() bool {
gm.mu.RLock()
empty := len(gm.m) == 0
gm.mu.RUnlock()
2017-11-23 10:21:28 +08:00
return empty
}
// 清空哈希表
2019-02-01 17:30:23 +08:00
func (gm *StringInterfaceMap) Clear() {
gm.mu.Lock()
gm.m = make(map[string]interface{})
gm.mu.Unlock()
2017-11-23 10:21:28 +08:00
}
// 并发安全写锁操作,使用自定义方法执行加锁修改操作
2019-02-01 17:30:23 +08:00
func (gm *StringInterfaceMap) LockFunc(f func(m map[string]interface{})) {
gm.mu.Lock()
defer gm.mu.Unlock()
2019-02-01 17:30:23 +08:00
f(gm.m)
}
// 并发安全读锁操作,使用自定义方法执行加锁读取操作
2019-02-01 17:30:23 +08:00
func (gm *StringInterfaceMap) RLockFunc(f func(m map[string]interface{})) {
gm.mu.RLock()
defer gm.mu.RUnlock()
2019-02-01 17:30:23 +08:00
f(gm.m)
}
// 交换Map中的键和值.
2019-02-01 17:30:23 +08:00
func (gm *StringInterfaceMap) Flip() {
gm.mu.Lock()
defer gm.mu.Unlock()
n := make(map[string]interface{}, len(gm.m))
for k, v := range gm.m {
n[gconv.String(v)] = k
}
2019-02-01 17:30:23 +08:00
gm.m = n
}
// 合并两个Map.
2019-02-01 17:30:23 +08:00
func (gm *StringInterfaceMap) Merge(m *StringInterfaceMap) {
gm.mu.Lock()
defer gm.mu.Unlock()
if m != gm {
m.mu.RLock()
defer m.mu.RUnlock()
}
for k, v := range m.m {
2019-02-01 17:30:23 +08:00
gm.m[k] = v
}
}