mirror of
https://gitee.com/johng/gf.git
synced 2024-11-30 19:27:46 +08:00
gset/gmap update
This commit is contained in:
parent
f2e149d3b3
commit
74a7f71894
@ -9,6 +9,3 @@
|
||||
// 并发安全数组.
|
||||
package garray
|
||||
|
||||
func New(size int, cap int, unsafe...bool) *Array {
|
||||
return NewArray(size, cap, unsafe...)
|
||||
}
|
@ -36,6 +36,10 @@ func NewIntArray(size int, cap int, unsafe...bool) *IntArray {
|
||||
return a
|
||||
}
|
||||
|
||||
func NewIntArrayEmpty(unsafe...bool) *IntArray {
|
||||
return NewIntArray(0, 0, unsafe...)
|
||||
}
|
||||
|
||||
func NewIntArrayFrom(array []int, unsafe...bool) *IntArray {
|
||||
return &IntArray{
|
||||
mu : rwmutex.New(unsafe...),
|
||||
@ -67,6 +71,32 @@ func (a *IntArray) SetArray(array []int) *IntArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// 使用指定数组替换到对应的索引元素值.
|
||||
func (a *IntArray) Replace(array []int) *IntArray {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
max := len(array)
|
||||
if max > len(a.array) {
|
||||
max = len(a.array)
|
||||
}
|
||||
for i := 0; i < max; i++ {
|
||||
a.array[i] = array[i]
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
// Calculate the sum of values in an array.
|
||||
//
|
||||
// 对数组中的元素项求和。
|
||||
func (a *IntArray) Sum() (sum int) {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
for _, v := range a.array {
|
||||
sum += v
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 将数组重新排序(从小到大).
|
||||
func (a *IntArray) Sort() *IntArray {
|
||||
a.mu.Lock()
|
||||
|
@ -22,6 +22,10 @@ type Array struct {
|
||||
array []interface{} // 底层数组
|
||||
}
|
||||
|
||||
func New(size int, cap int, unsafe...bool) *Array {
|
||||
return NewArray(size, cap, unsafe...)
|
||||
}
|
||||
|
||||
func NewArray(size int, cap int, unsafe...bool) *Array {
|
||||
a := &Array{
|
||||
mu : rwmutex.New(unsafe...),
|
||||
@ -36,6 +40,10 @@ func NewArray(size int, cap int, unsafe...bool) *Array {
|
||||
return a
|
||||
}
|
||||
|
||||
func NewArrayEmpty(unsafe...bool) *Array {
|
||||
return NewArray(0, 0, unsafe...)
|
||||
}
|
||||
|
||||
func NewArrayFrom(array []interface{}, unsafe...bool) *Array {
|
||||
return &Array{
|
||||
mu : rwmutex.New(unsafe...),
|
||||
@ -67,6 +75,32 @@ func (a *Array) SetArray(array []interface{}) *Array {
|
||||
return a
|
||||
}
|
||||
|
||||
// 使用指定数组替换到对应的索引元素值.
|
||||
func (a *Array) Replace(array []interface{}) *Array {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
max := len(array)
|
||||
if max > len(a.array) {
|
||||
max = len(a.array)
|
||||
}
|
||||
for i := 0; i < max; i++ {
|
||||
a.array[i] = array[i]
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
// Calculate the sum of values in an array.
|
||||
//
|
||||
// 对数组中的元素项求和(将元素值转换为int类型后叠加)。
|
||||
func (a *Array) Sum() (sum int) {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
for _, v := range a.array {
|
||||
sum += gconv.Int(v)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 将数组重新排序(从小到大).
|
||||
func (a *Array) Sort(less func(i, j int) bool) *Array {
|
||||
a.mu.Lock()
|
||||
@ -390,4 +424,17 @@ func (a *Array) Join(glue string) string {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
return strings.Join(gconv.Strings(a.array), glue)
|
||||
}
|
||||
|
||||
// Counts all the values of an array.
|
||||
//
|
||||
// 统计数组中所有的值出现的次数.
|
||||
func (a *Array) CountValues() map[interface{}]int {
|
||||
m := make(map[interface{}]int)
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
for _, v := range a.array {
|
||||
m[v]++
|
||||
}
|
||||
return m
|
||||
}
|
@ -8,6 +8,7 @@ package garray
|
||||
|
||||
import (
|
||||
"gitee.com/johng/gf/g/internal/rwmutex"
|
||||
"gitee.com/johng/gf/g/util/gconv"
|
||||
"gitee.com/johng/gf/g/util/grand"
|
||||
"math"
|
||||
"sort"
|
||||
@ -35,6 +36,10 @@ func NewStringArray(size int, cap int, unsafe...bool) *StringArray {
|
||||
return a
|
||||
}
|
||||
|
||||
func NewStringArrayEmpty(unsafe...bool) *StringArray {
|
||||
return NewStringArray(0, 0, unsafe...)
|
||||
}
|
||||
|
||||
func NewStringArrayFrom(array []string, unsafe...bool) *StringArray {
|
||||
return &StringArray {
|
||||
mu : rwmutex.New(unsafe...),
|
||||
@ -66,6 +71,32 @@ func (a *StringArray) SetArray(array []string) *StringArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// 使用指定数组替换到对应的索引元素值.
|
||||
func (a *StringArray) Replace(array []string) *StringArray {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
max := len(array)
|
||||
if max > len(a.array) {
|
||||
max = len(a.array)
|
||||
}
|
||||
for i := 0; i < max; i++ {
|
||||
a.array[i] = array[i]
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
// Calculate the sum of values in an array.
|
||||
//
|
||||
// 对数组中的元素项求和(将元素值转换为int类型后叠加)。
|
||||
func (a *StringArray) Sum() (sum int) {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
for _, v := range a.array {
|
||||
sum += gconv.Int(v)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 将数组重新排序(从小到大).
|
||||
func (a *StringArray) Sort() *StringArray {
|
||||
a.mu.Lock()
|
||||
|
@ -43,6 +43,10 @@ func NewSortedIntArray(cap int, unsafe...bool) *SortedIntArray {
|
||||
}
|
||||
}
|
||||
|
||||
func NewSortedIntArrayEmpty(unsafe...bool) *SortedIntArray {
|
||||
return NewSortedIntArray(0, unsafe...)
|
||||
}
|
||||
|
||||
func NewSortedIntArrayFrom(array []int, unsafe...bool) *SortedIntArray {
|
||||
a := NewSortedIntArray(0, unsafe...)
|
||||
a.array = array
|
||||
@ -149,6 +153,18 @@ func (a *SortedIntArray) Len() int {
|
||||
return length
|
||||
}
|
||||
|
||||
// Calculate the sum of values in an array.
|
||||
//
|
||||
// 对数组中的元素项求和。
|
||||
func (a *SortedIntArray) Sum() (sum int) {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
for _, v := range a.array {
|
||||
sum += v
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 返回原始数据数组
|
||||
func (a *SortedIntArray) Slice() []int {
|
||||
array := ([]int)(nil)
|
||||
|
@ -34,6 +34,10 @@ func NewSortedArray(cap int, compareFunc func(v1, v2 interface{}) int, unsafe...
|
||||
}
|
||||
}
|
||||
|
||||
func NewSortedArrayEmpty(compareFunc func(v1, v2 interface{}) int, unsafe...bool) *SortedArray {
|
||||
return NewSortedArray(0, compareFunc, unsafe...)
|
||||
}
|
||||
|
||||
func NewSortedArrayFrom(array []interface{}, compareFunc func(v1, v2 interface{}) int, unsafe...bool) *SortedArray {
|
||||
a := NewSortedArray(0, compareFunc, unsafe...)
|
||||
a.array = array
|
||||
@ -55,7 +59,7 @@ func (a *SortedArray) SetArray(array []interface{}) *SortedArray {
|
||||
}
|
||||
|
||||
// 将数组重新排序(从小到大).
|
||||
func (a *SortedArray) Sort() *SortedArray {
|
||||
func (a *SortedArray) Sort(reverse...bool) *SortedArray {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
sort.Slice(a.array, func(i, j int) bool {
|
||||
@ -138,6 +142,18 @@ func (a *SortedArray) PopRight() interface{} {
|
||||
return value
|
||||
}
|
||||
|
||||
// Calculate the sum of values in an array.
|
||||
//
|
||||
// 对数组中的元素项求和(将元素值转换为int类型后叠加)。
|
||||
func (a *SortedArray) Sum() (sum int) {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
for _, v := range a.array {
|
||||
sum += gconv.Int(v)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 数组长度
|
||||
func (a *SortedArray) Len() int {
|
||||
a.mu.RLock()
|
||||
|
@ -9,6 +9,7 @@ package garray
|
||||
import (
|
||||
"gitee.com/johng/gf/g/container/gtype"
|
||||
"gitee.com/johng/gf/g/internal/rwmutex"
|
||||
"gitee.com/johng/gf/g/util/gconv"
|
||||
"gitee.com/johng/gf/g/util/grand"
|
||||
"math"
|
||||
"sort"
|
||||
@ -35,6 +36,10 @@ func NewSortedStringArray(cap int, unsafe...bool) *SortedStringArray {
|
||||
}
|
||||
}
|
||||
|
||||
func NewSortedStringArrayEmpty(unsafe...bool) *SortedStringArray {
|
||||
return NewSortedStringArray(0, unsafe...)
|
||||
}
|
||||
|
||||
func NewSortedStringArrayFrom(array []string, unsafe...bool) *SortedStringArray {
|
||||
a := NewSortedStringArray(0, unsafe...)
|
||||
a.array = array
|
||||
@ -133,6 +138,18 @@ func (a *SortedStringArray) PopRight() string {
|
||||
return value
|
||||
}
|
||||
|
||||
// Calculate the sum of values in an array.
|
||||
//
|
||||
// 对数组中的元素项求和(将元素值转换为int类型后叠加)。
|
||||
func (a *SortedStringArray) Sum() (sum int) {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
for _, v := range a.array {
|
||||
sum += gconv.Int(v)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 数组长度
|
||||
func (a *SortedStringArray) Len() int {
|
||||
a.mu.RLock()
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Copyright 2017 gf Author(https://gitee.com/johng/gf). All Rights Reserved.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the MIT License.
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// If a copy of the MIT was not distributed with gm file,
|
||||
// You can obtain one at https://gitee.com/johng/gf.
|
||||
|
||||
// Package gmap provides kinds of concurrent-safe(alternative) maps.
|
||||
@ -9,13 +9,249 @@
|
||||
// 并发安全MAP.
|
||||
package gmap
|
||||
|
||||
// 默认的Map对象其实就是InterfaceInterfaceMap的别名。
|
||||
// 注意
|
||||
import "gitee.com/johng/gf/g/internal/rwmutex"
|
||||
|
||||
// 注意:
|
||||
// 1、这个Map是所有并发安全Map中效率最低的,如果对效率要求比较高的场合,请合理选择对应数据类型的Map;
|
||||
// 2、这个Map的优点是使用简便,由于键值都是interface{}类型,因此对键值的数据类型要求不高;
|
||||
// 3、底层实现比较类似于sync.Map;
|
||||
type Map = InterfaceInterfaceMap
|
||||
|
||||
type Map struct {
|
||||
mu *rwmutex.RWMutex
|
||||
m map[interface{}]interface{}
|
||||
}
|
||||
|
||||
func New(safe...bool) *Map {
|
||||
return NewInterfaceInterfaceMap(safe...)
|
||||
return NewMap(safe...)
|
||||
}
|
||||
|
||||
func NewMap(unsafe...bool) *Map {
|
||||
return &Map{
|
||||
m : make(map[interface{}]interface{}),
|
||||
mu : rwmutex.New(unsafe...),
|
||||
}
|
||||
}
|
||||
|
||||
func NewFromArray(keys []interface{}, values []interface{}, unsafe...bool) *Map {
|
||||
m := make(map[interface{}]interface{})
|
||||
l := len(values)
|
||||
for i, k := range keys {
|
||||
if i < l {
|
||||
m[k] = values[i]
|
||||
} else {
|
||||
m[k] = interface{}(nil)
|
||||
}
|
||||
}
|
||||
return &Map{
|
||||
m : m,
|
||||
mu : rwmutex.New(unsafe...),
|
||||
}
|
||||
}
|
||||
|
||||
// 给定回调函数对原始内容进行遍历,回调函数返回true表示继续遍历,否则停止遍历
|
||||
func (gm *Map) Iterator(f func (k interface{}, v interface{}) bool) {
|
||||
gm.mu.RLock()
|
||||
defer gm.mu.RUnlock()
|
||||
for k, v := range gm.m {
|
||||
if !f(k, v) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 哈希表克隆
|
||||
func (gm *Map) Clone() map[interface{}]interface{} {
|
||||
m := make(map[interface{}]interface{})
|
||||
gm.mu.RLock()
|
||||
for k, v := range gm.m {
|
||||
m[k] = v
|
||||
}
|
||||
gm.mu.RUnlock()
|
||||
return m
|
||||
}
|
||||
|
||||
// 设置键值对
|
||||
func (gm *Map) Set(key interface{}, val interface{}) {
|
||||
gm.mu.Lock()
|
||||
gm.m[key] = val
|
||||
gm.mu.Unlock()
|
||||
}
|
||||
|
||||
// 批量设置键值对
|
||||
func (gm *Map) BatchSet(m map[interface{}]interface{}) {
|
||||
gm.mu.Lock()
|
||||
for k, v := range m {
|
||||
gm.m[k] = v
|
||||
}
|
||||
gm.mu.Unlock()
|
||||
}
|
||||
|
||||
// 获取键值
|
||||
func (gm *Map) Get(key interface{}) interface{} {
|
||||
gm.mu.RLock()
|
||||
val, _ := gm.m[key]
|
||||
gm.mu.RUnlock()
|
||||
return val
|
||||
}
|
||||
|
||||
// 设置kv缓存键值对,内部会对键名的存在性使用写锁进行二次检索确认,如果存在则不再写入;返回键名对应的键值。
|
||||
// 在高并发下有用,防止数据写入的并发逻辑错误。
|
||||
func (gm *Map) doSetWithLockCheck(key interface{}, 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()
|
||||
}
|
||||
gm.m[key] = value
|
||||
return value
|
||||
}
|
||||
|
||||
// 当键名存在时返回其键值,否则写入指定的键值
|
||||
func (gm *Map) GetOrSet(key interface{}, value interface{}) interface{} {
|
||||
if v := gm.Get(key); v == nil {
|
||||
return gm.doSetWithLockCheck(key, value)
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
// 当键名存在时返回其键值,否则写入指定的键值,键值由指定的函数生成
|
||||
func (gm *Map) GetOrSetFunc(key interface{}, f func() interface{}) interface{} {
|
||||
if v := gm.Get(key); v == nil {
|
||||
return gm.doSetWithLockCheck(key, f())
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
// 与GetOrSetFunc不同的是,f是在写锁机制内执行
|
||||
func (gm *Map) GetOrSetFuncLock(key interface{}, f func() interface{}) interface{} {
|
||||
if v := gm.Get(key); v == nil {
|
||||
return gm.doSetWithLockCheck(key, f)
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
// 当键名不存在时写入,并返回true;否则返回false。
|
||||
func (gm *Map) SetIfNotExist(key interface{}, value interface{}) bool {
|
||||
if !gm.Contains(key) {
|
||||
gm.doSetWithLockCheck(key, value)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// 批量删除键值对
|
||||
func (gm *Map) BatchRemove(keys []interface{}) {
|
||||
gm.mu.Lock()
|
||||
for _, key := range keys {
|
||||
delete(gm.m, key)
|
||||
}
|
||||
gm.mu.Unlock()
|
||||
}
|
||||
|
||||
// 返回对应的键值,并删除该键值
|
||||
func (gm *Map) Remove(key interface{}) interface{} {
|
||||
gm.mu.Lock()
|
||||
val, exists := gm.m[key]
|
||||
if exists {
|
||||
delete(gm.m, key)
|
||||
}
|
||||
gm.mu.Unlock()
|
||||
return val
|
||||
}
|
||||
|
||||
// 返回键列表
|
||||
func (gm *Map) Keys() []interface{} {
|
||||
gm.mu.RLock()
|
||||
keys := make([]interface{}, 0)
|
||||
for key, _ := range gm.m {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
gm.mu.RUnlock()
|
||||
return keys
|
||||
}
|
||||
|
||||
// 返回值列表(注意是随机排序)
|
||||
func (gm *Map) Values() []interface{} {
|
||||
gm.mu.RLock()
|
||||
vals := make([]interface{}, 0)
|
||||
for _, val := range gm.m {
|
||||
vals = append(vals, val)
|
||||
}
|
||||
gm.mu.RUnlock()
|
||||
return vals
|
||||
}
|
||||
|
||||
// 是否存在某个键
|
||||
func (gm *Map) Contains(key interface{}) bool {
|
||||
gm.mu.RLock()
|
||||
_, exists := gm.m[key]
|
||||
gm.mu.RUnlock()
|
||||
return exists
|
||||
}
|
||||
|
||||
// 哈希表大小
|
||||
func (gm *Map) Size() int {
|
||||
gm.mu.RLock()
|
||||
length := len(gm.m)
|
||||
gm.mu.RUnlock()
|
||||
return length
|
||||
}
|
||||
|
||||
// 哈希表是否为空
|
||||
func (gm *Map) IsEmpty() bool {
|
||||
gm.mu.RLock()
|
||||
empty := len(gm.m) == 0
|
||||
gm.mu.RUnlock()
|
||||
return empty
|
||||
}
|
||||
|
||||
// 清空哈希表
|
||||
func (gm *Map) Clear() {
|
||||
gm.mu.Lock()
|
||||
gm.m = make(map[interface{}]interface{})
|
||||
gm.mu.Unlock()
|
||||
}
|
||||
|
||||
// 并发安全锁操作,使用自定义方法执行加锁修改操作
|
||||
func (gm *Map) LockFunc(f func(m map[interface{}]interface{})) {
|
||||
gm.mu.Lock(true)
|
||||
defer gm.mu.Unlock(true)
|
||||
f(gm.m)
|
||||
}
|
||||
|
||||
// 并发安全锁操作,使用自定义方法执行加锁读取操作
|
||||
func (gm *Map) RLockFunc(f func(m map[interface{}]interface{})) {
|
||||
gm.mu.RLock(true)
|
||||
defer gm.mu.RUnlock(true)
|
||||
f(gm.m)
|
||||
}
|
||||
|
||||
// 交换Map中的键和值.
|
||||
func (gm *Map) Flip() {
|
||||
gm.mu.Lock()
|
||||
defer gm.mu.Unlock()
|
||||
n := make(map[interface{}]interface{}, len(gm.m))
|
||||
for i, v := range gm.m {
|
||||
n[v] = i
|
||||
}
|
||||
gm.m = n
|
||||
}
|
||||
|
||||
// 合并两个Map.
|
||||
func (gm *Map) Merge(m *Map) {
|
||||
gm.mu.Lock()
|
||||
defer gm.mu.Unlock()
|
||||
if m != gm {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
}
|
||||
for k, v := range m.m {
|
||||
gm.m[k] = v
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
// Copyright 2019 gf Author(https://gitee.com/johng/gf). All Rights Reserved.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the MIT License.
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// If a copy of the MIT was not distributed with gm file,
|
||||
// You can obtain one at https://gitee.com/johng/gf.
|
||||
|
||||
package gmap
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Copyright 2017 gf Author(https://gitee.com/johng/gf). All Rights Reserved.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the MIT License.
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// If a copy of the MIT was not distributed with gm file,
|
||||
// You can obtain one at https://gitee.com/johng/gf.
|
||||
//
|
||||
|
||||
@ -24,21 +24,21 @@ func NewIntBoolMap(unsafe...bool) *IntBoolMap {
|
||||
}
|
||||
|
||||
// 哈希表克隆
|
||||
func (this *IntBoolMap) Clone() map[int]bool {
|
||||
func (gm *IntBoolMap) Clone() map[int]bool {
|
||||
m := make(map[int]bool)
|
||||
this.mu.RLock()
|
||||
for k, v := range this.m {
|
||||
gm.mu.RLock()
|
||||
for k, v := range gm.m {
|
||||
m[k] = v
|
||||
}
|
||||
this.mu.RUnlock()
|
||||
gm.mu.RUnlock()
|
||||
return m
|
||||
}
|
||||
|
||||
// 给定回调函数对原始内容进行遍历,回调函数返回true表示继续遍历,否则停止遍历
|
||||
func (this *IntBoolMap) Iterator(f func (k int, v bool) bool) {
|
||||
this.mu.RLock()
|
||||
defer this.mu.RUnlock()
|
||||
for k, v := range this.m {
|
||||
func (gm *IntBoolMap) Iterator(f func (k int, v bool) bool) {
|
||||
gm.mu.RLock()
|
||||
defer gm.mu.RUnlock()
|
||||
for k, v := range gm.m {
|
||||
if !f(k, v) {
|
||||
break
|
||||
}
|
||||
@ -46,80 +46,80 @@ func (this *IntBoolMap) Iterator(f func (k int, v bool) bool) {
|
||||
}
|
||||
|
||||
// 设置键值对
|
||||
func (this *IntBoolMap) Set(key int, val bool) {
|
||||
this.mu.Lock()
|
||||
this.m[key] = val
|
||||
this.mu.Unlock()
|
||||
func (gm *IntBoolMap) Set(key int, val bool) {
|
||||
gm.mu.Lock()
|
||||
gm.m[key] = val
|
||||
gm.mu.Unlock()
|
||||
}
|
||||
|
||||
// 批量设置键值对
|
||||
func (this *IntBoolMap) BatchSet(m map[int]bool) {
|
||||
this.mu.Lock()
|
||||
func (gm *IntBoolMap) BatchSet(m map[int]bool) {
|
||||
gm.mu.Lock()
|
||||
for k, v := range m {
|
||||
this.m[k] = v
|
||||
gm.m[k] = v
|
||||
}
|
||||
this.mu.Unlock()
|
||||
gm.mu.Unlock()
|
||||
}
|
||||
|
||||
// 获取键值
|
||||
func (this *IntBoolMap) Get(key int) bool {
|
||||
this.mu.RLock()
|
||||
val, _ := this.m[key]
|
||||
this.mu.RUnlock()
|
||||
func (gm *IntBoolMap) Get(key int) bool {
|
||||
gm.mu.RLock()
|
||||
val, _ := gm.m[key]
|
||||
gm.mu.RUnlock()
|
||||
return val
|
||||
}
|
||||
|
||||
// 设置kv缓存键值对,内部会对键名的存在性使用写锁进行二次检索确认,如果存在则不再写入;返回键名对应的键值。
|
||||
// 在高并发下有用,防止数据写入的并发逻辑错误。
|
||||
func (this *IntBoolMap) doSetWithLockCheck(key int, value bool) bool {
|
||||
this.mu.Lock()
|
||||
if v, ok := this.m[key]; ok {
|
||||
this.mu.Unlock()
|
||||
func (gm *IntBoolMap) doSetWithLockCheck(key int, value bool) bool {
|
||||
gm.mu.Lock()
|
||||
if v, ok := gm.m[key]; ok {
|
||||
gm.mu.Unlock()
|
||||
return v
|
||||
}
|
||||
this.m[key] = value
|
||||
this.mu.Unlock()
|
||||
gm.m[key] = value
|
||||
gm.mu.Unlock()
|
||||
return value
|
||||
}
|
||||
|
||||
// 当键名存在时返回其键值,否则写入指定的键值
|
||||
func (this *IntBoolMap) GetOrSet(key int, value bool) bool {
|
||||
this.mu.RLock()
|
||||
v, ok := this.m[key]
|
||||
this.mu.RUnlock()
|
||||
func (gm *IntBoolMap) GetOrSet(key int, value bool) bool {
|
||||
gm.mu.RLock()
|
||||
v, ok := gm.m[key]
|
||||
gm.mu.RUnlock()
|
||||
if !ok {
|
||||
return this.doSetWithLockCheck(key, value)
|
||||
return gm.doSetWithLockCheck(key, value)
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
// 当键名存在时返回其键值,否则写入指定的键值,键值由指定的函数生成
|
||||
func (this *IntBoolMap) GetOrSetFunc(key int, f func() bool) bool {
|
||||
this.mu.RLock()
|
||||
v, ok := this.m[key]
|
||||
this.mu.RUnlock()
|
||||
func (gm *IntBoolMap) GetOrSetFunc(key int, f func() bool) bool {
|
||||
gm.mu.RLock()
|
||||
v, ok := gm.m[key]
|
||||
gm.mu.RUnlock()
|
||||
if !ok {
|
||||
return this.doSetWithLockCheck(key, f())
|
||||
return gm.doSetWithLockCheck(key, f())
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
// 与GetOrSetFunc不同的是,f是在写锁机制内执行
|
||||
func (this *IntBoolMap) GetOrSetFuncLock(key int, f func() bool) bool {
|
||||
this.mu.RLock()
|
||||
val, ok := this.m[key]
|
||||
this.mu.RUnlock()
|
||||
func (gm *IntBoolMap) GetOrSetFuncLock(key int, f func() bool) bool {
|
||||
gm.mu.RLock()
|
||||
val, ok := gm.m[key]
|
||||
gm.mu.RUnlock()
|
||||
if !ok {
|
||||
this.mu.Lock()
|
||||
defer this.mu.Unlock()
|
||||
if v, ok := this.m[key]; ok {
|
||||
this.mu.Unlock()
|
||||
gm.mu.Lock()
|
||||
defer gm.mu.Unlock()
|
||||
if v, ok := gm.m[key]; ok {
|
||||
gm.mu.Unlock()
|
||||
return v
|
||||
}
|
||||
val = f()
|
||||
this.m[key] = val
|
||||
gm.m[key] = val
|
||||
return val
|
||||
} else {
|
||||
return val
|
||||
@ -127,110 +127,110 @@ func (this *IntBoolMap) GetOrSetFuncLock(key int, f func() bool) bool {
|
||||
}
|
||||
|
||||
// 当键名不存在时写入,并返回true;否则返回false。
|
||||
func (this *IntBoolMap) SetIfNotExist(key int, value bool) bool {
|
||||
if !this.Contains(key) {
|
||||
this.doSetWithLockCheck(key, value)
|
||||
func (gm *IntBoolMap) SetIfNotExist(key int, value bool) bool {
|
||||
if !gm.Contains(key) {
|
||||
gm.doSetWithLockCheck(key, value)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// 批量删除键值对
|
||||
func (this *IntBoolMap) BatchRemove(keys []int) {
|
||||
this.mu.Lock()
|
||||
func (gm *IntBoolMap) BatchRemove(keys []int) {
|
||||
gm.mu.Lock()
|
||||
for _, key := range keys {
|
||||
delete(this.m, key)
|
||||
delete(gm.m, key)
|
||||
}
|
||||
this.mu.Unlock()
|
||||
gm.mu.Unlock()
|
||||
}
|
||||
|
||||
// 返回对应的键值,并删除该键值
|
||||
func (this *IntBoolMap) Remove(key int) bool {
|
||||
this.mu.Lock()
|
||||
val, exists := this.m[key]
|
||||
func (gm *IntBoolMap) Remove(key int) bool {
|
||||
gm.mu.Lock()
|
||||
val, exists := gm.m[key]
|
||||
if exists {
|
||||
delete(this.m, key)
|
||||
delete(gm.m, key)
|
||||
}
|
||||
this.mu.Unlock()
|
||||
gm.mu.Unlock()
|
||||
return val
|
||||
}
|
||||
|
||||
// 返回键列表
|
||||
func (this *IntBoolMap) Keys() []int {
|
||||
this.mu.RLock()
|
||||
func (gm *IntBoolMap) Keys() []int {
|
||||
gm.mu.RLock()
|
||||
keys := make([]int, 0)
|
||||
for key, _ := range this.m {
|
||||
for key, _ := range gm.m {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
this.mu.RUnlock()
|
||||
gm.mu.RUnlock()
|
||||
return keys
|
||||
}
|
||||
|
||||
// 返回值列表(注意是随机排序)
|
||||
//func (this *IntBoolMap) Values() []bool {
|
||||
// this.mu.RLock()
|
||||
//func (gm *IntBoolMap) Values() []bool {
|
||||
// gm.mu.RLock()
|
||||
// vals := make([]bool, 0)
|
||||
// for _, val := range this.m {
|
||||
// for _, val := range gm.m {
|
||||
// vals = append(vals, val)
|
||||
// }
|
||||
// this.mu.RUnlock()
|
||||
// gm.mu.RUnlock()
|
||||
// return vals
|
||||
//}
|
||||
|
||||
// 是否存在某个键
|
||||
func (this *IntBoolMap) Contains(key int) bool {
|
||||
this.mu.RLock()
|
||||
_, exists := this.m[key]
|
||||
this.mu.RUnlock()
|
||||
func (gm *IntBoolMap) Contains(key int) bool {
|
||||
gm.mu.RLock()
|
||||
_, exists := gm.m[key]
|
||||
gm.mu.RUnlock()
|
||||
return exists
|
||||
}
|
||||
|
||||
// 哈希表大小
|
||||
func (this *IntBoolMap) Size() int {
|
||||
this.mu.RLock()
|
||||
length := len(this.m)
|
||||
this.mu.RUnlock()
|
||||
func (gm *IntBoolMap) Size() int {
|
||||
gm.mu.RLock()
|
||||
length := len(gm.m)
|
||||
gm.mu.RUnlock()
|
||||
return length
|
||||
}
|
||||
|
||||
// 哈希表是否为空
|
||||
func (this *IntBoolMap) IsEmpty() bool {
|
||||
this.mu.RLock()
|
||||
empty := len(this.m) == 0
|
||||
this.mu.RUnlock()
|
||||
func (gm *IntBoolMap) IsEmpty() bool {
|
||||
gm.mu.RLock()
|
||||
empty := len(gm.m) == 0
|
||||
gm.mu.RUnlock()
|
||||
return empty
|
||||
}
|
||||
|
||||
// 清空哈希表
|
||||
func (this *IntBoolMap) Clear() {
|
||||
this.mu.Lock()
|
||||
this.m = make(map[int]bool)
|
||||
this.mu.Unlock()
|
||||
func (gm *IntBoolMap) Clear() {
|
||||
gm.mu.Lock()
|
||||
gm.m = make(map[int]bool)
|
||||
gm.mu.Unlock()
|
||||
}
|
||||
|
||||
// 并发安全锁操作,使用自定义方法执行加锁修改操作
|
||||
func (this *IntBoolMap) LockFunc(f func(m map[int]bool)) {
|
||||
this.mu.Lock(true)
|
||||
defer this.mu.Unlock(true)
|
||||
f(this.m)
|
||||
func (gm *IntBoolMap) LockFunc(f func(m map[int]bool)) {
|
||||
gm.mu.Lock(true)
|
||||
defer gm.mu.Unlock(true)
|
||||
f(gm.m)
|
||||
}
|
||||
|
||||
// 并发安全锁操作,使用自定义方法执行加锁读取操作
|
||||
func (this *IntBoolMap) RLockFunc(f func(m map[int]bool)) {
|
||||
this.mu.RLock(true)
|
||||
defer this.mu.RUnlock(true)
|
||||
f(this.m)
|
||||
func (gm *IntBoolMap) RLockFunc(f func(m map[int]bool)) {
|
||||
gm.mu.RLock(true)
|
||||
defer gm.mu.RUnlock(true)
|
||||
f(gm.m)
|
||||
}
|
||||
|
||||
// 合并两个Map.
|
||||
func (this *IntBoolMap) Merge(m *IntBoolMap) {
|
||||
this.mu.Lock()
|
||||
defer this.mu.Unlock()
|
||||
if m != this {
|
||||
func (gm *IntBoolMap) Merge(m *IntBoolMap) {
|
||||
gm.mu.Lock()
|
||||
defer gm.mu.Unlock()
|
||||
if m != gm {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
}
|
||||
for k, v := range m.m {
|
||||
this.m[k] = v
|
||||
gm.m[k] = v
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
// Copyright 2017 gf Author(https://gitee.com/johng/gf). All Rights Reserved.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the MIT License.
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// If a copy of the MIT was not distributed with gm file,
|
||||
// You can obtain one at https://gitee.com/johng/gf.
|
||||
|
||||
|
||||
@ -24,10 +24,10 @@ func NewIntIntMap(unsafe...bool) *IntIntMap {
|
||||
}
|
||||
|
||||
// 给定回调函数对原始内容进行遍历,回调函数返回true表示继续遍历,否则停止遍历
|
||||
func (this *IntIntMap) Iterator(f func (k int, v int) bool) {
|
||||
this.mu.RLock()
|
||||
defer this.mu.RUnlock()
|
||||
for k, v := range this.m {
|
||||
func (gm *IntIntMap) Iterator(f func (k int, v int) bool) {
|
||||
gm.mu.RLock()
|
||||
defer gm.mu.RUnlock()
|
||||
for k, v := range gm.m {
|
||||
if !f(k, v) {
|
||||
break
|
||||
}
|
||||
@ -35,91 +35,91 @@ func (this *IntIntMap) Iterator(f func (k int, v int) bool) {
|
||||
}
|
||||
|
||||
// 哈希表克隆
|
||||
func (this *IntIntMap) Clone() map[int]int {
|
||||
func (gm *IntIntMap) Clone() map[int]int {
|
||||
m := make(map[int]int)
|
||||
this.mu.RLock()
|
||||
for k, v := range this.m {
|
||||
gm.mu.RLock()
|
||||
for k, v := range gm.m {
|
||||
m[k] = v
|
||||
}
|
||||
this.mu.RUnlock()
|
||||
gm.mu.RUnlock()
|
||||
return m
|
||||
}
|
||||
|
||||
// 设置键值对
|
||||
func (this *IntIntMap) Set(key int, val int) {
|
||||
this.mu.Lock()
|
||||
this.m[key] = val
|
||||
this.mu.Unlock()
|
||||
func (gm *IntIntMap) Set(key int, val int) {
|
||||
gm.mu.Lock()
|
||||
gm.m[key] = val
|
||||
gm.mu.Unlock()
|
||||
}
|
||||
|
||||
// 批量设置键值对
|
||||
func (this *IntIntMap) BatchSet(m map[int]int) {
|
||||
this.mu.Lock()
|
||||
func (gm *IntIntMap) BatchSet(m map[int]int) {
|
||||
gm.mu.Lock()
|
||||
for k, v := range m {
|
||||
this.m[k] = v
|
||||
gm.m[k] = v
|
||||
}
|
||||
this.mu.Unlock()
|
||||
gm.mu.Unlock()
|
||||
}
|
||||
|
||||
// 获取键值
|
||||
func (this *IntIntMap) Get(key int) (int) {
|
||||
this.mu.RLock()
|
||||
val, _ := this.m[key]
|
||||
this.mu.RUnlock()
|
||||
func (gm *IntIntMap) Get(key int) (int) {
|
||||
gm.mu.RLock()
|
||||
val, _ := gm.m[key]
|
||||
gm.mu.RUnlock()
|
||||
return val
|
||||
}
|
||||
|
||||
// 设置kv缓存键值对,内部会对键名的存在性使用写锁进行二次检索确认,如果存在则不再写入;返回键名对应的键值。
|
||||
// 在高并发下有用,防止数据写入的并发逻辑错误。
|
||||
func (this *IntIntMap) doSetWithLockCheck(key int, value int) int {
|
||||
this.mu.Lock()
|
||||
if v, ok := this.m[key]; ok {
|
||||
this.mu.Unlock()
|
||||
func (gm *IntIntMap) doSetWithLockCheck(key int, value int) int {
|
||||
gm.mu.Lock()
|
||||
if v, ok := gm.m[key]; ok {
|
||||
gm.mu.Unlock()
|
||||
return v
|
||||
}
|
||||
this.m[key] = value
|
||||
this.mu.Unlock()
|
||||
gm.m[key] = value
|
||||
gm.mu.Unlock()
|
||||
return value
|
||||
}
|
||||
|
||||
// 当键名存在时返回其键值,否则写入指定的键值
|
||||
func (this *IntIntMap) GetOrSet(key int, value int) int {
|
||||
this.mu.RLock()
|
||||
v, ok := this.m[key]
|
||||
this.mu.RUnlock()
|
||||
func (gm *IntIntMap) GetOrSet(key int, value int) int {
|
||||
gm.mu.RLock()
|
||||
v, ok := gm.m[key]
|
||||
gm.mu.RUnlock()
|
||||
if !ok {
|
||||
return this.doSetWithLockCheck(key, value)
|
||||
return gm.doSetWithLockCheck(key, value)
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
// 当键名存在时返回其键值,否则写入指定的键值,键值由指定的函数生成
|
||||
func (this *IntIntMap) GetOrSetFunc(key int, f func() int) int {
|
||||
this.mu.RLock()
|
||||
v, ok := this.m[key]
|
||||
this.mu.RUnlock()
|
||||
func (gm *IntIntMap) GetOrSetFunc(key int, f func() int) int {
|
||||
gm.mu.RLock()
|
||||
v, ok := gm.m[key]
|
||||
gm.mu.RUnlock()
|
||||
if !ok {
|
||||
return this.doSetWithLockCheck(key, f())
|
||||
return gm.doSetWithLockCheck(key, f())
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
// 与GetOrSetFunc不同的是,f是在写锁机制内执行
|
||||
func (this *IntIntMap) GetOrSetFuncLock(key int, f func() int) int {
|
||||
this.mu.RLock()
|
||||
val, ok := this.m[key]
|
||||
this.mu.RUnlock()
|
||||
func (gm *IntIntMap) GetOrSetFuncLock(key int, f func() int) int {
|
||||
gm.mu.RLock()
|
||||
val, ok := gm.m[key]
|
||||
gm.mu.RUnlock()
|
||||
if !ok {
|
||||
this.mu.Lock()
|
||||
defer this.mu.Unlock()
|
||||
if v, ok := this.m[key]; ok {
|
||||
this.mu.Unlock()
|
||||
gm.mu.Lock()
|
||||
defer gm.mu.Unlock()
|
||||
if v, ok := gm.m[key]; ok {
|
||||
gm.mu.Unlock()
|
||||
return v
|
||||
}
|
||||
val = f()
|
||||
this.m[key] = val
|
||||
gm.m[key] = val
|
||||
return val
|
||||
} else {
|
||||
return val
|
||||
@ -127,121 +127,121 @@ func (this *IntIntMap) GetOrSetFuncLock(key int, f func() int) int {
|
||||
}
|
||||
|
||||
// 当键名不存在时写入,并返回true;否则返回false。
|
||||
func (this *IntIntMap) SetIfNotExist(key int, value int) bool {
|
||||
if !this.Contains(key) {
|
||||
this.doSetWithLockCheck(key, value)
|
||||
func (gm *IntIntMap) SetIfNotExist(key int, value int) bool {
|
||||
if !gm.Contains(key) {
|
||||
gm.doSetWithLockCheck(key, value)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// 批量删除键值对
|
||||
func (this *IntIntMap) BatchRemove(keys []int) {
|
||||
this.mu.Lock()
|
||||
func (gm *IntIntMap) BatchRemove(keys []int) {
|
||||
gm.mu.Lock()
|
||||
for _, key := range keys {
|
||||
delete(this.m, key)
|
||||
delete(gm.m, key)
|
||||
}
|
||||
this.mu.Unlock()
|
||||
gm.mu.Unlock()
|
||||
}
|
||||
|
||||
// 返回对应的键值,并删除该键值
|
||||
func (this *IntIntMap) Remove(key int) int {
|
||||
this.mu.Lock()
|
||||
val, exists := this.m[key]
|
||||
func (gm *IntIntMap) Remove(key int) int {
|
||||
gm.mu.Lock()
|
||||
val, exists := gm.m[key]
|
||||
if exists {
|
||||
delete(this.m, key)
|
||||
delete(gm.m, key)
|
||||
}
|
||||
this.mu.Unlock()
|
||||
gm.mu.Unlock()
|
||||
return val
|
||||
}
|
||||
|
||||
// 返回键列表
|
||||
func (this *IntIntMap) Keys() []int {
|
||||
this.mu.RLock()
|
||||
func (gm *IntIntMap) Keys() []int {
|
||||
gm.mu.RLock()
|
||||
keys := make([]int, 0)
|
||||
for key, _ := range this.m {
|
||||
for key, _ := range gm.m {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
this.mu.RUnlock()
|
||||
gm.mu.RUnlock()
|
||||
return keys
|
||||
}
|
||||
|
||||
// 返回值列表(注意是随机排序)
|
||||
func (this *IntIntMap) Values() []int {
|
||||
this.mu.RLock()
|
||||
func (gm *IntIntMap) Values() []int {
|
||||
gm.mu.RLock()
|
||||
vals := make([]int, 0)
|
||||
for _, val := range this.m {
|
||||
for _, val := range gm.m {
|
||||
vals = append(vals, val)
|
||||
}
|
||||
this.mu.RUnlock()
|
||||
gm.mu.RUnlock()
|
||||
return vals
|
||||
}
|
||||
|
||||
// 是否存在某个键
|
||||
func (this *IntIntMap) Contains(key int) bool {
|
||||
this.mu.RLock()
|
||||
_, exists := this.m[key]
|
||||
this.mu.RUnlock()
|
||||
func (gm *IntIntMap) Contains(key int) bool {
|
||||
gm.mu.RLock()
|
||||
_, exists := gm.m[key]
|
||||
gm.mu.RUnlock()
|
||||
return exists
|
||||
}
|
||||
|
||||
// 哈希表大小
|
||||
func (this *IntIntMap) Size() int {
|
||||
this.mu.RLock()
|
||||
length := len(this.m)
|
||||
this.mu.RUnlock()
|
||||
func (gm *IntIntMap) Size() int {
|
||||
gm.mu.RLock()
|
||||
length := len(gm.m)
|
||||
gm.mu.RUnlock()
|
||||
return length
|
||||
}
|
||||
|
||||
// 哈希表是否为空
|
||||
func (this *IntIntMap) IsEmpty() bool {
|
||||
this.mu.RLock()
|
||||
empty := len(this.m) == 0
|
||||
this.mu.RUnlock()
|
||||
func (gm *IntIntMap) IsEmpty() bool {
|
||||
gm.mu.RLock()
|
||||
empty := len(gm.m) == 0
|
||||
gm.mu.RUnlock()
|
||||
return empty
|
||||
}
|
||||
|
||||
// 清空哈希表
|
||||
func (this *IntIntMap) Clear() {
|
||||
this.mu.Lock()
|
||||
this.m = make(map[int]int)
|
||||
this.mu.Unlock()
|
||||
func (gm *IntIntMap) Clear() {
|
||||
gm.mu.Lock()
|
||||
gm.m = make(map[int]int)
|
||||
gm.mu.Unlock()
|
||||
}
|
||||
|
||||
// 并发安全锁操作,使用自定义方法执行加锁修改操作
|
||||
func (this *IntIntMap) LockFunc(f func(m map[int]int)) {
|
||||
this.mu.Lock(true)
|
||||
defer this.mu.Unlock(true)
|
||||
f(this.m)
|
||||
func (gm *IntIntMap) LockFunc(f func(m map[int]int)) {
|
||||
gm.mu.Lock(true)
|
||||
defer gm.mu.Unlock(true)
|
||||
f(gm.m)
|
||||
}
|
||||
|
||||
// 并发安全锁操作,使用自定义方法执行加锁读取操作
|
||||
func (this *IntIntMap) RLockFunc(f func(m map[int]int)) {
|
||||
this.mu.RLock(true)
|
||||
defer this.mu.RUnlock(true)
|
||||
f(this.m)
|
||||
func (gm *IntIntMap) RLockFunc(f func(m map[int]int)) {
|
||||
gm.mu.RLock(true)
|
||||
defer gm.mu.RUnlock(true)
|
||||
f(gm.m)
|
||||
}
|
||||
|
||||
// 交换Map中的键和值.
|
||||
func (this *IntIntMap) Flip() {
|
||||
this.mu.Lock()
|
||||
defer this.mu.Unlock()
|
||||
n := make(map[int]int, len(this.m))
|
||||
for k, v := range this.m {
|
||||
func (gm *IntIntMap) Flip() {
|
||||
gm.mu.Lock()
|
||||
defer gm.mu.Unlock()
|
||||
n := make(map[int]int, len(gm.m))
|
||||
for k, v := range gm.m {
|
||||
n[v] = k
|
||||
}
|
||||
this.m = n
|
||||
gm.m = n
|
||||
}
|
||||
|
||||
// 合并两个Map.
|
||||
func (this *IntIntMap) Merge(m *IntIntMap) {
|
||||
this.mu.Lock()
|
||||
defer this.mu.Unlock()
|
||||
if m != this {
|
||||
func (gm *IntIntMap) Merge(m *IntIntMap) {
|
||||
gm.mu.Lock()
|
||||
defer gm.mu.Unlock()
|
||||
if m != gm {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
}
|
||||
for k, v := range m.m {
|
||||
this.m[k] = v
|
||||
gm.m[k] = v
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Copyright 2017 gf Author(https://gitee.com/johng/gf). All Rights Reserved.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the MIT License.
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// If a copy of the MIT was not distributed with gm file,
|
||||
// You can obtain one at https://gitee.com/johng/gf.
|
||||
//
|
||||
|
||||
@ -25,10 +25,10 @@ func NewIntInterfaceMap(unsafe...bool) *IntInterfaceMap {
|
||||
}
|
||||
|
||||
// 给定回调函数对原始内容进行遍历,回调函数返回true表示继续遍历,否则停止遍历
|
||||
func (this *IntInterfaceMap) Iterator(f func (k int, v interface{}) bool) {
|
||||
this.mu.RLock()
|
||||
defer this.mu.RUnlock()
|
||||
for k, v := range this.m {
|
||||
func (gm *IntInterfaceMap) Iterator(f func (k int, v interface{}) bool) {
|
||||
gm.mu.RLock()
|
||||
defer gm.mu.RUnlock()
|
||||
for k, v := range gm.m {
|
||||
if !f(k, v) {
|
||||
break
|
||||
}
|
||||
@ -36,198 +36,198 @@ func (this *IntInterfaceMap) Iterator(f func (k int, v interface{}) bool) {
|
||||
}
|
||||
|
||||
// 哈希表克隆
|
||||
func (this *IntInterfaceMap) Clone() map[int]interface{} {
|
||||
func (gm *IntInterfaceMap) Clone() map[int]interface{} {
|
||||
m := make(map[int]interface{})
|
||||
this.mu.RLock()
|
||||
for k, v := range this.m {
|
||||
gm.mu.RLock()
|
||||
for k, v := range gm.m {
|
||||
m[k] = v
|
||||
}
|
||||
this.mu.RUnlock()
|
||||
gm.mu.RUnlock()
|
||||
return m
|
||||
}
|
||||
|
||||
// 设置键值对
|
||||
func (this *IntInterfaceMap) Set(key int, val interface{}) {
|
||||
this.mu.Lock()
|
||||
this.m[key] = val
|
||||
this.mu.Unlock()
|
||||
func (gm *IntInterfaceMap) Set(key int, val interface{}) {
|
||||
gm.mu.Lock()
|
||||
gm.m[key] = val
|
||||
gm.mu.Unlock()
|
||||
}
|
||||
|
||||
// 批量设置键值对
|
||||
func (this *IntInterfaceMap) BatchSet(m map[int]interface{}) {
|
||||
this.mu.Lock()
|
||||
func (gm *IntInterfaceMap) BatchSet(m map[int]interface{}) {
|
||||
gm.mu.Lock()
|
||||
for k, v := range m {
|
||||
this.m[k] = v
|
||||
gm.m[k] = v
|
||||
}
|
||||
this.mu.Unlock()
|
||||
gm.mu.Unlock()
|
||||
}
|
||||
|
||||
// 获取键值
|
||||
func (this *IntInterfaceMap) Get(key int) (interface{}) {
|
||||
this.mu.RLock()
|
||||
val, _ := this.m[key]
|
||||
this.mu.RUnlock()
|
||||
func (gm *IntInterfaceMap) Get(key int) (interface{}) {
|
||||
gm.mu.RLock()
|
||||
val, _ := gm.m[key]
|
||||
gm.mu.RUnlock()
|
||||
return val
|
||||
}
|
||||
|
||||
// 设置kv缓存键值对,内部会对键名的存在性使用写锁进行二次检索确认,如果存在则不再写入;返回键名对应的键值。
|
||||
// 在高并发下有用,防止数据写入的并发逻辑错误。
|
||||
func (this *IntInterfaceMap) doSetWithLockCheck(key int, value interface{}) interface{} {
|
||||
this.mu.Lock()
|
||||
defer this.mu.Unlock()
|
||||
if v, ok := this.m[key]; ok {
|
||||
func (gm *IntInterfaceMap) doSetWithLockCheck(key int, 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()
|
||||
}
|
||||
this.m[key] = value
|
||||
gm.m[key] = value
|
||||
return value
|
||||
}
|
||||
|
||||
// 当键名存在时返回其键值,否则写入指定的键值
|
||||
func (this *IntInterfaceMap) GetOrSet(key int, value interface{}) interface{} {
|
||||
if v := this.Get(key); v == nil {
|
||||
return this.doSetWithLockCheck(key, value)
|
||||
func (gm *IntInterfaceMap) GetOrSet(key int, value interface{}) interface{} {
|
||||
if v := gm.Get(key); v == nil {
|
||||
return gm.doSetWithLockCheck(key, value)
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
// 当键名存在时返回其键值,否则写入指定的键值,键值由指定的函数生成
|
||||
func (this *IntInterfaceMap) GetOrSetFunc(key int, f func() interface{}) interface{} {
|
||||
if v := this.Get(key); v == nil {
|
||||
return this.doSetWithLockCheck(key, f())
|
||||
func (gm *IntInterfaceMap) GetOrSetFunc(key int, f func() interface{}) interface{} {
|
||||
if v := gm.Get(key); v == nil {
|
||||
return gm.doSetWithLockCheck(key, f())
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
// 与GetOrSetFunc不同的是,f是在写锁机制内执行
|
||||
func (this *IntInterfaceMap) GetOrSetFuncLock(key int, f func() interface{}) interface{} {
|
||||
if v := this.Get(key); v == nil {
|
||||
return this.doSetWithLockCheck(key, f)
|
||||
func (gm *IntInterfaceMap) GetOrSetFuncLock(key int, f func() interface{}) interface{} {
|
||||
if v := gm.Get(key); v == nil {
|
||||
return gm.doSetWithLockCheck(key, f)
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
// 当键名不存在时写入,并返回true;否则返回false。
|
||||
func (this *IntInterfaceMap) SetIfNotExist(key int, value interface{}) bool {
|
||||
if !this.Contains(key) {
|
||||
this.doSetWithLockCheck(key, value)
|
||||
func (gm *IntInterfaceMap) SetIfNotExist(key int, value interface{}) bool {
|
||||
if !gm.Contains(key) {
|
||||
gm.doSetWithLockCheck(key, value)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// 批量删除键值对
|
||||
func (this *IntInterfaceMap) BatchRemove(keys []int) {
|
||||
this.mu.Lock()
|
||||
func (gm *IntInterfaceMap) BatchRemove(keys []int) {
|
||||
gm.mu.Lock()
|
||||
for _, key := range keys {
|
||||
delete(this.m, key)
|
||||
delete(gm.m, key)
|
||||
}
|
||||
this.mu.Unlock()
|
||||
gm.mu.Unlock()
|
||||
}
|
||||
|
||||
// 返回对应的键值,并删除该键值
|
||||
func (this *IntInterfaceMap) Remove(key int) interface{} {
|
||||
this.mu.Lock()
|
||||
val, exists := this.m[key]
|
||||
func (gm *IntInterfaceMap) Remove(key int) interface{} {
|
||||
gm.mu.Lock()
|
||||
val, exists := gm.m[key]
|
||||
if exists {
|
||||
delete(this.m, key)
|
||||
delete(gm.m, key)
|
||||
}
|
||||
this.mu.Unlock()
|
||||
gm.mu.Unlock()
|
||||
return val
|
||||
}
|
||||
|
||||
// 返回键列表
|
||||
func (this *IntInterfaceMap) Keys() []int {
|
||||
this.mu.RLock()
|
||||
func (gm *IntInterfaceMap) Keys() []int {
|
||||
gm.mu.RLock()
|
||||
keys := make([]int, 0)
|
||||
for key, _ := range this.m {
|
||||
for key, _ := range gm.m {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
this.mu.RUnlock()
|
||||
gm.mu.RUnlock()
|
||||
return keys
|
||||
}
|
||||
|
||||
// 返回值列表(注意是随机排序)
|
||||
func (this *IntInterfaceMap) Values() []interface{} {
|
||||
this.mu.RLock()
|
||||
func (gm *IntInterfaceMap) Values() []interface{} {
|
||||
gm.mu.RLock()
|
||||
vals := make([]interface{}, 0)
|
||||
for _, val := range this.m {
|
||||
for _, val := range gm.m {
|
||||
vals = append(vals, val)
|
||||
}
|
||||
this.mu.RUnlock()
|
||||
gm.mu.RUnlock()
|
||||
return vals
|
||||
}
|
||||
|
||||
// 是否存在某个键
|
||||
func (this *IntInterfaceMap) Contains(key int) bool {
|
||||
this.mu.RLock()
|
||||
_, exists := this.m[key]
|
||||
this.mu.RUnlock()
|
||||
func (gm *IntInterfaceMap) Contains(key int) bool {
|
||||
gm.mu.RLock()
|
||||
_, exists := gm.m[key]
|
||||
gm.mu.RUnlock()
|
||||
return exists
|
||||
}
|
||||
|
||||
// 哈希表大小
|
||||
func (this *IntInterfaceMap) Size() int {
|
||||
this.mu.RLock()
|
||||
length := len(this.m)
|
||||
this.mu.RUnlock()
|
||||
func (gm *IntInterfaceMap) Size() int {
|
||||
gm.mu.RLock()
|
||||
length := len(gm.m)
|
||||
gm.mu.RUnlock()
|
||||
return length
|
||||
}
|
||||
|
||||
// 哈希表是否为空
|
||||
func (this *IntInterfaceMap) IsEmpty() bool {
|
||||
this.mu.RLock()
|
||||
empty := len(this.m) == 0
|
||||
this.mu.RUnlock()
|
||||
func (gm *IntInterfaceMap) IsEmpty() bool {
|
||||
gm.mu.RLock()
|
||||
empty := len(gm.m) == 0
|
||||
gm.mu.RUnlock()
|
||||
return empty
|
||||
}
|
||||
|
||||
// 清空哈希表
|
||||
func (this *IntInterfaceMap) Clear() {
|
||||
this.mu.Lock()
|
||||
this.m = make(map[int]interface{})
|
||||
this.mu.Unlock()
|
||||
func (gm *IntInterfaceMap) Clear() {
|
||||
gm.mu.Lock()
|
||||
gm.m = make(map[int]interface{})
|
||||
gm.mu.Unlock()
|
||||
}
|
||||
|
||||
// 并发安全锁操作,使用自定义方法执行加锁修改操作
|
||||
func (this *IntInterfaceMap) LockFunc(f func(m map[int]interface{})) {
|
||||
this.mu.Lock()
|
||||
defer this.mu.Unlock()
|
||||
f(this.m)
|
||||
func (gm *IntInterfaceMap) LockFunc(f func(m map[int]interface{})) {
|
||||
gm.mu.Lock()
|
||||
defer gm.mu.Unlock()
|
||||
f(gm.m)
|
||||
}
|
||||
|
||||
// 并发安全锁操作,使用自定义方法执行加锁读取操作
|
||||
func (this *IntInterfaceMap) RLockFunc(f func(m map[int]interface{})) {
|
||||
this.mu.RLock(true)
|
||||
defer this.mu.RUnlock(true)
|
||||
f(this.m)
|
||||
func (gm *IntInterfaceMap) RLockFunc(f func(m map[int]interface{})) {
|
||||
gm.mu.RLock(true)
|
||||
defer gm.mu.RUnlock(true)
|
||||
f(gm.m)
|
||||
}
|
||||
|
||||
// 交换Map中的键和值.
|
||||
func (this *IntInterfaceMap) Flip() {
|
||||
this.mu.Lock()
|
||||
defer this.mu.Unlock()
|
||||
n := make(map[int]interface{}, len(this.m))
|
||||
for k, v := range this.m {
|
||||
func (gm *IntInterfaceMap) Flip() {
|
||||
gm.mu.Lock()
|
||||
defer gm.mu.Unlock()
|
||||
n := make(map[int]interface{}, len(gm.m))
|
||||
for k, v := range gm.m {
|
||||
n[gconv.Int(v)] = k
|
||||
}
|
||||
this.m = n
|
||||
gm.m = n
|
||||
}
|
||||
|
||||
// 合并两个Map.
|
||||
func (this *IntInterfaceMap) Merge(m *IntInterfaceMap) {
|
||||
this.mu.Lock()
|
||||
defer this.mu.Unlock()
|
||||
if m != this {
|
||||
func (gm *IntInterfaceMap) Merge(m *IntInterfaceMap) {
|
||||
gm.mu.Lock()
|
||||
defer gm.mu.Unlock()
|
||||
if m != gm {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
}
|
||||
for k, v := range m.m {
|
||||
this.m[k] = v
|
||||
gm.m[k] = v
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
// Copyright 2017 gf Author(https://gitee.com/johng/gf). All Rights Reserved.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the MIT License.
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// If a copy of the MIT was not distributed with gm file,
|
||||
// You can obtain one at https://gitee.com/johng/gf.
|
||||
|
||||
|
||||
@ -25,10 +25,10 @@ func NewIntStringMap(unsafe...bool) *IntStringMap {
|
||||
}
|
||||
|
||||
// 给定回调函数对原始内容进行遍历,回调函数返回true表示继续遍历,否则停止遍历
|
||||
func (this *IntStringMap) Iterator(f func (k int, v string) bool) {
|
||||
this.mu.RLock()
|
||||
defer this.mu.RUnlock()
|
||||
for k, v := range this.m {
|
||||
func (gm *IntStringMap) Iterator(f func (k int, v string) bool) {
|
||||
gm.mu.RLock()
|
||||
defer gm.mu.RUnlock()
|
||||
for k, v := range gm.m {
|
||||
if !f(k, v) {
|
||||
break
|
||||
}
|
||||
@ -36,91 +36,91 @@ func (this *IntStringMap) Iterator(f func (k int, v string) bool) {
|
||||
}
|
||||
|
||||
// 哈希表克隆
|
||||
func (this *IntStringMap) Clone() map[int]string {
|
||||
func (gm *IntStringMap) Clone() map[int]string {
|
||||
m := make(map[int]string)
|
||||
this.mu.RLock()
|
||||
for k, v := range this.m {
|
||||
gm.mu.RLock()
|
||||
for k, v := range gm.m {
|
||||
m[k] = v
|
||||
}
|
||||
this.mu.RUnlock()
|
||||
gm.mu.RUnlock()
|
||||
return m
|
||||
}
|
||||
|
||||
// 设置键值对
|
||||
func (this *IntStringMap) Set(key int, val string) {
|
||||
this.mu.Lock()
|
||||
this.m[key] = val
|
||||
this.mu.Unlock()
|
||||
func (gm *IntStringMap) Set(key int, val string) {
|
||||
gm.mu.Lock()
|
||||
gm.m[key] = val
|
||||
gm.mu.Unlock()
|
||||
}
|
||||
|
||||
// 批量设置键值对
|
||||
func (this *IntStringMap) BatchSet(m map[int]string) {
|
||||
this.mu.Lock()
|
||||
func (gm *IntStringMap) BatchSet(m map[int]string) {
|
||||
gm.mu.Lock()
|
||||
for k, v := range m {
|
||||
this.m[k] = v
|
||||
gm.m[k] = v
|
||||
}
|
||||
this.mu.Unlock()
|
||||
gm.mu.Unlock()
|
||||
}
|
||||
|
||||
// 获取键值
|
||||
func (this *IntStringMap) Get(key int) string {
|
||||
this.mu.RLock()
|
||||
val, _ := this.m[key]
|
||||
this.mu.RUnlock()
|
||||
func (gm *IntStringMap) Get(key int) string {
|
||||
gm.mu.RLock()
|
||||
val, _ := gm.m[key]
|
||||
gm.mu.RUnlock()
|
||||
return val
|
||||
}
|
||||
|
||||
// 设置kv缓存键值对,内部会对键名的存在性使用写锁进行二次检索确认,如果存在则不再写入;返回键名对应的键值。
|
||||
// 在高并发下有用,防止数据写入的并发逻辑错误。
|
||||
func (this *IntStringMap) doSetWithLockCheck(key int, value string) string {
|
||||
this.mu.Lock()
|
||||
if v, ok := this.m[key]; ok {
|
||||
this.mu.Unlock()
|
||||
func (gm *IntStringMap) doSetWithLockCheck(key int, value string) string {
|
||||
gm.mu.Lock()
|
||||
if v, ok := gm.m[key]; ok {
|
||||
gm.mu.Unlock()
|
||||
return v
|
||||
}
|
||||
this.m[key] = value
|
||||
this.mu.Unlock()
|
||||
gm.m[key] = value
|
||||
gm.mu.Unlock()
|
||||
return value
|
||||
}
|
||||
|
||||
// 当键名存在时返回其键值,否则写入指定的键值
|
||||
func (this *IntStringMap) GetOrSet(key int, value string) string {
|
||||
this.mu.RLock()
|
||||
v, ok := this.m[key]
|
||||
this.mu.RUnlock()
|
||||
func (gm *IntStringMap) GetOrSet(key int, value string) string {
|
||||
gm.mu.RLock()
|
||||
v, ok := gm.m[key]
|
||||
gm.mu.RUnlock()
|
||||
if !ok {
|
||||
return this.doSetWithLockCheck(key, value)
|
||||
return gm.doSetWithLockCheck(key, value)
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
// 当键名存在时返回其键值,否则写入指定的键值,键值由指定的函数生成
|
||||
func (this *IntStringMap) GetOrSetFunc(key int, f func() string) string {
|
||||
this.mu.RLock()
|
||||
v, ok := this.m[key]
|
||||
this.mu.RUnlock()
|
||||
func (gm *IntStringMap) GetOrSetFunc(key int, f func() string) string {
|
||||
gm.mu.RLock()
|
||||
v, ok := gm.m[key]
|
||||
gm.mu.RUnlock()
|
||||
if !ok {
|
||||
return this.doSetWithLockCheck(key, f())
|
||||
return gm.doSetWithLockCheck(key, f())
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
// 与GetOrSetFunc不同的是,f是在写锁机制内执行
|
||||
func (this *IntStringMap) GetOrSetFuncLock(key int, f func() string) string {
|
||||
this.mu.RLock()
|
||||
val, ok := this.m[key]
|
||||
this.mu.RUnlock()
|
||||
func (gm *IntStringMap) GetOrSetFuncLock(key int, f func() string) string {
|
||||
gm.mu.RLock()
|
||||
val, ok := gm.m[key]
|
||||
gm.mu.RUnlock()
|
||||
if !ok {
|
||||
this.mu.Lock()
|
||||
defer this.mu.Unlock()
|
||||
if v, ok := this.m[key]; ok {
|
||||
this.mu.Unlock()
|
||||
gm.mu.Lock()
|
||||
defer gm.mu.Unlock()
|
||||
if v, ok := gm.m[key]; ok {
|
||||
gm.mu.Unlock()
|
||||
return v
|
||||
}
|
||||
val = f()
|
||||
this.m[key] = val
|
||||
gm.m[key] = val
|
||||
return val
|
||||
} else {
|
||||
return val
|
||||
@ -128,121 +128,121 @@ func (this *IntStringMap) GetOrSetFuncLock(key int, f func() string) string {
|
||||
}
|
||||
|
||||
// 当键名不存在时写入,并返回true;否则返回false。
|
||||
func (this *IntStringMap) SetIfNotExist(key int, value string) bool {
|
||||
if !this.Contains(key) {
|
||||
this.doSetWithLockCheck(key, value)
|
||||
func (gm *IntStringMap) SetIfNotExist(key int, value string) bool {
|
||||
if !gm.Contains(key) {
|
||||
gm.doSetWithLockCheck(key, value)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// 批量删除键值对
|
||||
func (this *IntStringMap) BatchRemove(keys []int) {
|
||||
this.mu.Lock()
|
||||
func (gm *IntStringMap) BatchRemove(keys []int) {
|
||||
gm.mu.Lock()
|
||||
for _, key := range keys {
|
||||
delete(this.m, key)
|
||||
delete(gm.m, key)
|
||||
}
|
||||
this.mu.Unlock()
|
||||
gm.mu.Unlock()
|
||||
}
|
||||
|
||||
// 返回对应的键值,并删除该键值
|
||||
func (this *IntStringMap) Remove(key int) string {
|
||||
this.mu.Lock()
|
||||
val, exists := this.m[key]
|
||||
func (gm *IntStringMap) Remove(key int) string {
|
||||
gm.mu.Lock()
|
||||
val, exists := gm.m[key]
|
||||
if exists {
|
||||
delete(this.m, key)
|
||||
delete(gm.m, key)
|
||||
}
|
||||
this.mu.Unlock()
|
||||
gm.mu.Unlock()
|
||||
return val
|
||||
}
|
||||
|
||||
// 返回键列表
|
||||
func (this *IntStringMap) Keys() []int {
|
||||
this.mu.RLock()
|
||||
func (gm *IntStringMap) Keys() []int {
|
||||
gm.mu.RLock()
|
||||
keys := make([]int, 0)
|
||||
for key, _ := range this.m {
|
||||
for key, _ := range gm.m {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
this.mu.RUnlock()
|
||||
gm.mu.RUnlock()
|
||||
return keys
|
||||
}
|
||||
|
||||
// 返回值列表(注意是随机排序)
|
||||
func (this *IntStringMap) Values() []string {
|
||||
this.mu.RLock()
|
||||
func (gm *IntStringMap) Values() []string {
|
||||
gm.mu.RLock()
|
||||
vals := make([]string, 0)
|
||||
for _, val := range this.m {
|
||||
for _, val := range gm.m {
|
||||
vals = append(vals, val)
|
||||
}
|
||||
this.mu.RUnlock()
|
||||
gm.mu.RUnlock()
|
||||
return vals
|
||||
}
|
||||
|
||||
// 是否存在某个键
|
||||
func (this *IntStringMap) Contains(key int) bool {
|
||||
this.mu.RLock()
|
||||
_, exists := this.m[key]
|
||||
this.mu.RUnlock()
|
||||
func (gm *IntStringMap) Contains(key int) bool {
|
||||
gm.mu.RLock()
|
||||
_, exists := gm.m[key]
|
||||
gm.mu.RUnlock()
|
||||
return exists
|
||||
}
|
||||
|
||||
// 哈希表大小
|
||||
func (this *IntStringMap) Size() int {
|
||||
this.mu.RLock()
|
||||
length := len(this.m)
|
||||
this.mu.RUnlock()
|
||||
func (gm *IntStringMap) Size() int {
|
||||
gm.mu.RLock()
|
||||
length := len(gm.m)
|
||||
gm.mu.RUnlock()
|
||||
return length
|
||||
}
|
||||
|
||||
// 哈希表是否为空
|
||||
func (this *IntStringMap) IsEmpty() bool {
|
||||
this.mu.RLock()
|
||||
empty := len(this.m) == 0
|
||||
this.mu.RUnlock()
|
||||
func (gm *IntStringMap) IsEmpty() bool {
|
||||
gm.mu.RLock()
|
||||
empty := len(gm.m) == 0
|
||||
gm.mu.RUnlock()
|
||||
return empty
|
||||
}
|
||||
|
||||
// 清空哈希表
|
||||
func (this *IntStringMap) Clear() {
|
||||
this.mu.Lock()
|
||||
this.m = make(map[int]string)
|
||||
this.mu.Unlock()
|
||||
func (gm *IntStringMap) Clear() {
|
||||
gm.mu.Lock()
|
||||
gm.m = make(map[int]string)
|
||||
gm.mu.Unlock()
|
||||
}
|
||||
|
||||
// 并发安全锁操作,使用自定义方法执行加锁修改操作
|
||||
func (this *IntStringMap) LockFunc(f func(m map[int]string)) {
|
||||
this.mu.Lock(true)
|
||||
defer this.mu.Unlock(true)
|
||||
f(this.m)
|
||||
func (gm *IntStringMap) LockFunc(f func(m map[int]string)) {
|
||||
gm.mu.Lock(true)
|
||||
defer gm.mu.Unlock(true)
|
||||
f(gm.m)
|
||||
}
|
||||
|
||||
// 并发安全锁操作,使用自定义方法执行加锁读取操作
|
||||
func (this *IntStringMap) RLockFunc(f func(m map[int]string)) {
|
||||
this.mu.RLock(true)
|
||||
defer this.mu.RUnlock(true)
|
||||
f(this.m)
|
||||
func (gm *IntStringMap) RLockFunc(f func(m map[int]string)) {
|
||||
gm.mu.RLock(true)
|
||||
defer gm.mu.RUnlock(true)
|
||||
f(gm.m)
|
||||
}
|
||||
|
||||
// 交换Map中的键和值.
|
||||
func (this *IntStringMap) Flip() {
|
||||
this.mu.Lock()
|
||||
defer this.mu.Unlock()
|
||||
n := make(map[int]string, len(this.m))
|
||||
for k, v := range this.m {
|
||||
func (gm *IntStringMap) Flip() {
|
||||
gm.mu.Lock()
|
||||
defer gm.mu.Unlock()
|
||||
n := make(map[int]string, len(gm.m))
|
||||
for k, v := range gm.m {
|
||||
n[gconv.Int(v)] = gconv.String(k)
|
||||
}
|
||||
this.m = n
|
||||
gm.m = n
|
||||
}
|
||||
|
||||
// 合并两个Map.
|
||||
func (this *IntStringMap) Merge(m *IntStringMap) {
|
||||
this.mu.Lock()
|
||||
defer this.mu.Unlock()
|
||||
if m != this {
|
||||
func (gm *IntStringMap) Merge(m *IntStringMap) {
|
||||
gm.mu.Lock()
|
||||
defer gm.mu.Unlock()
|
||||
if m != gm {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
}
|
||||
for k, v := range m.m {
|
||||
this.m[k] = v
|
||||
gm.m[k] = v
|
||||
}
|
||||
}
|
@ -1,232 +0,0 @@
|
||||
// Copyright 2017 gf Author(https://gitee.com/johng/gf). All Rights Reserved.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the MIT License.
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://gitee.com/johng/gf.
|
||||
//
|
||||
|
||||
package gmap
|
||||
|
||||
import (
|
||||
"gitee.com/johng/gf/g/internal/rwmutex"
|
||||
)
|
||||
|
||||
type InterfaceInterfaceMap struct {
|
||||
mu *rwmutex.RWMutex
|
||||
m map[interface{}]interface{}
|
||||
}
|
||||
|
||||
func NewInterfaceInterfaceMap(unsafe...bool) *InterfaceInterfaceMap {
|
||||
return &InterfaceInterfaceMap{
|
||||
m : make(map[interface{}]interface{}),
|
||||
mu : rwmutex.New(unsafe...),
|
||||
}
|
||||
}
|
||||
|
||||
// 给定回调函数对原始内容进行遍历,回调函数返回true表示继续遍历,否则停止遍历
|
||||
func (this *InterfaceInterfaceMap) Iterator(f func (k interface{}, v interface{}) bool) {
|
||||
this.mu.RLock()
|
||||
defer this.mu.RUnlock()
|
||||
for k, v := range this.m {
|
||||
if !f(k, v) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 哈希表克隆
|
||||
func (this *InterfaceInterfaceMap) Clone() map[interface{}]interface{} {
|
||||
m := make(map[interface{}]interface{})
|
||||
this.mu.RLock()
|
||||
for k, v := range this.m {
|
||||
m[k] = v
|
||||
}
|
||||
this.mu.RUnlock()
|
||||
return m
|
||||
}
|
||||
|
||||
// 设置键值对
|
||||
func (this *InterfaceInterfaceMap) Set(key interface{}, val interface{}) {
|
||||
this.mu.Lock()
|
||||
this.m[key] = val
|
||||
this.mu.Unlock()
|
||||
}
|
||||
|
||||
// 批量设置键值对
|
||||
func (this *InterfaceInterfaceMap) BatchSet(m map[interface{}]interface{}) {
|
||||
this.mu.Lock()
|
||||
for k, v := range m {
|
||||
this.m[k] = v
|
||||
}
|
||||
this.mu.Unlock()
|
||||
}
|
||||
|
||||
// 获取键值
|
||||
func (this *InterfaceInterfaceMap) Get(key interface{}) interface{} {
|
||||
this.mu.RLock()
|
||||
val, _ := this.m[key]
|
||||
this.mu.RUnlock()
|
||||
return val
|
||||
}
|
||||
|
||||
// 设置kv缓存键值对,内部会对键名的存在性使用写锁进行二次检索确认,如果存在则不再写入;返回键名对应的键值。
|
||||
// 在高并发下有用,防止数据写入的并发逻辑错误。
|
||||
func (this *InterfaceInterfaceMap) doSetWithLockCheck(key interface{}, value interface{}) interface{} {
|
||||
this.mu.Lock()
|
||||
defer this.mu.Unlock()
|
||||
if v, ok := this.m[key]; ok {
|
||||
return v
|
||||
}
|
||||
if f, ok := value.(func() interface {}); ok {
|
||||
value = f()
|
||||
}
|
||||
this.m[key] = value
|
||||
return value
|
||||
}
|
||||
|
||||
// 当键名存在时返回其键值,否则写入指定的键值
|
||||
func (this *InterfaceInterfaceMap) GetOrSet(key interface{}, value interface{}) interface{} {
|
||||
if v := this.Get(key); v == nil {
|
||||
return this.doSetWithLockCheck(key, value)
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
// 当键名存在时返回其键值,否则写入指定的键值,键值由指定的函数生成
|
||||
func (this *InterfaceInterfaceMap) GetOrSetFunc(key interface{}, f func() interface{}) interface{} {
|
||||
if v := this.Get(key); v == nil {
|
||||
return this.doSetWithLockCheck(key, f())
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
// 与GetOrSetFunc不同的是,f是在写锁机制内执行
|
||||
func (this *InterfaceInterfaceMap) GetOrSetFuncLock(key interface{}, f func() interface{}) interface{} {
|
||||
if v := this.Get(key); v == nil {
|
||||
return this.doSetWithLockCheck(key, f)
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
// 当键名不存在时写入,并返回true;否则返回false。
|
||||
func (this *InterfaceInterfaceMap) SetIfNotExist(key interface{}, value interface{}) bool {
|
||||
if !this.Contains(key) {
|
||||
this.doSetWithLockCheck(key, value)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// 批量删除键值对
|
||||
func (this *InterfaceInterfaceMap) BatchRemove(keys []interface{}) {
|
||||
this.mu.Lock()
|
||||
for _, key := range keys {
|
||||
delete(this.m, key)
|
||||
}
|
||||
this.mu.Unlock()
|
||||
}
|
||||
|
||||
// 返回对应的键值,并删除该键值
|
||||
func (this *InterfaceInterfaceMap) Remove(key interface{}) interface{} {
|
||||
this.mu.Lock()
|
||||
val, exists := this.m[key]
|
||||
if exists {
|
||||
delete(this.m, key)
|
||||
}
|
||||
this.mu.Unlock()
|
||||
return val
|
||||
}
|
||||
|
||||
// 返回键列表
|
||||
func (this *InterfaceInterfaceMap) Keys() []interface{} {
|
||||
this.mu.RLock()
|
||||
keys := make([]interface{}, 0)
|
||||
for key, _ := range this.m {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
this.mu.RUnlock()
|
||||
return keys
|
||||
}
|
||||
|
||||
// 返回值列表(注意是随机排序)
|
||||
func (this *InterfaceInterfaceMap) Values() []interface{} {
|
||||
this.mu.RLock()
|
||||
vals := make([]interface{}, 0)
|
||||
for _, val := range this.m {
|
||||
vals = append(vals, val)
|
||||
}
|
||||
this.mu.RUnlock()
|
||||
return vals
|
||||
}
|
||||
|
||||
// 是否存在某个键
|
||||
func (this *InterfaceInterfaceMap) Contains(key interface{}) bool {
|
||||
this.mu.RLock()
|
||||
_, exists := this.m[key]
|
||||
this.mu.RUnlock()
|
||||
return exists
|
||||
}
|
||||
|
||||
// 哈希表大小
|
||||
func (this *InterfaceInterfaceMap) Size() int {
|
||||
this.mu.RLock()
|
||||
length := len(this.m)
|
||||
this.mu.RUnlock()
|
||||
return length
|
||||
}
|
||||
|
||||
// 哈希表是否为空
|
||||
func (this *InterfaceInterfaceMap) IsEmpty() bool {
|
||||
this.mu.RLock()
|
||||
empty := len(this.m) == 0
|
||||
this.mu.RUnlock()
|
||||
return empty
|
||||
}
|
||||
|
||||
// 清空哈希表
|
||||
func (this *InterfaceInterfaceMap) Clear() {
|
||||
this.mu.Lock()
|
||||
this.m = make(map[interface{}]interface{})
|
||||
this.mu.Unlock()
|
||||
}
|
||||
|
||||
// 并发安全锁操作,使用自定义方法执行加锁修改操作
|
||||
func (this *InterfaceInterfaceMap) LockFunc(f func(m map[interface{}]interface{})) {
|
||||
this.mu.Lock(true)
|
||||
defer this.mu.Unlock(true)
|
||||
f(this.m)
|
||||
}
|
||||
|
||||
// 并发安全锁操作,使用自定义方法执行加锁读取操作
|
||||
func (this *InterfaceInterfaceMap) RLockFunc(f func(m map[interface{}]interface{})) {
|
||||
this.mu.RLock(true)
|
||||
defer this.mu.RUnlock(true)
|
||||
f(this.m)
|
||||
}
|
||||
|
||||
// 交换Map中的键和值.
|
||||
func (this *InterfaceInterfaceMap) Flip() {
|
||||
this.mu.Lock()
|
||||
defer this.mu.Unlock()
|
||||
n := make(map[interface{}]interface{}, len(this.m))
|
||||
for i, v := range this.m {
|
||||
n[v] = i
|
||||
}
|
||||
this.m = n
|
||||
}
|
||||
|
||||
// 合并两个Map.
|
||||
func (this *InterfaceInterfaceMap) Merge(m *Map) {
|
||||
this.mu.Lock()
|
||||
defer this.mu.Unlock()
|
||||
if m != this {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
}
|
||||
for k, v := range m.m {
|
||||
this.m[k] = v
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
// Copyright 2017 gf Author(https://gitee.com/johng/gf). All Rights Reserved.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the MIT License.
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// If a copy of the MIT was not distributed with gm file,
|
||||
// You can obtain one at https://gitee.com/johng/gf.
|
||||
//
|
||||
|
||||
@ -24,10 +24,10 @@ func NewStringBoolMap(unsafe...bool) *StringBoolMap {
|
||||
}
|
||||
|
||||
// 给定回调函数对原始内容进行遍历,回调函数返回true表示继续遍历,否则停止遍历
|
||||
func (this *StringBoolMap) Iterator(f func (k string, v bool) bool) {
|
||||
this.mu.RLock()
|
||||
defer this.mu.RUnlock()
|
||||
for k, v := range this.m {
|
||||
func (gm *StringBoolMap) Iterator(f func (k string, v bool) bool) {
|
||||
gm.mu.RLock()
|
||||
defer gm.mu.RUnlock()
|
||||
for k, v := range gm.m {
|
||||
if !f(k, v) {
|
||||
break
|
||||
}
|
||||
@ -35,91 +35,91 @@ func (this *StringBoolMap) Iterator(f func (k string, v bool) bool) {
|
||||
}
|
||||
|
||||
// 哈希表克隆
|
||||
func (this *StringBoolMap) Clone() map[string]bool {
|
||||
func (gm *StringBoolMap) Clone() map[string]bool {
|
||||
m := make(map[string]bool)
|
||||
this.mu.RLock()
|
||||
for k, v := range this.m {
|
||||
gm.mu.RLock()
|
||||
for k, v := range gm.m {
|
||||
m[k] = v
|
||||
}
|
||||
this.mu.RUnlock()
|
||||
gm.mu.RUnlock()
|
||||
return m
|
||||
}
|
||||
|
||||
// 设置键值对
|
||||
func (this *StringBoolMap) Set(key string, val bool) {
|
||||
this.mu.Lock()
|
||||
this.m[key] = val
|
||||
this.mu.Unlock()
|
||||
func (gm *StringBoolMap) Set(key string, val bool) {
|
||||
gm.mu.Lock()
|
||||
gm.m[key] = val
|
||||
gm.mu.Unlock()
|
||||
}
|
||||
|
||||
// 批量设置键值对
|
||||
func (this *StringBoolMap) BatchSet(m map[string]bool) {
|
||||
this.mu.Lock()
|
||||
func (gm *StringBoolMap) BatchSet(m map[string]bool) {
|
||||
gm.mu.Lock()
|
||||
for k, v := range m {
|
||||
this.m[k] = v
|
||||
gm.m[k] = v
|
||||
}
|
||||
this.mu.Unlock()
|
||||
gm.mu.Unlock()
|
||||
}
|
||||
|
||||
// 获取键值
|
||||
func (this *StringBoolMap) Get(key string) bool {
|
||||
this.mu.RLock()
|
||||
val, _ := this.m[key]
|
||||
this.mu.RUnlock()
|
||||
func (gm *StringBoolMap) Get(key string) bool {
|
||||
gm.mu.RLock()
|
||||
val, _ := gm.m[key]
|
||||
gm.mu.RUnlock()
|
||||
return val
|
||||
}
|
||||
|
||||
// 设置kv缓存键值对,内部会对键名的存在性使用写锁进行二次检索确认,如果存在则不再写入;返回键名对应的键值。
|
||||
// 在高并发下有用,防止数据写入的并发逻辑错误。
|
||||
func (this *StringBoolMap) doSetWithLockCheck(key string, value bool) bool {
|
||||
this.mu.Lock()
|
||||
if v, ok := this.m[key]; ok {
|
||||
this.mu.Unlock()
|
||||
func (gm *StringBoolMap) doSetWithLockCheck(key string, value bool) bool {
|
||||
gm.mu.Lock()
|
||||
if v, ok := gm.m[key]; ok {
|
||||
gm.mu.Unlock()
|
||||
return v
|
||||
}
|
||||
this.m[key] = value
|
||||
this.mu.Unlock()
|
||||
gm.m[key] = value
|
||||
gm.mu.Unlock()
|
||||
return value
|
||||
}
|
||||
|
||||
// 当键名存在时返回其键值,否则写入指定的键值
|
||||
func (this *StringBoolMap) GetOrSet(key string, value bool) bool {
|
||||
this.mu.RLock()
|
||||
v, ok := this.m[key]
|
||||
this.mu.RUnlock()
|
||||
func (gm *StringBoolMap) GetOrSet(key string, value bool) bool {
|
||||
gm.mu.RLock()
|
||||
v, ok := gm.m[key]
|
||||
gm.mu.RUnlock()
|
||||
if !ok {
|
||||
return this.doSetWithLockCheck(key, value)
|
||||
return gm.doSetWithLockCheck(key, value)
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
// 当键名存在时返回其键值,否则写入指定的键值,键值由指定的函数生成
|
||||
func (this *StringBoolMap) GetOrSetFunc(key string, f func() bool) bool {
|
||||
this.mu.RLock()
|
||||
v, ok := this.m[key]
|
||||
this.mu.RUnlock()
|
||||
func (gm *StringBoolMap) GetOrSetFunc(key string, f func() bool) bool {
|
||||
gm.mu.RLock()
|
||||
v, ok := gm.m[key]
|
||||
gm.mu.RUnlock()
|
||||
if !ok {
|
||||
return this.doSetWithLockCheck(key, f())
|
||||
return gm.doSetWithLockCheck(key, f())
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
// 与GetOrSetFunc不同的是,f是在写锁机制内执行
|
||||
func (this *StringBoolMap) GetOrSetFuncLock(key string, f func() bool) bool {
|
||||
this.mu.RLock()
|
||||
val, ok := this.m[key]
|
||||
this.mu.RUnlock()
|
||||
func (gm *StringBoolMap) GetOrSetFuncLock(key string, f func() bool) bool {
|
||||
gm.mu.RLock()
|
||||
val, ok := gm.m[key]
|
||||
gm.mu.RUnlock()
|
||||
if !ok {
|
||||
this.mu.Lock()
|
||||
defer this.mu.Unlock()
|
||||
if v, ok := this.m[key]; ok {
|
||||
this.mu.Unlock()
|
||||
gm.mu.Lock()
|
||||
defer gm.mu.Unlock()
|
||||
if v, ok := gm.m[key]; ok {
|
||||
gm.mu.Unlock()
|
||||
return v
|
||||
}
|
||||
val = f()
|
||||
this.m[key] = val
|
||||
gm.m[key] = val
|
||||
return val
|
||||
} else {
|
||||
return val
|
||||
@ -127,110 +127,110 @@ func (this *StringBoolMap) GetOrSetFuncLock(key string, f func() bool) bool {
|
||||
}
|
||||
|
||||
// 当键名不存在时写入,并返回true;否则返回false。
|
||||
func (this *StringBoolMap) SetIfNotExist(key string, value bool) bool {
|
||||
if !this.Contains(key) {
|
||||
this.doSetWithLockCheck(key, value)
|
||||
func (gm *StringBoolMap) SetIfNotExist(key string, value bool) bool {
|
||||
if !gm.Contains(key) {
|
||||
gm.doSetWithLockCheck(key, value)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// 批量删除键值对
|
||||
func (this *StringBoolMap) BatchRemove(keys []string) {
|
||||
this.mu.Lock()
|
||||
func (gm *StringBoolMap) BatchRemove(keys []string) {
|
||||
gm.mu.Lock()
|
||||
for _, key := range keys {
|
||||
delete(this.m, key)
|
||||
delete(gm.m, key)
|
||||
}
|
||||
this.mu.Unlock()
|
||||
gm.mu.Unlock()
|
||||
}
|
||||
|
||||
// 返回对应的键值,并删除该键值
|
||||
func (this *StringBoolMap) Remove(key string) bool {
|
||||
this.mu.Lock()
|
||||
val, exists := this.m[key]
|
||||
func (gm *StringBoolMap) Remove(key string) bool {
|
||||
gm.mu.Lock()
|
||||
val, exists := gm.m[key]
|
||||
if exists {
|
||||
delete(this.m, key)
|
||||
delete(gm.m, key)
|
||||
}
|
||||
this.mu.Unlock()
|
||||
gm.mu.Unlock()
|
||||
return val
|
||||
}
|
||||
|
||||
// 返回键列表
|
||||
func (this *StringBoolMap) Keys() []string {
|
||||
this.mu.RLock()
|
||||
func (gm *StringBoolMap) Keys() []string {
|
||||
gm.mu.RLock()
|
||||
keys := make([]string, 0)
|
||||
for key, _ := range this.m {
|
||||
for key, _ := range gm.m {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
this.mu.RUnlock()
|
||||
gm.mu.RUnlock()
|
||||
return keys
|
||||
}
|
||||
|
||||
// 返回值列表(注意是随机排序)
|
||||
//func (this *StringBoolMap) Values() []bool {
|
||||
// this.mu.RLock()
|
||||
//func (gm *StringBoolMap) Values() []bool {
|
||||
// gm.mu.RLock()
|
||||
// vals := make([]bool, 0)
|
||||
// for _, val := range this.m {
|
||||
// for _, val := range gm.m {
|
||||
// vals = append(vals, val)
|
||||
// }
|
||||
// this.mu.RUnlock()
|
||||
// gm.mu.RUnlock()
|
||||
// return vals
|
||||
//}
|
||||
|
||||
// 是否存在某个键
|
||||
func (this *StringBoolMap) Contains(key string) bool {
|
||||
this.mu.RLock()
|
||||
_, exists := this.m[key]
|
||||
this.mu.RUnlock()
|
||||
func (gm *StringBoolMap) Contains(key string) bool {
|
||||
gm.mu.RLock()
|
||||
_, exists := gm.m[key]
|
||||
gm.mu.RUnlock()
|
||||
return exists
|
||||
}
|
||||
|
||||
// 哈希表大小
|
||||
func (this *StringBoolMap) Size() int {
|
||||
this.mu.RLock()
|
||||
length := len(this.m)
|
||||
this.mu.RUnlock()
|
||||
func (gm *StringBoolMap) Size() int {
|
||||
gm.mu.RLock()
|
||||
length := len(gm.m)
|
||||
gm.mu.RUnlock()
|
||||
return length
|
||||
}
|
||||
|
||||
// 哈希表是否为空
|
||||
func (this *StringBoolMap) IsEmpty() bool {
|
||||
this.mu.RLock()
|
||||
empty := len(this.m) == 0
|
||||
this.mu.RUnlock()
|
||||
func (gm *StringBoolMap) IsEmpty() bool {
|
||||
gm.mu.RLock()
|
||||
empty := len(gm.m) == 0
|
||||
gm.mu.RUnlock()
|
||||
return empty
|
||||
}
|
||||
|
||||
// 清空哈希表
|
||||
func (this *StringBoolMap) Clear() {
|
||||
this.mu.Lock()
|
||||
this.m = make(map[string]bool)
|
||||
this.mu.Unlock()
|
||||
func (gm *StringBoolMap) Clear() {
|
||||
gm.mu.Lock()
|
||||
gm.m = make(map[string]bool)
|
||||
gm.mu.Unlock()
|
||||
}
|
||||
|
||||
// 并发安全锁操作,使用自定义方法执行加锁修改操作
|
||||
func (this *StringBoolMap) LockFunc(f func(m map[string]bool)) {
|
||||
this.mu.Lock(true)
|
||||
defer this.mu.Unlock(true)
|
||||
f(this.m)
|
||||
func (gm *StringBoolMap) LockFunc(f func(m map[string]bool)) {
|
||||
gm.mu.Lock(true)
|
||||
defer gm.mu.Unlock(true)
|
||||
f(gm.m)
|
||||
}
|
||||
|
||||
// 并发安全锁操作,使用自定义方法执行加锁读取操作
|
||||
func (this *StringBoolMap) RLockFunc(f func(m map[string]bool)) {
|
||||
this.mu.RLock(true)
|
||||
defer this.mu.RUnlock(true)
|
||||
f(this.m)
|
||||
func (gm *StringBoolMap) RLockFunc(f func(m map[string]bool)) {
|
||||
gm.mu.RLock(true)
|
||||
defer gm.mu.RUnlock(true)
|
||||
f(gm.m)
|
||||
}
|
||||
|
||||
// 合并两个Map.
|
||||
func (this *StringBoolMap) Merge(m *StringBoolMap) {
|
||||
this.mu.Lock()
|
||||
defer this.mu.Unlock()
|
||||
if m != this {
|
||||
func (gm *StringBoolMap) Merge(m *StringBoolMap) {
|
||||
gm.mu.Lock()
|
||||
defer gm.mu.Unlock()
|
||||
if m != gm {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
}
|
||||
for k, v := range m.m {
|
||||
this.m[k] = v
|
||||
gm.m[k] = v
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
// Copyright 2017 gf Author(https://gitee.com/johng/gf). All Rights Reserved.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the MIT License.
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// If a copy of the MIT was not distributed with gm file,
|
||||
// You can obtain one at https://gitee.com/johng/gf.
|
||||
//
|
||||
|
||||
@ -25,10 +25,10 @@ func NewStringIntMap(unsafe...bool) *StringIntMap {
|
||||
}
|
||||
|
||||
// 给定回调函数对原始内容进行遍历,回调函数返回true表示继续遍历,否则停止遍历
|
||||
func (this *StringIntMap) Iterator(f func (k string, v int) bool) {
|
||||
this.mu.RLock()
|
||||
defer this.mu.RUnlock()
|
||||
for k, v := range this.m {
|
||||
func (gm *StringIntMap) Iterator(f func (k string, v int) bool) {
|
||||
gm.mu.RLock()
|
||||
defer gm.mu.RUnlock()
|
||||
for k, v := range gm.m {
|
||||
if !f(k, v) {
|
||||
break
|
||||
}
|
||||
@ -36,91 +36,91 @@ func (this *StringIntMap) Iterator(f func (k string, v int) bool) {
|
||||
}
|
||||
|
||||
// 哈希表克隆
|
||||
func (this *StringIntMap) Clone() map[string]int {
|
||||
func (gm *StringIntMap) Clone() map[string]int {
|
||||
m := make(map[string]int)
|
||||
this.mu.RLock()
|
||||
for k, v := range this.m {
|
||||
gm.mu.RLock()
|
||||
for k, v := range gm.m {
|
||||
m[k] = v
|
||||
}
|
||||
this.mu.RUnlock()
|
||||
gm.mu.RUnlock()
|
||||
return m
|
||||
}
|
||||
|
||||
// 设置键值对
|
||||
func (this *StringIntMap) Set(key string, val int) {
|
||||
this.mu.Lock()
|
||||
this.m[key] = val
|
||||
this.mu.Unlock()
|
||||
func (gm *StringIntMap) Set(key string, val int) {
|
||||
gm.mu.Lock()
|
||||
gm.m[key] = val
|
||||
gm.mu.Unlock()
|
||||
}
|
||||
|
||||
// 批量设置键值对
|
||||
func (this *StringIntMap) BatchSet(m map[string]int) {
|
||||
this.mu.Lock()
|
||||
func (gm *StringIntMap) BatchSet(m map[string]int) {
|
||||
gm.mu.Lock()
|
||||
for k, v := range m {
|
||||
this.m[k] = v
|
||||
gm.m[k] = v
|
||||
}
|
||||
this.mu.Unlock()
|
||||
gm.mu.Unlock()
|
||||
}
|
||||
|
||||
// 获取键值
|
||||
func (this *StringIntMap) Get(key string) int {
|
||||
this.mu.RLock()
|
||||
val, _ := this.m[key]
|
||||
this.mu.RUnlock()
|
||||
func (gm *StringIntMap) Get(key string) int {
|
||||
gm.mu.RLock()
|
||||
val, _ := gm.m[key]
|
||||
gm.mu.RUnlock()
|
||||
return val
|
||||
}
|
||||
|
||||
// 设置kv缓存键值对,内部会对键名的存在性使用写锁进行二次检索确认,如果存在则不再写入;返回键名对应的键值。
|
||||
// 在高并发下有用,防止数据写入的并发逻辑错误。
|
||||
func (this *StringIntMap) doSetWithLockCheck(key string, value int) int {
|
||||
this.mu.Lock()
|
||||
if v, ok := this.m[key]; ok {
|
||||
this.mu.Unlock()
|
||||
func (gm *StringIntMap) doSetWithLockCheck(key string, value int) int {
|
||||
gm.mu.Lock()
|
||||
if v, ok := gm.m[key]; ok {
|
||||
gm.mu.Unlock()
|
||||
return v
|
||||
}
|
||||
this.m[key] = value
|
||||
this.mu.Unlock()
|
||||
gm.m[key] = value
|
||||
gm.mu.Unlock()
|
||||
return value
|
||||
}
|
||||
|
||||
// 当键名存在时返回其键值,否则写入指定的键值
|
||||
func (this *StringIntMap) GetOrSet(key string, value int) int {
|
||||
this.mu.RLock()
|
||||
v, ok := this.m[key]
|
||||
this.mu.RUnlock()
|
||||
func (gm *StringIntMap) GetOrSet(key string, value int) int {
|
||||
gm.mu.RLock()
|
||||
v, ok := gm.m[key]
|
||||
gm.mu.RUnlock()
|
||||
if !ok {
|
||||
return this.doSetWithLockCheck(key, value)
|
||||
return gm.doSetWithLockCheck(key, value)
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
// 当键名存在时返回其键值,否则写入指定的键值,键值由指定的函数生成
|
||||
func (this *StringIntMap) GetOrSetFunc(key string, f func() int) int {
|
||||
this.mu.RLock()
|
||||
v, ok := this.m[key]
|
||||
this.mu.RUnlock()
|
||||
func (gm *StringIntMap) GetOrSetFunc(key string, f func() int) int {
|
||||
gm.mu.RLock()
|
||||
v, ok := gm.m[key]
|
||||
gm.mu.RUnlock()
|
||||
if !ok {
|
||||
return this.doSetWithLockCheck(key, f())
|
||||
return gm.doSetWithLockCheck(key, f())
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
// 与GetOrSetFunc不同的是,f是在写锁机制内执行
|
||||
func (this *StringIntMap) GetOrSetFuncLock(key string, f func() int) int {
|
||||
this.mu.RLock()
|
||||
val, ok := this.m[key]
|
||||
this.mu.RUnlock()
|
||||
func (gm *StringIntMap) GetOrSetFuncLock(key string, f func() int) int {
|
||||
gm.mu.RLock()
|
||||
val, ok := gm.m[key]
|
||||
gm.mu.RUnlock()
|
||||
if !ok {
|
||||
this.mu.Lock()
|
||||
defer this.mu.Unlock()
|
||||
if v, ok := this.m[key]; ok {
|
||||
this.mu.Unlock()
|
||||
gm.mu.Lock()
|
||||
defer gm.mu.Unlock()
|
||||
if v, ok := gm.m[key]; ok {
|
||||
gm.mu.Unlock()
|
||||
return v
|
||||
}
|
||||
val = f()
|
||||
this.m[key] = val
|
||||
gm.m[key] = val
|
||||
return val
|
||||
} else {
|
||||
return val
|
||||
@ -128,121 +128,121 @@ func (this *StringIntMap) GetOrSetFuncLock(key string, f func() int) int {
|
||||
}
|
||||
|
||||
// 当键名不存在时写入,并返回true;否则返回false。
|
||||
func (this *StringIntMap) SetIfNotExist(key string, value int) bool {
|
||||
if !this.Contains(key) {
|
||||
this.doSetWithLockCheck(key, value)
|
||||
func (gm *StringIntMap) SetIfNotExist(key string, value int) bool {
|
||||
if !gm.Contains(key) {
|
||||
gm.doSetWithLockCheck(key, value)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// 批量删除键值对
|
||||
func (this *StringIntMap) BatchRemove(keys []string) {
|
||||
this.mu.Lock()
|
||||
func (gm *StringIntMap) BatchRemove(keys []string) {
|
||||
gm.mu.Lock()
|
||||
for _, key := range keys {
|
||||
delete(this.m, key)
|
||||
delete(gm.m, key)
|
||||
}
|
||||
this.mu.Unlock()
|
||||
gm.mu.Unlock()
|
||||
}
|
||||
|
||||
// 返回对应的键值,并删除该键值
|
||||
func (this *StringIntMap) Remove(key string) int {
|
||||
this.mu.Lock()
|
||||
val, exists := this.m[key]
|
||||
func (gm *StringIntMap) Remove(key string) int {
|
||||
gm.mu.Lock()
|
||||
val, exists := gm.m[key]
|
||||
if exists {
|
||||
delete(this.m, key)
|
||||
delete(gm.m, key)
|
||||
}
|
||||
this.mu.Unlock()
|
||||
gm.mu.Unlock()
|
||||
return val
|
||||
}
|
||||
|
||||
// 返回键列表
|
||||
func (this *StringIntMap) Keys() []string {
|
||||
this.mu.RLock()
|
||||
func (gm *StringIntMap) Keys() []string {
|
||||
gm.mu.RLock()
|
||||
keys := make([]string, 0)
|
||||
for key, _ := range this.m {
|
||||
for key, _ := range gm.m {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
this.mu.RUnlock()
|
||||
gm.mu.RUnlock()
|
||||
return keys
|
||||
}
|
||||
|
||||
// 返回值列表(注意是随机排序)
|
||||
func (this *StringIntMap) Values() []int {
|
||||
this.mu.RLock()
|
||||
func (gm *StringIntMap) Values() []int {
|
||||
gm.mu.RLock()
|
||||
vals := make([]int, 0)
|
||||
for _, val := range this.m {
|
||||
for _, val := range gm.m {
|
||||
vals = append(vals, val)
|
||||
}
|
||||
this.mu.RUnlock()
|
||||
gm.mu.RUnlock()
|
||||
return vals
|
||||
}
|
||||
|
||||
// 是否存在某个键
|
||||
func (this *StringIntMap) Contains(key string) bool {
|
||||
this.mu.RLock()
|
||||
_, exists := this.m[key]
|
||||
this.mu.RUnlock()
|
||||
func (gm *StringIntMap) Contains(key string) bool {
|
||||
gm.mu.RLock()
|
||||
_, exists := gm.m[key]
|
||||
gm.mu.RUnlock()
|
||||
return exists
|
||||
}
|
||||
|
||||
// 哈希表大小
|
||||
func (this *StringIntMap) Size() int {
|
||||
this.mu.RLock()
|
||||
length := len(this.m)
|
||||
this.mu.RUnlock()
|
||||
func (gm *StringIntMap) Size() int {
|
||||
gm.mu.RLock()
|
||||
length := len(gm.m)
|
||||
gm.mu.RUnlock()
|
||||
return length
|
||||
}
|
||||
|
||||
// 哈希表是否为空
|
||||
func (this *StringIntMap) IsEmpty() bool {
|
||||
this.mu.RLock()
|
||||
empty := len(this.m) == 0
|
||||
this.mu.RUnlock()
|
||||
func (gm *StringIntMap) IsEmpty() bool {
|
||||
gm.mu.RLock()
|
||||
empty := len(gm.m) == 0
|
||||
gm.mu.RUnlock()
|
||||
return empty
|
||||
}
|
||||
|
||||
// 清空哈希表
|
||||
func (this *StringIntMap) Clear() {
|
||||
this.mu.Lock()
|
||||
this.m = make(map[string]int)
|
||||
this.mu.Unlock()
|
||||
func (gm *StringIntMap) Clear() {
|
||||
gm.mu.Lock()
|
||||
gm.m = make(map[string]int)
|
||||
gm.mu.Unlock()
|
||||
}
|
||||
|
||||
// 并发安全写锁操作,使用自定义方法执行加锁修改操作
|
||||
func (this *StringIntMap) LockFunc(f func(m map[string]int)) {
|
||||
this.mu.Lock(true)
|
||||
defer this.mu.Unlock(true)
|
||||
f(this.m)
|
||||
func (gm *StringIntMap) LockFunc(f func(m map[string]int)) {
|
||||
gm.mu.Lock(true)
|
||||
defer gm.mu.Unlock(true)
|
||||
f(gm.m)
|
||||
}
|
||||
|
||||
// 并发安全读锁操作,使用自定义方法执行加锁读取操作
|
||||
func (this *StringIntMap) RLockFunc(f func(m map[string]int)) {
|
||||
this.mu.RLock(true)
|
||||
defer this.mu.RUnlock(true)
|
||||
f(this.m)
|
||||
func (gm *StringIntMap) RLockFunc(f func(m map[string]int)) {
|
||||
gm.mu.RLock(true)
|
||||
defer gm.mu.RUnlock(true)
|
||||
f(gm.m)
|
||||
}
|
||||
|
||||
// 交换Map中的键和值.
|
||||
func (this *StringIntMap) Flip() {
|
||||
this.mu.Lock()
|
||||
defer this.mu.Unlock()
|
||||
n := make(map[string]int, len(this.m))
|
||||
for k, v := range this.m {
|
||||
func (gm *StringIntMap) Flip() {
|
||||
gm.mu.Lock()
|
||||
defer gm.mu.Unlock()
|
||||
n := make(map[string]int, len(gm.m))
|
||||
for k, v := range gm.m {
|
||||
n[gconv.String(v)] = gconv.Int(k)
|
||||
}
|
||||
this.m = n
|
||||
gm.m = n
|
||||
}
|
||||
|
||||
// 合并两个Map.
|
||||
func (this *StringIntMap) Merge(m *StringIntMap) {
|
||||
this.mu.Lock()
|
||||
defer this.mu.Unlock()
|
||||
if m != this {
|
||||
func (gm *StringIntMap) Merge(m *StringIntMap) {
|
||||
gm.mu.Lock()
|
||||
defer gm.mu.Unlock()
|
||||
if m != gm {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
}
|
||||
for k, v := range m.m {
|
||||
this.m[k] = v
|
||||
gm.m[k] = v
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
// Copyright 2017 gf Author(https://gitee.com/johng/gf). All Rights Reserved.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the MIT License.
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// If a copy of the MIT was not distributed with gm file,
|
||||
// You can obtain one at https://gitee.com/johng/gf.
|
||||
//
|
||||
|
||||
@ -25,10 +25,10 @@ func NewStringInterfaceMap(unsafe...bool) *StringInterfaceMap {
|
||||
}
|
||||
|
||||
// 给定回调函数对原始内容进行遍历,回调函数返回true表示继续遍历,否则停止遍历
|
||||
func (this *StringInterfaceMap) Iterator(f func (k string, v interface{}) bool) {
|
||||
this.mu.RLock()
|
||||
defer this.mu.RUnlock()
|
||||
for k, v := range this.m {
|
||||
func (gm *StringInterfaceMap) Iterator(f func (k string, v interface{}) bool) {
|
||||
gm.mu.RLock()
|
||||
defer gm.mu.RUnlock()
|
||||
for k, v := range gm.m {
|
||||
if !f(k, v) {
|
||||
break
|
||||
}
|
||||
@ -36,198 +36,198 @@ func (this *StringInterfaceMap) Iterator(f func (k string, v interface{}) bool)
|
||||
}
|
||||
|
||||
// 哈希表克隆
|
||||
func (this *StringInterfaceMap) Clone() map[string]interface{} {
|
||||
func (gm *StringInterfaceMap) Clone() map[string]interface{} {
|
||||
m := make(map[string]interface{})
|
||||
this.mu.RLock()
|
||||
for k, v := range this.m {
|
||||
gm.mu.RLock()
|
||||
for k, v := range gm.m {
|
||||
m[k] = v
|
||||
}
|
||||
this.mu.RUnlock()
|
||||
gm.mu.RUnlock()
|
||||
return m
|
||||
}
|
||||
|
||||
// 设置键值对
|
||||
func (this *StringInterfaceMap) Set(key string, val interface{}) {
|
||||
this.mu.Lock()
|
||||
this.m[key] = val
|
||||
this.mu.Unlock()
|
||||
func (gm *StringInterfaceMap) Set(key string, val interface{}) {
|
||||
gm.mu.Lock()
|
||||
gm.m[key] = val
|
||||
gm.mu.Unlock()
|
||||
}
|
||||
|
||||
// 批量设置键值对
|
||||
func (this *StringInterfaceMap) BatchSet(m map[string]interface{}) {
|
||||
this.mu.Lock()
|
||||
func (gm *StringInterfaceMap) BatchSet(m map[string]interface{}) {
|
||||
gm.mu.Lock()
|
||||
for k, v := range m {
|
||||
this.m[k] = v
|
||||
gm.m[k] = v
|
||||
}
|
||||
this.mu.Unlock()
|
||||
gm.mu.Unlock()
|
||||
}
|
||||
|
||||
// 获取键值
|
||||
func (this *StringInterfaceMap) Get(key string) interface{} {
|
||||
this.mu.RLock()
|
||||
val, _ := this.m[key]
|
||||
this.mu.RUnlock()
|
||||
func (gm *StringInterfaceMap) Get(key string) interface{} {
|
||||
gm.mu.RLock()
|
||||
val, _ := gm.m[key]
|
||||
gm.mu.RUnlock()
|
||||
return val
|
||||
}
|
||||
|
||||
// 设置kv缓存键值对,内部会对键名的存在性使用写锁进行二次检索确认,如果存在则不再写入;返回键名对应的键值。
|
||||
// 在高并发下有用,防止数据写入的并发逻辑错误。
|
||||
func (this *StringInterfaceMap) doSetWithLockCheck(key string, value interface{}) interface{} {
|
||||
this.mu.Lock()
|
||||
defer this.mu.Unlock()
|
||||
if v, ok := this.m[key]; ok {
|
||||
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()
|
||||
}
|
||||
this.m[key] = value
|
||||
gm.m[key] = value
|
||||
return value
|
||||
}
|
||||
|
||||
// 当键名存在时返回其键值,否则写入指定的键值
|
||||
func (this *StringInterfaceMap) GetOrSet(key string, value interface{}) interface{} {
|
||||
if v := this.Get(key); v == nil {
|
||||
return this.doSetWithLockCheck(key, value)
|
||||
func (gm *StringInterfaceMap) GetOrSet(key string, value interface{}) interface{} {
|
||||
if v := gm.Get(key); v == nil {
|
||||
return gm.doSetWithLockCheck(key, value)
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
// 当键名存在时返回其键值,否则写入指定的键值,键值由指定的函数生成
|
||||
func (this *StringInterfaceMap) GetOrSetFunc(key string, f func() interface{}) interface{} {
|
||||
if v := this.Get(key); v == nil {
|
||||
return this.doSetWithLockCheck(key, f())
|
||||
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是在写锁机制内执行
|
||||
func (this *StringInterfaceMap) GetOrSetFuncLock(key string, f func() interface{}) interface{} {
|
||||
if v := this.Get(key); v == nil {
|
||||
return this.doSetWithLockCheck(key, f)
|
||||
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。
|
||||
func (this *StringInterfaceMap) SetIfNotExist(key string, value interface{}) bool {
|
||||
if !this.Contains(key) {
|
||||
this.doSetWithLockCheck(key, value)
|
||||
func (gm *StringInterfaceMap) SetIfNotExist(key string, value interface{}) bool {
|
||||
if !gm.Contains(key) {
|
||||
gm.doSetWithLockCheck(key, value)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// 批量删除键值对
|
||||
func (this *StringInterfaceMap) BatchRemove(keys []string) {
|
||||
this.mu.Lock()
|
||||
func (gm *StringInterfaceMap) BatchRemove(keys []string) {
|
||||
gm.mu.Lock()
|
||||
for _, key := range keys {
|
||||
delete(this.m, key)
|
||||
delete(gm.m, key)
|
||||
}
|
||||
this.mu.Unlock()
|
||||
gm.mu.Unlock()
|
||||
}
|
||||
|
||||
// 返回对应的键值,并删除该键值
|
||||
func (this *StringInterfaceMap) Remove(key string) interface{} {
|
||||
this.mu.Lock()
|
||||
val, exists := this.m[key]
|
||||
func (gm *StringInterfaceMap) Remove(key string) interface{} {
|
||||
gm.mu.Lock()
|
||||
val, exists := gm.m[key]
|
||||
if exists {
|
||||
delete(this.m, key)
|
||||
delete(gm.m, key)
|
||||
}
|
||||
this.mu.Unlock()
|
||||
gm.mu.Unlock()
|
||||
return val
|
||||
}
|
||||
|
||||
// 返回键列表
|
||||
func (this *StringInterfaceMap) Keys() []string {
|
||||
this.mu.RLock()
|
||||
func (gm *StringInterfaceMap) Keys() []string {
|
||||
gm.mu.RLock()
|
||||
keys := make([]string, 0)
|
||||
for key, _ := range this.m {
|
||||
for key, _ := range gm.m {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
this.mu.RUnlock()
|
||||
gm.mu.RUnlock()
|
||||
return keys
|
||||
}
|
||||
|
||||
// 返回值列表(注意是随机排序)
|
||||
func (this *StringInterfaceMap) Values() []interface{} {
|
||||
this.mu.RLock()
|
||||
func (gm *StringInterfaceMap) Values() []interface{} {
|
||||
gm.mu.RLock()
|
||||
vals := make([]interface{}, 0)
|
||||
for _, val := range this.m {
|
||||
for _, val := range gm.m {
|
||||
vals = append(vals, val)
|
||||
}
|
||||
this.mu.RUnlock()
|
||||
gm.mu.RUnlock()
|
||||
return vals
|
||||
}
|
||||
|
||||
// 是否存在某个键
|
||||
func (this *StringInterfaceMap) Contains(key string) bool {
|
||||
this.mu.RLock()
|
||||
_, exists := this.m[key]
|
||||
this.mu.RUnlock()
|
||||
func (gm *StringInterfaceMap) Contains(key string) bool {
|
||||
gm.mu.RLock()
|
||||
_, exists := gm.m[key]
|
||||
gm.mu.RUnlock()
|
||||
return exists
|
||||
}
|
||||
|
||||
// 哈希表大小
|
||||
func (this *StringInterfaceMap) Size() int {
|
||||
this.mu.RLock()
|
||||
length := len(this.m)
|
||||
this.mu.RUnlock()
|
||||
func (gm *StringInterfaceMap) Size() int {
|
||||
gm.mu.RLock()
|
||||
length := len(gm.m)
|
||||
gm.mu.RUnlock()
|
||||
return length
|
||||
}
|
||||
|
||||
// 哈希表是否为空
|
||||
func (this *StringInterfaceMap) IsEmpty() bool {
|
||||
this.mu.RLock()
|
||||
empty := len(this.m) == 0
|
||||
this.mu.RUnlock()
|
||||
func (gm *StringInterfaceMap) IsEmpty() bool {
|
||||
gm.mu.RLock()
|
||||
empty := len(gm.m) == 0
|
||||
gm.mu.RUnlock()
|
||||
return empty
|
||||
}
|
||||
|
||||
// 清空哈希表
|
||||
func (this *StringInterfaceMap) Clear() {
|
||||
this.mu.Lock()
|
||||
this.m = make(map[string]interface{})
|
||||
this.mu.Unlock()
|
||||
func (gm *StringInterfaceMap) Clear() {
|
||||
gm.mu.Lock()
|
||||
gm.m = make(map[string]interface{})
|
||||
gm.mu.Unlock()
|
||||
}
|
||||
|
||||
// 并发安全写锁操作,使用自定义方法执行加锁修改操作
|
||||
func (this *StringInterfaceMap) LockFunc(f func(m map[string]interface{})) {
|
||||
this.mu.Lock(true)
|
||||
defer this.mu.Unlock(true)
|
||||
f(this.m)
|
||||
func (gm *StringInterfaceMap) LockFunc(f func(m map[string]interface{})) {
|
||||
gm.mu.Lock(true)
|
||||
defer gm.mu.Unlock(true)
|
||||
f(gm.m)
|
||||
}
|
||||
|
||||
// 并发安全读锁操作,使用自定义方法执行加锁读取操作
|
||||
func (this *StringInterfaceMap) RLockFunc(f func(m map[string]interface{})) {
|
||||
this.mu.RLock(true)
|
||||
defer this.mu.RUnlock(true)
|
||||
f(this.m)
|
||||
func (gm *StringInterfaceMap) RLockFunc(f func(m map[string]interface{})) {
|
||||
gm.mu.RLock(true)
|
||||
defer gm.mu.RUnlock(true)
|
||||
f(gm.m)
|
||||
}
|
||||
|
||||
// 交换Map中的键和值.
|
||||
func (this *StringInterfaceMap) Flip() {
|
||||
this.mu.Lock()
|
||||
defer this.mu.Unlock()
|
||||
n := make(map[string]interface{}, len(this.m))
|
||||
for k, v := range this.m {
|
||||
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
|
||||
}
|
||||
this.m = n
|
||||
gm.m = n
|
||||
}
|
||||
|
||||
// 合并两个Map.
|
||||
func (this *StringInterfaceMap) Merge(m *StringInterfaceMap) {
|
||||
this.mu.Lock()
|
||||
defer this.mu.Unlock()
|
||||
if m != this {
|
||||
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 {
|
||||
this.m[k] = v
|
||||
gm.m[k] = v
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
// Copyright 2017 gf Author(https://gitee.com/johng/gf). All Rights Reserved.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the MIT License.
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// If a copy of the MIT was not distributed with gm file,
|
||||
// You can obtain one at https://gitee.com/johng/gf.
|
||||
//
|
||||
|
||||
@ -24,10 +24,10 @@ func NewStringStringMap(unsafe...bool) *StringStringMap {
|
||||
}
|
||||
|
||||
// 给定回调函数对原始内容进行遍历,回调函数返回true表示继续遍历,否则停止遍历
|
||||
func (this *StringStringMap) Iterator(f func (k string, v string) bool) {
|
||||
this.mu.RLock()
|
||||
defer this.mu.RUnlock()
|
||||
for k, v := range this.m {
|
||||
func (gm *StringStringMap) Iterator(f func (k string, v string) bool) {
|
||||
gm.mu.RLock()
|
||||
defer gm.mu.RUnlock()
|
||||
for k, v := range gm.m {
|
||||
if !f(k, v) {
|
||||
break
|
||||
}
|
||||
@ -35,91 +35,91 @@ func (this *StringStringMap) Iterator(f func (k string, v string) bool) {
|
||||
}
|
||||
|
||||
// 哈希表克隆
|
||||
func (this *StringStringMap) Clone() map[string]string {
|
||||
func (gm *StringStringMap) Clone() map[string]string {
|
||||
m := make(map[string]string)
|
||||
this.mu.RLock()
|
||||
for k, v := range this.m {
|
||||
gm.mu.RLock()
|
||||
for k, v := range gm.m {
|
||||
m[k] = v
|
||||
}
|
||||
this.mu.RUnlock()
|
||||
gm.mu.RUnlock()
|
||||
return m
|
||||
}
|
||||
|
||||
// 设置键值对
|
||||
func (this *StringStringMap) Set(key string, val string) {
|
||||
this.mu.Lock()
|
||||
this.m[key] = val
|
||||
this.mu.Unlock()
|
||||
func (gm *StringStringMap) Set(key string, val string) {
|
||||
gm.mu.Lock()
|
||||
gm.m[key] = val
|
||||
gm.mu.Unlock()
|
||||
}
|
||||
|
||||
// 批量设置键值对
|
||||
func (this *StringStringMap) BatchSet(m map[string]string) {
|
||||
this.mu.Lock()
|
||||
func (gm *StringStringMap) BatchSet(m map[string]string) {
|
||||
gm.mu.Lock()
|
||||
for k, v := range m {
|
||||
this.m[k] = v
|
||||
gm.m[k] = v
|
||||
}
|
||||
this.mu.Unlock()
|
||||
gm.mu.Unlock()
|
||||
}
|
||||
|
||||
// 获取键值
|
||||
func (this *StringStringMap) Get(key string) string {
|
||||
this.mu.RLock()
|
||||
val, _ := this.m[key]
|
||||
this.mu.RUnlock()
|
||||
func (gm *StringStringMap) Get(key string) string {
|
||||
gm.mu.RLock()
|
||||
val, _ := gm.m[key]
|
||||
gm.mu.RUnlock()
|
||||
return val
|
||||
}
|
||||
|
||||
// 设置kv缓存键值对,内部会对键名的存在性使用写锁进行二次检索确认,如果存在则不再写入;返回键名对应的键值。
|
||||
// 在高并发下有用,防止数据写入的并发逻辑错误。
|
||||
func (this *StringStringMap) doSetWithLockCheck(key string, value string) string {
|
||||
this.mu.Lock()
|
||||
if v, ok := this.m[key]; ok {
|
||||
this.mu.Unlock()
|
||||
func (gm *StringStringMap) doSetWithLockCheck(key string, value string) string {
|
||||
gm.mu.Lock()
|
||||
if v, ok := gm.m[key]; ok {
|
||||
gm.mu.Unlock()
|
||||
return v
|
||||
}
|
||||
this.m[key] = value
|
||||
this.mu.Unlock()
|
||||
gm.m[key] = value
|
||||
gm.mu.Unlock()
|
||||
return value
|
||||
}
|
||||
|
||||
// 当键名存在时返回其键值,否则写入指定的键值
|
||||
func (this *StringStringMap) GetOrSet(key string, value string) string {
|
||||
this.mu.RLock()
|
||||
v, ok := this.m[key]
|
||||
this.mu.RUnlock()
|
||||
func (gm *StringStringMap) GetOrSet(key string, value string) string {
|
||||
gm.mu.RLock()
|
||||
v, ok := gm.m[key]
|
||||
gm.mu.RUnlock()
|
||||
if !ok {
|
||||
return this.doSetWithLockCheck(key, value)
|
||||
return gm.doSetWithLockCheck(key, value)
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
// 当键名存在时返回其键值,否则写入指定的键值,键值由指定的函数生成
|
||||
func (this *StringStringMap) GetOrSetFunc(key string, f func() string) string {
|
||||
this.mu.RLock()
|
||||
v, ok := this.m[key]
|
||||
this.mu.RUnlock()
|
||||
func (gm *StringStringMap) GetOrSetFunc(key string, f func() string) string {
|
||||
gm.mu.RLock()
|
||||
v, ok := gm.m[key]
|
||||
gm.mu.RUnlock()
|
||||
if !ok {
|
||||
return this.doSetWithLockCheck(key, f())
|
||||
return gm.doSetWithLockCheck(key, f())
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
// 与GetOrSetFunc不同的是,f是在写锁机制内执行
|
||||
func (this *StringStringMap) GetOrSetFuncLock(key string, f func() string) string {
|
||||
this.mu.RLock()
|
||||
val, ok := this.m[key]
|
||||
this.mu.RUnlock()
|
||||
func (gm *StringStringMap) GetOrSetFuncLock(key string, f func() string) string {
|
||||
gm.mu.RLock()
|
||||
val, ok := gm.m[key]
|
||||
gm.mu.RUnlock()
|
||||
if !ok {
|
||||
this.mu.Lock()
|
||||
defer this.mu.Unlock()
|
||||
if v, ok := this.m[key]; ok {
|
||||
this.mu.Unlock()
|
||||
gm.mu.Lock()
|
||||
defer gm.mu.Unlock()
|
||||
if v, ok := gm.m[key]; ok {
|
||||
gm.mu.Unlock()
|
||||
return v
|
||||
}
|
||||
val = f()
|
||||
this.m[key] = val
|
||||
gm.m[key] = val
|
||||
return val
|
||||
} else {
|
||||
return val
|
||||
@ -127,121 +127,121 @@ func (this *StringStringMap) GetOrSetFuncLock(key string, f func() string) strin
|
||||
}
|
||||
|
||||
// 当键名不存在时写入,并返回true;否则返回false。
|
||||
func (this *StringStringMap) SetIfNotExist(key string, value string) bool {
|
||||
if !this.Contains(key) {
|
||||
this.doSetWithLockCheck(key, value)
|
||||
func (gm *StringStringMap) SetIfNotExist(key string, value string) bool {
|
||||
if !gm.Contains(key) {
|
||||
gm.doSetWithLockCheck(key, value)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// 批量删除键值对
|
||||
func (this *StringStringMap) BatchRemove(keys []string) {
|
||||
this.mu.Lock()
|
||||
func (gm *StringStringMap) BatchRemove(keys []string) {
|
||||
gm.mu.Lock()
|
||||
for _, key := range keys {
|
||||
delete(this.m, key)
|
||||
delete(gm.m, key)
|
||||
}
|
||||
this.mu.Unlock()
|
||||
gm.mu.Unlock()
|
||||
}
|
||||
|
||||
// 返回对应的键值,并删除该键值
|
||||
func (this *StringStringMap) Remove(key string) string {
|
||||
this.mu.Lock()
|
||||
val, exists := this.m[key]
|
||||
func (gm *StringStringMap) Remove(key string) string {
|
||||
gm.mu.Lock()
|
||||
val, exists := gm.m[key]
|
||||
if exists {
|
||||
delete(this.m, key)
|
||||
delete(gm.m, key)
|
||||
}
|
||||
this.mu.Unlock()
|
||||
gm.mu.Unlock()
|
||||
return val
|
||||
}
|
||||
|
||||
// 返回键列表
|
||||
func (this *StringStringMap) Keys() []string {
|
||||
this.mu.RLock()
|
||||
func (gm *StringStringMap) Keys() []string {
|
||||
gm.mu.RLock()
|
||||
keys := make([]string, 0)
|
||||
for key, _ := range this.m {
|
||||
for key, _ := range gm.m {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
this.mu.RUnlock()
|
||||
gm.mu.RUnlock()
|
||||
return keys
|
||||
}
|
||||
|
||||
// 返回值列表(注意是随机排序)
|
||||
func (this *StringStringMap) Values() []string {
|
||||
this.mu.RLock()
|
||||
func (gm *StringStringMap) Values() []string {
|
||||
gm.mu.RLock()
|
||||
vals := make([]string, 0)
|
||||
for _, val := range this.m {
|
||||
for _, val := range gm.m {
|
||||
vals = append(vals, val)
|
||||
}
|
||||
this.mu.RUnlock()
|
||||
gm.mu.RUnlock()
|
||||
return vals
|
||||
}
|
||||
|
||||
// 是否存在某个键
|
||||
func (this *StringStringMap) Contains(key string) bool {
|
||||
this.mu.RLock()
|
||||
_, exists := this.m[key]
|
||||
this.mu.RUnlock()
|
||||
func (gm *StringStringMap) Contains(key string) bool {
|
||||
gm.mu.RLock()
|
||||
_, exists := gm.m[key]
|
||||
gm.mu.RUnlock()
|
||||
return exists
|
||||
}
|
||||
|
||||
// 哈希表大小
|
||||
func (this *StringStringMap) Size() int {
|
||||
this.mu.RLock()
|
||||
length := len(this.m)
|
||||
this.mu.RUnlock()
|
||||
func (gm *StringStringMap) Size() int {
|
||||
gm.mu.RLock()
|
||||
length := len(gm.m)
|
||||
gm.mu.RUnlock()
|
||||
return length
|
||||
}
|
||||
|
||||
// 哈希表是否为空
|
||||
func (this *StringStringMap) IsEmpty() bool {
|
||||
this.mu.RLock()
|
||||
empty := len(this.m) == 0
|
||||
this.mu.RUnlock()
|
||||
func (gm *StringStringMap) IsEmpty() bool {
|
||||
gm.mu.RLock()
|
||||
empty := len(gm.m) == 0
|
||||
gm.mu.RUnlock()
|
||||
return empty
|
||||
}
|
||||
|
||||
// 清空哈希表
|
||||
func (this *StringStringMap) Clear() {
|
||||
this.mu.Lock()
|
||||
this.m = make(map[string]string)
|
||||
this.mu.Unlock()
|
||||
func (gm *StringStringMap) Clear() {
|
||||
gm.mu.Lock()
|
||||
gm.m = make(map[string]string)
|
||||
gm.mu.Unlock()
|
||||
}
|
||||
|
||||
// 并发安全写锁操作,使用自定义方法执行加锁修改操作
|
||||
func (this *StringStringMap) LockFunc(f func(m map[string]string)) {
|
||||
this.mu.Lock(true)
|
||||
defer this.mu.Unlock(true)
|
||||
f(this.m)
|
||||
func (gm *StringStringMap) LockFunc(f func(m map[string]string)) {
|
||||
gm.mu.Lock(true)
|
||||
defer gm.mu.Unlock(true)
|
||||
f(gm.m)
|
||||
}
|
||||
|
||||
// 并发安全读锁操作,使用自定义方法执行加锁读取操作
|
||||
func (this *StringStringMap) RLockFunc(f func(m map[string]string)) {
|
||||
this.mu.RLock(true)
|
||||
defer this.mu.RUnlock(true)
|
||||
f(this.m)
|
||||
func (gm *StringStringMap) RLockFunc(f func(m map[string]string)) {
|
||||
gm.mu.RLock(true)
|
||||
defer gm.mu.RUnlock(true)
|
||||
f(gm.m)
|
||||
}
|
||||
|
||||
// 交换Map中的键和值.
|
||||
func (this *StringStringMap) Flip() {
|
||||
this.mu.Lock()
|
||||
defer this.mu.Unlock()
|
||||
n := make(map[string]string, len(this.m))
|
||||
for k, v := range this.m {
|
||||
func (gm *StringStringMap) Flip() {
|
||||
gm.mu.Lock()
|
||||
defer gm.mu.Unlock()
|
||||
n := make(map[string]string, len(gm.m))
|
||||
for k, v := range gm.m {
|
||||
n[v] = k
|
||||
}
|
||||
this.m = n
|
||||
gm.m = n
|
||||
}
|
||||
|
||||
// 合并两个Map.
|
||||
func (this *StringStringMap) Merge(m *StringStringMap) {
|
||||
this.mu.Lock()
|
||||
defer this.mu.Unlock()
|
||||
if m != this {
|
||||
func (gm *StringStringMap) Merge(m *StringStringMap) {
|
||||
gm.mu.Lock()
|
||||
defer gm.mu.Unlock()
|
||||
if m != gm {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
}
|
||||
for k, v := range m.m {
|
||||
this.m[k] = v
|
||||
gm.m[k] = v
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Copyright 2017 gf Author(https://gitee.com/johng/gf). All Rights Reserved.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the MIT License.
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// If a copy of the MIT was not distributed with gm file,
|
||||
// You can obtain one at https://gitee.com/johng/gf.
|
||||
|
||||
// go test *.go -bench=".*" -benchmem
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Copyright 2017 gf Author(https://gitee.com/johng/gf). All Rights Reserved.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the MIT License.
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// If a copy of the MIT was not distributed with gm file,
|
||||
// You can obtain one at https://gitee.com/johng/gf.
|
||||
|
||||
// go test *.go -bench=".*" -benchmem
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Copyright 2017 gf Author(https://gitee.com/johng/gf). All Rights Reserved.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the MIT License.
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// If a copy of the MIT was not distributed with gm file,
|
||||
// You can obtain one at https://gitee.com/johng/gf.
|
||||
|
||||
// go test *.go -bench=".*" -benchmem
|
||||
|
@ -110,6 +110,7 @@ func (set *Set) String() string {
|
||||
return fmt.Sprint(set.Slice())
|
||||
}
|
||||
|
||||
// 写锁操作
|
||||
func (set *Set) LockFunc(f func(m map[interface{}]struct{})) *Set {
|
||||
set.mu.Lock(true)
|
||||
defer set.mu.Unlock(true)
|
||||
@ -117,6 +118,7 @@ func (set *Set) LockFunc(f func(m map[interface{}]struct{})) *Set {
|
||||
return set
|
||||
}
|
||||
|
||||
// 读锁操作
|
||||
func (set *Set) RLockFunc(f func(m map[interface{}]struct{})) *Set {
|
||||
set.mu.RLock(true)
|
||||
defer set.mu.RUnlock(true)
|
||||
@ -161,57 +163,67 @@ func (set *Set) IsSubsetOf(other *Set) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// 并集, 返回新的集合:属于set或属于other的元素为元素的集合.
|
||||
func (set *Set) Union(other *Set) (newSet *Set) {
|
||||
// 并集, 返回新的集合:属于set或属于others的元素为元素的集合.
|
||||
func (set *Set) Union(others ... *Set) (newSet *Set) {
|
||||
newSet = NewSet(true)
|
||||
set.mu.RLock()
|
||||
defer set.mu.RUnlock()
|
||||
if set != other {
|
||||
other.mu.RLock()
|
||||
defer other.mu.RUnlock()
|
||||
}
|
||||
for k, v := range set.m {
|
||||
newSet.m[k] = v
|
||||
}
|
||||
if set != other {
|
||||
for k, v := range other.m {
|
||||
for _, other := range others {
|
||||
if set != other {
|
||||
other.mu.RLock()
|
||||
}
|
||||
for k, v := range set.m {
|
||||
newSet.m[k] = v
|
||||
}
|
||||
if set != other {
|
||||
for k, v := range other.m {
|
||||
newSet.m[k] = v
|
||||
}
|
||||
}
|
||||
if set != other {
|
||||
other.mu.RUnlock()
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// 差集, 返回新的集合: 属于set且不属于others的元素为元素的集合.
|
||||
func (set *Set) Diff(others...*Set) (newSet *Set) {
|
||||
newSet = NewSet(true)
|
||||
set.mu.RLock()
|
||||
defer set.mu.RUnlock()
|
||||
for _, other := range others {
|
||||
if set == other {
|
||||
continue
|
||||
}
|
||||
other.mu.RLock()
|
||||
for k, v := range set.m {
|
||||
if _, ok := other.m[k]; !ok {
|
||||
newSet.m[k] = v
|
||||
}
|
||||
}
|
||||
other.mu.RUnlock()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 差集, 返回新的集合: 属于set且不属于other的元素为元素的集合.
|
||||
func (set *Set) Diff(other *Set) (newSet *Set) {
|
||||
// 交集, 返回新的集合: 属于set且属于others的元素为元素的集合.
|
||||
func (set *Set) Intersect(others...*Set) (newSet *Set) {
|
||||
newSet = NewSet(true)
|
||||
if set == other {
|
||||
return newSet
|
||||
}
|
||||
set.mu.RLock()
|
||||
defer set.mu.RUnlock()
|
||||
other.mu.RLock()
|
||||
defer other.mu.RUnlock()
|
||||
|
||||
for k, v := range set.m {
|
||||
if _, ok := other.m[k]; !ok {
|
||||
newSet.m[k] = v
|
||||
for _, other := range others {
|
||||
if set != other {
|
||||
other.mu.RLock()
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 交集, 返回新的集合: 属于set且属于other的元素为元素的集合.
|
||||
func (set *Set) Inter(other *Set) (newSet *Set) {
|
||||
newSet = NewSet(true)
|
||||
set.mu.RLock()
|
||||
defer set.mu.RUnlock()
|
||||
if set != other {
|
||||
other.mu.RLock()
|
||||
defer other.mu.RUnlock()
|
||||
}
|
||||
for k, v := range set.m {
|
||||
if _, ok := other.m[k]; ok {
|
||||
newSet.m[k] = v
|
||||
for k, v := range set.m {
|
||||
if _, ok := other.m[k]; ok {
|
||||
newSet.m[k] = v
|
||||
}
|
||||
}
|
||||
if set != other {
|
||||
other.mu.RUnlock()
|
||||
}
|
||||
}
|
||||
return
|
||||
@ -223,8 +235,10 @@ func (set *Set) Complement(full *Set) (newSet *Set) {
|
||||
newSet = NewSet(true)
|
||||
set.mu.RLock()
|
||||
defer set.mu.RUnlock()
|
||||
full.mu.RLock()
|
||||
defer full.mu.RUnlock()
|
||||
if set != full {
|
||||
full.mu.RLock()
|
||||
defer full.mu.RUnlock()
|
||||
}
|
||||
for k, v := range full.m {
|
||||
if _, ok := set.m[k]; !ok {
|
||||
newSet.m[k] = v
|
||||
|
@ -156,57 +156,67 @@ func (set *IntSet) IsSubsetOf(other *IntSet) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// 并集, 返回新的集合:属于set或属于other的元素为元素的集合.
|
||||
func (set *IntSet) Union(other *IntSet) (newSet *IntSet) {
|
||||
// 并集, 返回新的集合:属于set或属于others的元素为元素的集合.
|
||||
func (set *IntSet) Union(others ... *IntSet) (newSet *IntSet) {
|
||||
newSet = NewIntSet(true)
|
||||
set.mu.RLock()
|
||||
defer set.mu.RUnlock()
|
||||
if set != other {
|
||||
other.mu.RLock()
|
||||
defer other.mu.RUnlock()
|
||||
}
|
||||
for k, v := range set.m {
|
||||
newSet.m[k] = v
|
||||
}
|
||||
if set != other {
|
||||
for k, v := range other.m {
|
||||
for _, other := range others {
|
||||
if set != other {
|
||||
other.mu.RLock()
|
||||
}
|
||||
for k, v := range set.m {
|
||||
newSet.m[k] = v
|
||||
}
|
||||
if set != other {
|
||||
for k, v := range other.m {
|
||||
newSet.m[k] = v
|
||||
}
|
||||
}
|
||||
if set != other {
|
||||
other.mu.RUnlock()
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// 差集, 返回新的集合: 属于set且不属于others的元素为元素的集合.
|
||||
func (set *IntSet) Diff(others...*IntSet) (newSet *IntSet) {
|
||||
newSet = NewIntSet(true)
|
||||
set.mu.RLock()
|
||||
defer set.mu.RUnlock()
|
||||
for _, other := range others {
|
||||
if set == other {
|
||||
continue
|
||||
}
|
||||
other.mu.RLock()
|
||||
for k, v := range set.m {
|
||||
if _, ok := other.m[k]; !ok {
|
||||
newSet.m[k] = v
|
||||
}
|
||||
}
|
||||
other.mu.RUnlock()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 差集, 返回新的集合: 属于set且不属于other的元素为元素的集合.
|
||||
func (set *IntSet) Diff(other *IntSet) (newSet *IntSet) {
|
||||
// 交集, 返回新的集合: 属于set且属于others的元素为元素的集合.
|
||||
func (set *IntSet) Intersect(others...*IntSet) (newSet *IntSet) {
|
||||
newSet = NewIntSet(true)
|
||||
if set == other {
|
||||
return newSet
|
||||
}
|
||||
set.mu.RLock()
|
||||
defer set.mu.RUnlock()
|
||||
other.mu.RLock()
|
||||
defer other.mu.RUnlock()
|
||||
|
||||
for k, v := range set.m {
|
||||
if _, ok := other.m[k]; !ok {
|
||||
newSet.m[k] = v
|
||||
for _, other := range others {
|
||||
if set != other {
|
||||
other.mu.RLock()
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 交集, 返回新的集合: 属于set且属于other的元素为元素的集合.
|
||||
func (set *IntSet) Inter(other *IntSet) (newSet *IntSet) {
|
||||
newSet = NewIntSet(true)
|
||||
set.mu.RLock()
|
||||
defer set.mu.RUnlock()
|
||||
if set != other {
|
||||
other.mu.RLock()
|
||||
defer other.mu.RUnlock()
|
||||
}
|
||||
for k, v := range set.m {
|
||||
if _, ok := other.m[k]; ok {
|
||||
newSet.m[k] = v
|
||||
for k, v := range set.m {
|
||||
if _, ok := other.m[k]; ok {
|
||||
newSet.m[k] = v
|
||||
}
|
||||
}
|
||||
if set != other {
|
||||
other.mu.RUnlock()
|
||||
}
|
||||
}
|
||||
return
|
||||
@ -218,12 +228,14 @@ func (set *IntSet) Complement(full *IntSet) (newSet *IntSet) {
|
||||
newSet = NewIntSet(true)
|
||||
set.mu.RLock()
|
||||
defer set.mu.RUnlock()
|
||||
full.mu.RLock()
|
||||
defer full.mu.RUnlock()
|
||||
if set != full {
|
||||
full.mu.RLock()
|
||||
defer full.mu.RUnlock()
|
||||
}
|
||||
for k, v := range full.m {
|
||||
if _, ok := set.m[k]; !ok {
|
||||
newSet.m[k] = v
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -156,74 +156,86 @@ func (set *StringSet) IsSubsetOf(other *StringSet) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// 并集, 返回新的集合:属于set或属于other的元素为元素的集合.
|
||||
func (set *StringSet) Union(other *StringSet) (newSet *StringSet) {
|
||||
newSet = NewStringSet(true)
|
||||
set.mu.RLock()
|
||||
defer set.mu.RUnlock()
|
||||
if set != other {
|
||||
other.mu.RLock()
|
||||
defer other.mu.RUnlock()
|
||||
}
|
||||
for k, v := range set.m {
|
||||
newSet.m[k] = v
|
||||
}
|
||||
if set != other {
|
||||
for k, v := range other.m {
|
||||
newSet.m[k] = v
|
||||
}
|
||||
}
|
||||
return
|
||||
// 并集, 返回新的集合:属于set或属于others的元素为元素的集合.
|
||||
func (set *StringSet) Union(others ... *StringSet) (newSet *StringSet) {
|
||||
newSet = NewStringSet(true)
|
||||
set.mu.RLock()
|
||||
defer set.mu.RUnlock()
|
||||
for _, other := range others {
|
||||
if set != other {
|
||||
other.mu.RLock()
|
||||
}
|
||||
for k, v := range set.m {
|
||||
newSet.m[k] = v
|
||||
}
|
||||
if set != other {
|
||||
for k, v := range other.m {
|
||||
newSet.m[k] = v
|
||||
}
|
||||
}
|
||||
if set != other {
|
||||
other.mu.RUnlock()
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// 差集, 返回新的集合: 属于set且不属于other的元素为元素的集合.
|
||||
func (set *StringSet) Diff(other *StringSet) (newSet *StringSet) {
|
||||
newSet = NewStringSet(true)
|
||||
if set == other {
|
||||
return newSet
|
||||
}
|
||||
set.mu.RLock()
|
||||
defer set.mu.RUnlock()
|
||||
other.mu.RLock()
|
||||
defer other.mu.RUnlock()
|
||||
|
||||
for k, v := range set.m {
|
||||
if _, ok := other.m[k]; !ok {
|
||||
newSet.m[k] = v
|
||||
}
|
||||
}
|
||||
return
|
||||
// 差集, 返回新的集合: 属于set且不属于others的元素为元素的集合.
|
||||
func (set *StringSet) Diff(others...*StringSet) (newSet *StringSet) {
|
||||
newSet = NewStringSet(true)
|
||||
set.mu.RLock()
|
||||
defer set.mu.RUnlock()
|
||||
for _, other := range others {
|
||||
if set == other {
|
||||
continue
|
||||
}
|
||||
other.mu.RLock()
|
||||
for k, v := range set.m {
|
||||
if _, ok := other.m[k]; !ok {
|
||||
newSet.m[k] = v
|
||||
}
|
||||
}
|
||||
other.mu.RUnlock()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 交集, 返回新的集合: 属于set且属于other的元素为元素的集合.
|
||||
func (set *StringSet) Inter(other *StringSet) (newSet *StringSet) {
|
||||
newSet = NewStringSet(true)
|
||||
set.mu.RLock()
|
||||
defer set.mu.RUnlock()
|
||||
if set != other {
|
||||
other.mu.RLock()
|
||||
defer other.mu.RUnlock()
|
||||
}
|
||||
for k, v := range set.m {
|
||||
if _, ok := other.m[k]; ok {
|
||||
newSet.m[k] = v
|
||||
}
|
||||
}
|
||||
return
|
||||
// 交集, 返回新的集合: 属于set且属于others的元素为元素的集合.
|
||||
func (set *StringSet) Intersect(others...*StringSet) (newSet *StringSet) {
|
||||
newSet = NewStringSet(true)
|
||||
set.mu.RLock()
|
||||
defer set.mu.RUnlock()
|
||||
for _, other := range others {
|
||||
if set != other {
|
||||
other.mu.RLock()
|
||||
}
|
||||
for k, v := range set.m {
|
||||
if _, ok := other.m[k]; ok {
|
||||
newSet.m[k] = v
|
||||
}
|
||||
}
|
||||
if set != other {
|
||||
other.mu.RUnlock()
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 补集, 返回新的集合: (前提: set应当为full的子集)属于全集full不属于集合set的元素组成的集合.
|
||||
// 如果给定的full集合不是set的全集时,返回full与set的差集.
|
||||
func (set *StringSet) Complement(full *StringSet) (newSet *StringSet) {
|
||||
newSet = NewStringSet(true)
|
||||
set.mu.RLock()
|
||||
defer set.mu.RUnlock()
|
||||
full.mu.RLock()
|
||||
defer full.mu.RUnlock()
|
||||
for k, v := range full.m {
|
||||
if _, ok := set.m[k]; !ok {
|
||||
newSet.m[k] = v
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
newSet = NewStringSet(true)
|
||||
set.mu.RLock()
|
||||
defer set.mu.RUnlock()
|
||||
if set != full {
|
||||
full.mu.RLock()
|
||||
defer full.mu.RUnlock()
|
||||
}
|
||||
for k, v := range full.m {
|
||||
if _, ok := set.m[k]; !ok {
|
||||
newSet.m[k] = v
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -131,13 +131,13 @@ func TestIntSet_Diff(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestIntSet_Inter(t *testing.T) {
|
||||
func TestIntSet_Intersect(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
s1 := gset.NewIntSet()
|
||||
s2 := gset.NewIntSet()
|
||||
s1.Add(1).Add(2).Add(3)
|
||||
s2.Add(3).Add(4).Add(5)
|
||||
s3 := s1.Inter(s2)
|
||||
s3 := s1.Intersect(s2)
|
||||
gtest.Assert(s3.Contains(1), false)
|
||||
gtest.Assert(s3.Contains(2), false)
|
||||
gtest.Assert(s3.Contains(3), true)
|
||||
|
@ -131,13 +131,13 @@ func TestStringSet_Diff(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestStringSet_Inter(t *testing.T) {
|
||||
func TestStringSet_Intersect(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
s1 := gset.NewStringSet()
|
||||
s2 := gset.NewStringSet()
|
||||
s1.Add("1").Add("2").Add("3")
|
||||
s2.Add("3").Add("4").Add("5")
|
||||
s3 := s1.Inter(s2)
|
||||
s3 := s1.Intersect(s2)
|
||||
gtest.Assert(s3.Contains("1"), false)
|
||||
gtest.Assert(s3.Contains("2"), false)
|
||||
gtest.Assert(s3.Contains("3"), true)
|
||||
|
@ -131,13 +131,13 @@ func TestSet_Diff(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestSet_Inter(t *testing.T) {
|
||||
func TestSet_Intersect(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
s1 := gset.NewSet()
|
||||
s2 := gset.NewSet()
|
||||
s1.Add(1).Add(2).Add(3)
|
||||
s2.Add(3).Add(4).Add(5)
|
||||
s3 := s1.Inter(s2)
|
||||
s3 := s1.Intersect(s2)
|
||||
gtest.Assert(s3.Contains(1), false)
|
||||
gtest.Assert(s3.Contains(2), false)
|
||||
gtest.Assert(s3.Contains(3), true)
|
||||
|
@ -14,7 +14,7 @@ func funcTest() string {
|
||||
|
||||
func main() {
|
||||
view := g.View()
|
||||
b, err := view.Parse("gview.tpl", nil, gview.FuncMap{
|
||||
b, err := view.Parse("index.html", nil, gview.FuncMap{
|
||||
"test" : funcTest,
|
||||
})
|
||||
fmt.Println(err)
|
||||
|
Loading…
Reference in New Issue
Block a user