改进gmap,并完善基准测试

This commit is contained in:
john
2018-09-20 09:28:45 +08:00
parent 76e06bedcd
commit f48c05522b
19 changed files with 565 additions and 328 deletions

View File

@ -23,7 +23,6 @@ var sbm = NewStringBoolMap()
var sim = NewStringIntMap()
var sifm = NewStringInterfaceMap()
var ssm = NewStringStringMap()
var uifm = NewUintInterfaceMap()
// 写入性能测试
@ -81,11 +80,6 @@ func Benchmark_StringStringMap_Set(b *testing.B) {
}
}
func Benchmark_UintInterfaceMap_Set(b *testing.B) {
for i := 0; i < b.N; i++ {
uifm.Set(uint(i), i)
}
}
// 读取性能测试
@ -143,9 +137,3 @@ func Benchmark_StringStringMap_Get(b *testing.B) {
}
}
func Benchmark_UintInterfaceMap_Get(b *testing.B) {
for i := 0; i < b.N; i++ {
uifm.Get(uint(i))
}
}

View File

@ -4,7 +4,7 @@
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://gitee.com/johng/gf.
// go test *.go -bench=".*"
// go test *.go -bench=".*" -benchmem
package gmap_test

View File

@ -0,0 +1,139 @@
// 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.
// go test *.go -bench=".*" -benchmem
package gmap
import (
"testing"
"strconv"
)
var ibmUnsafe = NewIntBoolMap(false)
var iimUnsafe = NewIntIntMap(false)
var iifmUnsafe = NewIntInterfaceMap(false)
var ismUnsafe = NewIntStringMap(false)
var ififmUnsafe = NewInterfaceInterfaceMap(false)
var sbmUnsafe = NewStringBoolMap(false)
var simUnsafe = NewStringIntMap(false)
var sifmUnsafe = NewStringInterfaceMap(false)
var ssmUnsafe = NewStringStringMap(false)
// 写入性能测试
func Benchmark_Unsafe_IntBoolMap_Set(b *testing.B) {
for i := 0; i < b.N; i++ {
ibmUnsafe.Set(i, true)
}
}
func Benchmark_Unsafe_IntIntMap_Set(b *testing.B) {
for i := 0; i < b.N; i++ {
iimUnsafe.Set(i, i)
}
}
func Benchmark_Unsafe_IntInterfaceMap_Set(b *testing.B) {
for i := 0; i < b.N; i++ {
iifmUnsafe.Set(i, i)
}
}
func Benchmark_Unsafe_IntStringMap_Set(b *testing.B) {
for i := 0; i < b.N; i++ {
ismUnsafe.Set(i, strconv.Itoa(i))
}
}
func Benchmark_Unsafe_InterfaceInterfaceMap_Set(b *testing.B) {
for i := 0; i < b.N; i++ {
ififmUnsafe.Set(i, i)
}
}
func Benchmark_Unsafe_StringBoolMap_Set(b *testing.B) {
for i := 0; i < b.N; i++ {
sbmUnsafe.Set(strconv.Itoa(i), true)
}
}
func Benchmark_Unsafe_StringIntMap_Set(b *testing.B) {
for i := 0; i < b.N; i++ {
simUnsafe.Set(strconv.Itoa(i), i)
}
}
func Benchmark_Unsafe_StringInterfaceMap_Set(b *testing.B) {
for i := 0; i < b.N; i++ {
sifmUnsafe.Set(strconv.Itoa(i), i)
}
}
func Benchmark_Unsafe_StringStringMap_Set(b *testing.B) {
for i := 0; i < b.N; i++ {
ssmUnsafe.Set(strconv.Itoa(i), strconv.Itoa(i))
}
}
// 读取性能测试
func Benchmark_Unsafe_IntBoolMap_Get(b *testing.B) {
for i := 0; i < b.N; i++ {
ibmUnsafe.Get(i)
}
}
func Benchmark_Unsafe_IntIntMap_Get(b *testing.B) {
for i := 0; i < b.N; i++ {
iimUnsafe.Get(i)
}
}
func Benchmark_Unsafe_IntInterfaceMap_Get(b *testing.B) {
for i := 0; i < b.N; i++ {
iifmUnsafe.Get(i)
}
}
func Benchmark_Unsafe_IntStringMap_Get(b *testing.B) {
for i := 0; i < b.N; i++ {
ismUnsafe.Get(i)
}
}
func Benchmark_Unsafe_InterfaceInterfaceMap_Get(b *testing.B) {
for i := 0; i < b.N; i++ {
ififmUnsafe.Get(i)
}
}
func Benchmark_Unsafe_StringBoolMap_Get(b *testing.B) {
for i := 0; i < b.N; i++ {
sbmUnsafe.Get(strconv.Itoa(i))
}
}
func Benchmark_Unsafe_StringIntMap_Get(b *testing.B) {
for i := 0; i < b.N; i++ {
simUnsafe.Get(strconv.Itoa(i))
}
}
func Benchmark_Unsafe_StringInterfaceMap_Get(b *testing.B) {
for i := 0; i < b.N; i++ {
sifmUnsafe.Get(strconv.Itoa(i))
}
}
func Benchmark_Unsafe_StringStringMap_Get(b *testing.B) {
for i := 0; i < b.N; i++ {
ssmUnsafe.Get(strconv.Itoa(i))
}
}

View File

@ -69,23 +69,70 @@ func (this *IntBoolMap) Get(key int) bool {
return val
}
// 获取键值,如果键值不存在则写入默认值
func (this *IntBoolMap) GetWithDefault(key int, value bool) bool {
// 设置kv缓存键值对内部会对键名的存在性使用写锁进行二次检索确认如果存在则不再写入返回键名对应的键值。
// 在高并发下有用,防止数据写入的并发逻辑错误。
func (this *IntBoolMap) doSetWithLockCheck(key int, value bool) bool {
this.mu.Lock()
val, ok := this.m[key]
if !ok {
this.m[key] = value
val = value
if v, ok := this.m[key]; ok {
this.mu.Unlock()
return v
}
this.m[key] = value
this.mu.Unlock()
return val
return value
}
// 删除键值对
func (this *IntBoolMap) Remove(key int) {
this.mu.Lock()
delete(this.m, key)
this.mu.Unlock()
// 当键名存在时返回其键值,否则写入指定的键值
func (this *IntBoolMap) GetOrSet(key int, value bool) bool {
this.mu.RLock()
v, ok := this.m[key]
this.mu.RUnlock()
if !ok {
return this.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()
if !ok {
return this.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()
if !ok {
this.mu.Lock()
defer this.mu.Unlock()
if v, ok := this.m[key]; ok {
this.mu.Unlock()
return v
}
val = f()
this.m[key] = val
return val
} else {
return val
}
}
// 当键名不存在时写入并返回true否则返回false。
func (this *IntBoolMap) SetIfNotExist(key int, value bool) bool {
if !this.Contains(key) {
this.doSetWithLockCheck(key, value)
return true
}
return false
}
// 批量删除键值对
@ -98,7 +145,7 @@ func (this *IntBoolMap) BatchRemove(keys []int) {
}
// 返回对应的键值,并删除该键值
func (this *IntBoolMap) GetAndRemove(key int) (bool) {
func (this *IntBoolMap) Remove(key int) bool {
this.mu.Lock()
val, exists := this.m[key]
if exists {

View File

@ -69,23 +69,70 @@ func (this *IntIntMap) Get(key int) (int) {
return val
}
// 获取键值,如果键值不存在则写入默认值
func (this *IntIntMap) GetWithDefault(key int, value int) int {
// 设置kv缓存键值对内部会对键名的存在性使用写锁进行二次检索确认如果存在则不再写入返回键名对应的键值。
// 在高并发下有用,防止数据写入的并发逻辑错误。
func (this *IntIntMap) doSetWithLockCheck(key int, value int) int {
this.mu.Lock()
val, ok := this.m[key]
if !ok {
this.m[key] = value
val = value
if v, ok := this.m[key]; ok {
this.mu.Unlock()
return v
}
this.m[key] = value
this.mu.Unlock()
return val
return value
}
// 删除键值对
func (this *IntIntMap) Remove(key int) {
this.mu.Lock()
delete(this.m, key)
this.mu.Unlock()
// 当键名存在时返回其键值,否则写入指定的键值
func (this *IntIntMap) GetOrSet(key int, value int) int {
this.mu.RLock()
v, ok := this.m[key]
this.mu.RUnlock()
if !ok {
return this.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()
if !ok {
return this.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()
if !ok {
this.mu.Lock()
defer this.mu.Unlock()
if v, ok := this.m[key]; ok {
this.mu.Unlock()
return v
}
val = f()
this.m[key] = val
return val
} else {
return val
}
}
// 当键名不存在时写入并返回true否则返回false。
func (this *IntIntMap) SetIfNotExist(key int, value int) bool {
if !this.Contains(key) {
this.doSetWithLockCheck(key, value)
return true
}
return false
}
// 批量删除键值对
@ -98,7 +145,7 @@ func (this *IntIntMap) BatchRemove(keys []int) {
}
// 返回对应的键值,并删除该键值
func (this *IntIntMap) GetAndRemove(key int) (int) {
func (this *IntIntMap) Remove(key int) int {
this.mu.Lock()
val, exists := this.m[key]
if exists {

View File

@ -67,23 +67,58 @@ func (this *IntInterfaceMap) Get(key int) (interface{}) {
return val
}
// 获取键值,如果键值不存在则写入默认值
func (this *IntInterfaceMap) GetWithDefault(key int, value interface{}) interface{} {
// 设置kv缓存键值对内部会对键名的存在性使用写锁进行二次检索确认如果存在则不再写入返回键名对应的键值。
// 在高并发下有用,防止数据写入的并发逻辑错误。
func (this *IntInterfaceMap) doSetWithLockCheck(key int, value interface{}) interface{} {
this.mu.Lock()
val, ok := this.m[key]
if !ok {
this.m[key] = value
val = value
defer this.mu.Unlock()
if v, ok := this.m[key]; ok {
return v
}
this.mu.Unlock()
return val
if f, ok := value.(func() interface {}); ok {
value = f()
}
this.m[key] = value
return value
}
// 删除键值对
func (this *IntInterfaceMap) Remove(key int) {
this.mu.Lock()
delete(this.m, key)
this.mu.Unlock()
// 当键名存在时返回其键值,否则写入指定的键值
func (this *IntInterfaceMap) GetOrSet(key int, value interface{}) interface{} {
if v := this.Get(key); v == nil {
return this.doSetWithLockCheck(key, value)
} else {
return v
}
}
// 当键名存在时返回其键值,否则写入指定的键值,键值由指定的函数生成
func (this *IntInterfaceMap) GetOrSetFunc(key int, f func() interface{}) interface{} {
if v := this.Get(key); v == nil {
v = f()
this.doSetWithLockCheck(key, v)
return v
} else {
return v
}
}
// 与GetOrSetFunc不同的是f是在写锁机制内执行
func (this *IntInterfaceMap) GetOrSetFuncLock(key int, f func() interface{}) interface{} {
if v := this.Get(key); v == nil {
this.doSetWithLockCheck(key, f)
return v
} else {
return v
}
}
// 当键名不存在时写入并返回true否则返回false。
func (this *IntInterfaceMap) SetIfNotExist(key int, value interface{}) bool {
if !this.Contains(key) {
this.doSetWithLockCheck(key, value)
return true
}
return false
}
// 批量删除键值对
@ -96,7 +131,7 @@ func (this *IntInterfaceMap) BatchRemove(keys []int) {
}
// 返回对应的键值,并删除该键值
func (this *IntInterfaceMap) GetAndRemove(key int) (interface{}) {
func (this *IntInterfaceMap) Remove(key int) interface{} {
this.mu.Lock()
val, exists := this.m[key]
if exists {

View File

@ -69,23 +69,70 @@ func (this *IntStringMap) Get(key int) string {
return val
}
// 获取键值,如果键值不存在则写入默认值
func (this *IntStringMap) GetWithDefault(key int, value string) string {
// 设置kv缓存键值对内部会对键名的存在性使用写锁进行二次检索确认如果存在则不再写入返回键名对应的键值。
// 在高并发下有用,防止数据写入的并发逻辑错误。
func (this *IntStringMap) doSetWithLockCheck(key int, value string) string {
this.mu.Lock()
val, ok := this.m[key]
if !ok {
this.m[key] = value
val = value
if v, ok := this.m[key]; ok {
this.mu.Unlock()
return v
}
this.m[key] = value
this.mu.Unlock()
return val
return value
}
// 删除键值对
func (this *IntStringMap) Remove(key int) {
this.mu.Lock()
delete(this.m, key)
this.mu.Unlock()
// 当键名存在时返回其键值,否则写入指定的键值
func (this *IntStringMap) GetOrSet(key int, value string) string {
this.mu.RLock()
v, ok := this.m[key]
this.mu.RUnlock()
if !ok {
return this.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()
if !ok {
return this.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()
if !ok {
this.mu.Lock()
defer this.mu.Unlock()
if v, ok := this.m[key]; ok {
this.mu.Unlock()
return v
}
val = f()
this.m[key] = val
return val
} else {
return val
}
}
// 当键名不存在时写入并返回true否则返回false。
func (this *IntStringMap) SetIfNotExist(key int, value string) bool {
if !this.Contains(key) {
this.doSetWithLockCheck(key, value)
return true
}
return false
}
// 批量删除键值对
@ -98,7 +145,7 @@ func (this *IntStringMap) BatchRemove(keys []int) {
}
// 返回对应的键值,并删除该键值
func (this *IntStringMap) GetAndRemove(key int) (string) {
func (this *IntStringMap) Remove(key int) string {
this.mu.Lock()
val, exists := this.m[key]
if exists {

View File

@ -73,15 +73,14 @@ func (this *InterfaceInterfaceMap) Get(key interface{}) interface{} {
// 在高并发下有用,防止数据写入的并发逻辑错误。
func (this *InterfaceInterfaceMap) doSetWithLockCheck(key interface{}, value interface{}) interface{} {
this.mu.Lock()
defer this.mu.Unlock()
if v, ok := this.m[key]; ok {
this.mu.Unlock()
return v
}
if f, ok := value.(func() interface {}); ok {
value = f()
}
this.m[key] = value
this.mu.Unlock()
return value
}
@ -124,13 +123,6 @@ func (this *InterfaceInterfaceMap) SetIfNotExist(key interface{}, value interfac
return false
}
// 删除键值对
func (this *InterfaceInterfaceMap) Remove(key interface{}) {
this.mu.Lock()
delete(this.m, key)
this.mu.Unlock()
}
// 批量删除键值对
func (this *InterfaceInterfaceMap) BatchRemove(keys []interface{}) {
this.mu.Lock()
@ -141,7 +133,7 @@ func (this *InterfaceInterfaceMap) BatchRemove(keys []interface{}) {
}
// 返回对应的键值,并删除该键值
func (this *InterfaceInterfaceMap) GetAndRemove(key interface{}) (interface{}) {
func (this *InterfaceInterfaceMap) Remove(key interface{}) interface{} {
this.mu.Lock()
val, exists := this.m[key]
if exists {

View File

@ -69,23 +69,70 @@ func (this *StringBoolMap) Get(key string) bool {
return val
}
// 获取键值,如果键值不存在则写入默认值
func (this *StringBoolMap) GetWithDefault(key string, value bool) bool {
// 设置kv缓存键值对内部会对键名的存在性使用写锁进行二次检索确认如果存在则不再写入返回键名对应的键值。
// 在高并发下有用,防止数据写入的并发逻辑错误。
func (this *StringBoolMap) doSetWithLockCheck(key string, value bool) bool {
this.mu.Lock()
val, ok := this.m[key]
if !ok {
this.m[key] = value
val = value
if v, ok := this.m[key]; ok {
this.mu.Unlock()
return v
}
this.m[key] = value
this.mu.Unlock()
return val
return value
}
// 删除键值对
func (this *StringBoolMap) Remove(key string) {
this.mu.Lock()
delete(this.m, key)
this.mu.Unlock()
// 当键名存在时返回其键值,否则写入指定的键值
func (this *StringBoolMap) GetOrSet(key string, value bool) bool {
this.mu.RLock()
v, ok := this.m[key]
this.mu.RUnlock()
if !ok {
return this.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()
if !ok {
return this.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()
if !ok {
this.mu.Lock()
defer this.mu.Unlock()
if v, ok := this.m[key]; ok {
this.mu.Unlock()
return v
}
val = f()
this.m[key] = val
return val
} else {
return val
}
}
// 当键名不存在时写入并返回true否则返回false。
func (this *StringBoolMap) SetIfNotExist(key string, value bool) bool {
if !this.Contains(key) {
this.doSetWithLockCheck(key, value)
return true
}
return false
}
// 批量删除键值对
@ -98,7 +145,7 @@ func (this *StringBoolMap) BatchRemove(keys []string) {
}
// 返回对应的键值,并删除该键值
func (this *StringBoolMap) GetAndRemove(key string) (bool) {
func (this *StringBoolMap) Remove(key string) bool {
this.mu.Lock()
val, exists := this.m[key]
if exists {

View File

@ -67,23 +67,70 @@ func (this *StringIntMap) Get(key string) int {
return val
}
// 获取键值,如果键值不存在则写入默认值
func (this *StringIntMap) GetWithDefault(key string, value int) int {
// 设置kv缓存键值对内部会对键名的存在性使用写锁进行二次检索确认如果存在则不再写入返回键名对应的键值。
// 在高并发下有用,防止数据写入的并发逻辑错误。
func (this *StringIntMap) doSetWithLockCheck(key string, value int) int {
this.mu.Lock()
val, ok := this.m[key]
if !ok {
this.m[key] = value
val = value
if v, ok := this.m[key]; ok {
this.mu.Unlock()
return v
}
this.m[key] = value
this.mu.Unlock()
return val
return value
}
// 删除键值对
func (this *StringIntMap) Remove(key string) {
this.mu.Lock()
delete(this.m, key)
this.mu.Unlock()
// 当键名存在时返回其键值,否则写入指定的键值
func (this *StringIntMap) GetOrSet(key string, value int) int {
this.mu.RLock()
v, ok := this.m[key]
this.mu.RUnlock()
if !ok {
return this.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()
if !ok {
return this.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()
if !ok {
this.mu.Lock()
defer this.mu.Unlock()
if v, ok := this.m[key]; ok {
this.mu.Unlock()
return v
}
val = f()
this.m[key] = val
return val
} else {
return val
}
}
// 当键名不存在时写入并返回true否则返回false。
func (this *StringIntMap) SetIfNotExist(key string, value int) bool {
if !this.Contains(key) {
this.doSetWithLockCheck(key, value)
return true
}
return false
}
// 批量删除键值对
@ -96,7 +143,7 @@ func (this *StringIntMap) BatchRemove(keys []string) {
}
// 返回对应的键值,并删除该键值
func (this *StringIntMap) GetAndRemove(key string) (int) {
func (this *StringIntMap) Remove(key string) int {
this.mu.Lock()
val, exists := this.m[key]
if exists {

View File

@ -72,16 +72,15 @@ func (this *StringInterfaceMap) Get(key string) interface{} {
// 设置kv缓存键值对内部会对键名的存在性使用写锁进行二次检索确认如果存在则不再写入返回键名对应的键值。
// 在高并发下有用,防止数据写入的并发逻辑错误。
func (this *StringInterfaceMap) doSetWithLockCheck(key string, value interface{}) interface{} {
this.mu.Lock()
this.mu.Lock()
defer this.mu.Unlock()
if v, ok := this.m[key]; ok {
this.mu.Unlock()
return v
}
if f, ok := value.(func() interface {}); ok {
value = f()
}
this.m[key] = value
this.mu.Unlock()
return value
}
@ -124,13 +123,6 @@ func (this *StringInterfaceMap) SetIfNotExist(key string, value interface{}) boo
return false
}
// 删除键值对
func (this *StringInterfaceMap) Remove(key string) {
this.mu.Lock()
delete(this.m, key)
this.mu.Unlock()
}
// 批量删除键值对
func (this *StringInterfaceMap) BatchRemove(keys []string) {
this.mu.Lock()
@ -141,7 +133,7 @@ func (this *StringInterfaceMap) BatchRemove(keys []string) {
}
// 返回对应的键值,并删除该键值
func (this *StringInterfaceMap) GetAndRemove(key string) interface{} {
func (this *StringInterfaceMap) Remove(key string) interface{} {
this.mu.Lock()
val, exists := this.m[key]
if exists {

View File

@ -67,23 +67,70 @@ func (this *StringStringMap) Get(key string) string {
return val
}
// 获取键值,如果键值不存在则写入默认值
func (this *StringStringMap) GetWithDefault(key string, value string) string {
// 设置kv缓存键值对内部会对键名的存在性使用写锁进行二次检索确认如果存在则不再写入返回键名对应的键值。
// 在高并发下有用,防止数据写入的并发逻辑错误。
func (this *StringStringMap) doSetWithLockCheck(key string, value string) string {
this.mu.Lock()
val, ok := this.m[key]
if !ok {
this.m[key] = value
val = value
if v, ok := this.m[key]; ok {
this.mu.Unlock()
return v
}
this.m[key] = value
this.mu.Unlock()
return val
return value
}
// 删除键值对
func (this *StringStringMap) Remove(key string) {
this.mu.Lock()
delete(this.m, key)
this.mu.Unlock()
// 当键名存在时返回其键值,否则写入指定的键值
func (this *StringStringMap) GetOrSet(key string, value string) string {
this.mu.RLock()
v, ok := this.m[key]
this.mu.RUnlock()
if !ok {
return this.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()
if !ok {
return this.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()
if !ok {
this.mu.Lock()
defer this.mu.Unlock()
if v, ok := this.m[key]; ok {
this.mu.Unlock()
return v
}
val = f()
this.m[key] = val
return val
} else {
return val
}
}
// 当键名不存在时写入并返回true否则返回false。
func (this *StringStringMap) SetIfNotExist(key string, value string) bool {
if !this.Contains(key) {
this.doSetWithLockCheck(key, value)
return true
}
return false
}
// 批量删除键值对
@ -96,7 +143,7 @@ func (this *StringStringMap) BatchRemove(keys []string) {
}
// 返回对应的键值,并删除该键值
func (this *StringStringMap) GetAndRemove(key string) string {
func (this *StringStringMap) Remove(key string) string {
this.mu.Lock()
val, exists := this.m[key]
if exists {

View File

@ -1,175 +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/container/internal/rwmutex"
)
type UintInterfaceMap struct {
mu *rwmutex.RWMutex
m map[uint]interface{}
}
func NewUintInterfaceMap(safe...bool) *UintInterfaceMap {
return &UintInterfaceMap{
m : make(map[uint]interface{}),
mu : rwmutex.New(safe...),
}
}
func (this *UintInterfaceMap) Iterator(f func (k uint, v interface{}) bool) {
this.mu.RLock()
defer this.mu.RUnlock()
for k, v := range this.m {
if !f(k, v) {
break
}
}
}
// 哈希表克隆
func (this *UintInterfaceMap) Clone() map[uint]interface{} {
m := make(map[uint]interface{})
this.mu.RLock()
for k, v := range this.m {
m[k] = v
}
this.mu.RUnlock()
return m
}
// 设置键值对
func (this *UintInterfaceMap) Set(key uint, val interface{}) {
this.mu.Lock()
this.m[key] = val
this.mu.Unlock()
}
// 批量设置键值对
func (this *UintInterfaceMap) BatchSet(m map[uint]interface{}) {
this.mu.Lock()
for k, v := range m {
this.m[k] = v
}
this.mu.Unlock()
}
// 获取键值
func (this *UintInterfaceMap) Get(key uint) interface{} {
this.mu.RLock()
val, _ := this.m[key]
this.mu.RUnlock()
return val
}
// 获取键值,如果键值不存在则写入默认值
func (this *UintInterfaceMap) GetWithDefault(key uint, value interface{}) interface{} {
this.mu.Lock()
val, ok := this.m[key]
if !ok {
this.m[key] = value
val = value
}
this.mu.Unlock()
return val
}
// 删除键值对
func (this *UintInterfaceMap) Remove(key uint) {
this.mu.Lock()
delete(this.m, key)
this.mu.Unlock()
}
// 批量删除键值对
func (this *UintInterfaceMap) BatchRemove(keys []uint) {
this.mu.Lock()
for _, key := range keys {
delete(this.m, key)
}
this.mu.Unlock()
}
// 返回对应的键值,并删除该键值
func (this *UintInterfaceMap) GetAndRemove(key uint) (interface{}) {
this.mu.Lock()
val, exists := this.m[key]
if exists {
delete(this.m, key)
}
this.mu.Unlock()
return val
}
// 返回键列表
func (this *UintInterfaceMap) Keys() []uint {
this.mu.RLock()
keys := make([]uint, 0)
for key, _ := range this.m {
keys = append(keys, key)
}
this.mu.RUnlock()
return keys
}
// 返回值列表(注意是随机排序)
func (this *UintInterfaceMap) 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 *UintInterfaceMap) Contains(key uint) bool {
this.mu.RLock()
_, exists := this.m[key]
this.mu.RUnlock()
return exists
}
// 哈希表大小
func (this *UintInterfaceMap) Size() int {
this.mu.RLock()
length := len(this.m)
this.mu.RUnlock()
return length
}
// 哈希表是否为空
func (this *UintInterfaceMap) IsEmpty() bool {
this.mu.RLock()
empty := len(this.m) == 0
this.mu.RUnlock()
return empty
}
// 清空哈希表
func (this *UintInterfaceMap) Clear() {
this.mu.Lock()
this.m = make(map[uint]interface{})
this.mu.Unlock()
}
// 并发安全写锁操作,使用自定义方法执行加锁修改操作
func (this *UintInterfaceMap) LockFunc(f func(m map[uint]interface{})) {
this.mu.Lock(true)
defer this.mu.Unlock(true)
f(this.m)
}
// 并发安全读锁操作,使用自定义方法执行加锁读取操作
func (this *UintInterfaceMap) RLockFunc(f func(m map[uint]interface{})) {
this.mu.RLock(true)
defer this.mu.RUnlock(true)
f(this.m)
}

View File

@ -15,7 +15,6 @@ import (
)
var ints = gset.NewIntSet()
var uints = gset.NewUintSet()
var itfs = gset.NewInterfaceSet()
var strs = gset.NewStringSet()
@ -37,24 +36,6 @@ func BenchmarkIntSet_Remove(b *testing.B) {
}
}
func BenchmarkUintSet_Add(b *testing.B) {
for i := 0; i < b.N; i++ {
uints.Add(uint(i))
}
}
func BenchmarkUintSet_Contains(b *testing.B) {
for i := 0; i < b.N; i++ {
uints.Contains(uint(i))
}
}
func BenchmarkUintSet_Remove(b *testing.B) {
for i := 0; i < b.N; i++ {
uints.Remove(uint(i))
}
}
func BenchmarkInterfaceSet_Add(b *testing.B) {
for i := 0; i < b.N; i++ {
itfs.Add(i)

View File

@ -46,6 +46,11 @@ func GetOrSetFunc(key interface{}, f func() interface{}, expire int) interface{}
return cache.GetOrSetFunc(key, f, expire)
}
// 与GetOrSetFunc不同的是f是在写锁机制内执行
func GetOrSetFuncLock(key interface{}, f func() interface{}, expire int) interface{} {
return cache.GetOrSetFuncLock(key, f, expire)
}
// 是否存在指定的键名true表示存在false表示不存在。
func Contains(key interface{}) bool {
return cache.Contains(key)
@ -57,8 +62,8 @@ func Remove(key interface{}) interface{} {
}
// (使用全局KV缓存对象)批量删除指定键值对
func BatchRemove(keys []interface{}) map[interface{}]interface{} {
return cache.BatchRemove(keys)
func BatchRemove(keys []interface{}) {
cache.BatchRemove(keys)
}
// 获得所有的键名,组成数组返回

View File

@ -213,14 +213,12 @@ func (c *memCache) Remove(key interface{}) interface{} {
}
// 批量删除键值对,并返回被删除的键值对数据
func (c *memCache) BatchRemove(keys []interface{}) map[interface{}]interface{} {
m := make(map[interface{}]interface{})
func (c *memCache) BatchRemove(keys []interface{}) {
c.dmu.Lock()
for _, key := range keys {
if v := c.Remove(key); v != nil {
m[key] = v
}
delete(c.data, key)
}
return m
c.dmu.Unlock()
}
// 获得所有的键名,组成数组返回