数据结构容器增加并发安全特性开启/关闭功能,当关闭后和普通的数据结构无异,非并发安全模式下性能会得到提高

This commit is contained in:
john
2018-09-05 18:34:41 +08:00
parent 12bee26d5a
commit ebc10f7779
28 changed files with 278 additions and 126 deletions

View File

@ -6,3 +6,7 @@
// 并发安全的数组.
package garray
func New(size int, cap int, safe...bool) *Array {
return NewArray(size, cap, safe...)
}

View File

@ -6,21 +6,25 @@
package garray
import "sync"
import (
"gitee.com/johng/gf/g/container/internal/rwmutex"
)
type IntArray struct {
mu sync.RWMutex // 互斥锁
cap int // 初始化设置的数组容量
size int // 初始化设置的数组大小
array []int // 底层数组
mu *rwmutex.RWMutex // 互斥锁
cap int // 初始化设置的数组容量
size int // 初始化设置的数组大小
array []int // 底层数组
}
func NewIntArray(size int, cap ... int) *IntArray {
a := &IntArray{}
func NewIntArray(size int, cap int, safe...bool) *IntArray {
a := &IntArray{
mu : rwmutex.New(safe...),
}
a.size = size
if len(cap) > 0 {
a.cap = cap[0]
a.array = make([]int, size, cap[0])
if cap > 0 {
a.cap = cap
a.array = make([]int, size, cap)
} else {
a.array = make([]int, size)
}

View File

@ -6,21 +6,25 @@
package garray
import "sync"
import (
"gitee.com/johng/gf/g/container/internal/rwmutex"
)
type Array struct {
mu sync.RWMutex // 互斥锁
cap int // 初始化设置的数组容量
size int // 初始化设置的数组大小
array []interface{} // 底层数组
mu *rwmutex.RWMutex // 互斥锁
cap int // 初始化设置的数组容量
size int // 初始化设置的数组大小
array []interface{} // 底层数组
}
func NewArray(size int, cap ... int) *Array {
a := &Array{}
func NewArray(size int, cap int, safe...bool) *Array {
a := &Array{
mu : rwmutex.New(safe...),
}
a.size = size
if len(cap) > 0 {
a.cap = cap[0]
a.array = make([]interface{}, size, cap[0])
if cap > 0 {
a.cap = cap
a.array = make([]interface{}, size, cap)
} else {
a.array = make([]interface{}, size)
}

View File

@ -7,13 +7,13 @@
package garray
import (
"sync"
"gitee.com/johng/gf/g/container/gtype"
"gitee.com/johng/gf/g/container/internal/rwmutex"
)
// 默认按照从低到高进行排序
type SortedIntArray struct {
mu sync.RWMutex // 互斥锁
mu *rwmutex.RWMutex // 互斥锁
cap int // 初始化设置的数组容量
size int // 初始化设置的数组大小
array []int // 底层数组
@ -21,8 +21,9 @@ type SortedIntArray struct {
compareFunc func(v1, v2 int) int // 比较函数,返回值 -1: v1 < v20: v1 == v21: v1 > v2
}
func NewSortedIntArray(size int, cap ... int) *SortedIntArray {
func NewSortedIntArray(size int, cap int, safe...bool) *SortedIntArray {
a := &SortedIntArray {
mu : rwmutex.New(safe...),
unique : gtype.NewBool(),
compareFunc : func(v1, v2 int) int {
if v1 < v2 {
@ -35,9 +36,9 @@ func NewSortedIntArray(size int, cap ... int) *SortedIntArray {
},
}
a.size = size
if len(cap) > 0 {
a.cap = cap[0]
a.array = make([]int, size, cap[0])
if cap > 0 {
a.cap = cap
a.array = make([]int, size, cap)
} else {
a.array = make([]int, size)
}

View File

@ -7,13 +7,13 @@
package garray
import (
"sync"
"gitee.com/johng/gf/g/container/gtype"
"gitee.com/johng/gf/g/container/internal/rwmutex"
)
// 默认按照从低到高进行排序
type SortedArray struct {
mu sync.RWMutex // 互斥锁
mu *rwmutex.RWMutex // 互斥锁
cap int // 初始化设置的数组容量
size int // 初始化设置的数组大小
array []interface{} // 底层数组
@ -21,8 +21,9 @@ type SortedArray struct {
compareFunc func(v1, v2 interface{}) int // 比较函数,返回值 -1: v1 < v20: v1 == v21: v1 > v2
}
func NewSortedArray(size int, cap int, compareFunc func(v1, v2 interface{}) int) *SortedArray {
func NewSortedArray(size int, cap int, compareFunc func(v1, v2 interface{}) int, safe...bool) *SortedArray {
return &SortedArray{
mu : rwmutex.New(safe...),
unique : gtype.NewBool(),
array : make([]interface{}, size, cap),
compareFunc : compareFunc,

View File

@ -7,14 +7,14 @@
package garray
import (
"sync"
"gitee.com/johng/gf/g/container/gtype"
"strings"
"gitee.com/johng/gf/g/container/internal/rwmutex"
)
// 默认按照从低到高进行排序
type SortedStringArray struct {
mu sync.RWMutex // 互斥锁
mu *rwmutex.RWMutex // 互斥锁
cap int // 初始化设置的数组容量
size int // 初始化设置的数组大小
array []string // 底层数组
@ -22,17 +22,18 @@ type SortedStringArray struct {
compareFunc func(v1, v2 string) int // 比较函数,返回值 -1: v1 < v20: v1 == v21: v1 > v2
}
func NewSortedStringArray(size int, cap ... int) *SortedStringArray {
func NewSortedStringArray(size int, cap int, safe...bool) *SortedStringArray {
a := &SortedStringArray {
mu : rwmutex.New(safe...),
unique : gtype.NewBool(),
compareFunc : func(v1, v2 string) int {
return strings.Compare(v1, v2)
},
}
a.size = size
if len(cap) > 0 {
a.cap = cap[0]
a.array = make([]string, size, cap[0])
if cap > 0 {
a.cap = cap
a.array = make([]string, size, cap)
} else {
a.array = make([]string, size)
}

View File

@ -7,23 +7,25 @@
package garray
import (
"sync"
"strings"
"gitee.com/johng/gf/g/container/internal/rwmutex"
)
type StringArray struct {
mu sync.RWMutex // 互斥锁
cap int // 初始化设置的数组容量
size int // 初始化设置的数组大小
array []string // 底层数组
mu *rwmutex.RWMutex // 互斥锁
cap int // 初始化设置的数组容量
size int // 初始化设置的数组大小
array []string // 底层数组
}
func NewStringArray(size int, cap ... int) *StringArray {
a := &StringArray{}
func NewStringArray(size int, cap int, safe...bool) *StringArray {
a := &StringArray{
mu : rwmutex.New(safe...),
}
a.size = size
if len(cap) > 0 {
a.cap = cap[0]
a.array = make([]string, size, cap[0])
if cap > 0 {
a.cap = cap
a.array = make([]string, size, cap)
} else {
a.array = make([]string, size)
}

View File

@ -9,19 +9,22 @@
package glist
import (
"sync"
"container/list"
"gitee.com/johng/gf/g/container/internal/rwmutex"
)
// 变长双向链表
type List struct {
mu sync.RWMutex
mu *rwmutex.RWMutex
list *list.List
}
// 获得一个变长链表指针
func New() *List {
return &List{list: list.New()}
func New(safe...bool) *List {
return &List{
mu : rwmutex.New(safe...),
list : list.New(),
}
}
// 往链表头入栈数据项

View File

@ -14,6 +14,6 @@ package gmap
// 3、底层实现比较类似于sync.Map
type Map = InterfaceInterfaceMap
func NewMap() *Map {
return NewInterfaceInterfaceMap()
func New(safe...bool) *Map {
return NewInterfaceInterfaceMap(safe...)
}

View File

@ -8,17 +8,18 @@
package gmap
import (
"sync"
"gitee.com/johng/gf/g/container/internal/rwmutex"
)
type IntBoolMap struct {
mu sync.RWMutex
m map[int]bool
mu *rwmutex.RWMutex
}
func NewIntBoolMap() *IntBoolMap {
func NewIntBoolMap(safe...bool) *IntBoolMap {
return &IntBoolMap{
m: make(map[int]bool),
m : make(map[int]bool),
mu : rwmutex.New(safe...),
}
}

View File

@ -8,17 +8,18 @@
package gmap
import (
"sync"
"gitee.com/johng/gf/g/container/internal/rwmutex"
)
type IntIntMap struct {
mu sync.RWMutex
mu *rwmutex.RWMutex
m map[int]int
}
func NewIntIntMap() *IntIntMap {
func NewIntIntMap(safe...bool) *IntIntMap {
return &IntIntMap{
m: make(map[int]int),
m : make(map[int]int),
mu : rwmutex.New(safe...),
}
}

View File

@ -7,18 +7,17 @@
package gmap
import (
"sync"
)
import "gitee.com/johng/gf/g/container/internal/rwmutex"
type IntInterfaceMap struct {
mu sync.RWMutex
mu *rwmutex.RWMutex
m map[int]interface{}
}
func NewIntInterfaceMap() *IntInterfaceMap {
func NewIntInterfaceMap(safe...bool) *IntInterfaceMap {
return &IntInterfaceMap{
m: make(map[int]interface{}),
m : make(map[int]interface{}),
mu : rwmutex.New(safe...),
}
}

View File

@ -8,17 +8,18 @@
package gmap
import (
"sync"
"gitee.com/johng/gf/g/container/internal/rwmutex"
)
type IntStringMap struct {
mu sync.RWMutex
mu *rwmutex.RWMutex
m map[int]string
}
func NewIntStringMap() *IntStringMap {
func NewIntStringMap(safe...bool) *IntStringMap {
return &IntStringMap{
m: make(map[int]string),
m : make(map[int]string),
mu : rwmutex.New(safe...),
}
}

View File

@ -8,17 +8,18 @@
package gmap
import (
"sync"
"gitee.com/johng/gf/g/container/internal/rwmutex"
)
type InterfaceInterfaceMap struct {
mu sync.RWMutex
mu *rwmutex.RWMutex
m map[interface{}]interface{}
}
func NewInterfaceInterfaceMap() *InterfaceInterfaceMap {
func NewInterfaceInterfaceMap(safe...bool) *InterfaceInterfaceMap {
return &InterfaceInterfaceMap{
m: make(map[interface{}]interface{}),
m : make(map[interface{}]interface{}),
mu : rwmutex.New(safe...),
}
}

View File

@ -8,17 +8,18 @@
package gmap
import (
"sync"
"gitee.com/johng/gf/g/container/internal/rwmutex"
)
type StringBoolMap struct {
mu sync.RWMutex
mu *rwmutex.RWMutex
m map[string]bool
}
func NewStringBoolMap() *StringBoolMap {
func NewStringBoolMap(safe...bool) *StringBoolMap {
return &StringBoolMap{
m: make(map[string]bool),
m : make(map[string]bool),
mu : rwmutex.New(safe...),
}
}

View File

@ -7,18 +7,17 @@
package gmap
import (
"sync"
)
import "gitee.com/johng/gf/g/container/internal/rwmutex"
type StringIntMap struct {
mu sync.RWMutex
mu *rwmutex.RWMutex
m map[string]int
}
func NewStringIntMap() *StringIntMap {
func NewStringIntMap(safe...bool) *StringIntMap {
return &StringIntMap{
m: make(map[string]int),
m : make(map[string]int),
mu : rwmutex.New(safe...),
}
}

View File

@ -8,17 +8,18 @@
package gmap
import (
"sync"
"gitee.com/johng/gf/g/container/internal/rwmutex"
)
type StringInterfaceMap struct {
mu sync.RWMutex
mu *rwmutex.RWMutex
m map[string]interface{}
}
func NewStringInterfaceMap() *StringInterfaceMap {
func NewStringInterfaceMap(safe...bool) *StringInterfaceMap {
return &StringInterfaceMap{
m: make(map[string]interface{}),
m : make(map[string]interface{}),
mu : rwmutex.New(safe...),
}
}

View File

@ -7,18 +7,17 @@
package gmap
import (
"sync"
)
import "gitee.com/johng/gf/g/container/internal/rwmutex"
type StringStringMap struct {
mu sync.RWMutex
mu *rwmutex.RWMutex
m map[string]string
}
func NewStringStringMap() *StringStringMap {
func NewStringStringMap(safe...bool) *StringStringMap {
return &StringStringMap{
m: make(map[string]string),
m : make(map[string]string),
mu : rwmutex.New(safe...),
}
}

View File

@ -8,17 +8,18 @@
package gmap
import (
"sync"
"gitee.com/johng/gf/g/container/internal/rwmutex"
)
type UintInterfaceMap struct {
mu sync.RWMutex
mu *rwmutex.RWMutex
m map[uint]interface{}
}
func NewUintInterfaceMap() *UintInterfaceMap {
func NewUintInterfaceMap(safe...bool) *UintInterfaceMap {
return &UintInterfaceMap{
m: make(map[uint]interface{}),
m : make(map[uint]interface{}),
mu : rwmutex.New(safe...),
}
}

View File

@ -9,20 +9,21 @@ package gring
import (
"container/ring"
"sync"
"gitee.com/johng/gf/g/container/gtype"
"gitee.com/johng/gf/g/container/internal/rwmutex"
)
type Ring struct {
mu sync.RWMutex // 互斥锁
ring *ring.Ring // 底层环形数据结构
len *gtype.Int // 数据大小(已使用的大小)
cap *gtype.Int // 总长度(分配的环大小,包括未使用的数据项数量)
dirty *gtype.Bool // 标记环是否脏了(需要重新计算大小,当环大小发生改变时做标记)
mu *rwmutex.RWMutex // 互斥锁
ring *ring.Ring // 底层环形数据结构
len *gtype.Int // 数据大小(已使用的大小)
cap *gtype.Int // 总长度(分配的环大小,包括未使用的数据项数量)
dirty *gtype.Bool // 标记环是否脏了(需要重新计算大小,当环大小发生改变时做标记)
}
func New(cap int) *Ring {
func New(cap int, safe...bool) *Ring {
return &Ring {
mu : rwmutex.New(safe...),
ring : ring.New(cap),
len : gtype.NewInt(),
cap : gtype.NewInt(cap),

View File

@ -10,6 +10,6 @@ package gset
type Set = InterfaceSet
// 默认Set类型
func New() *Set {
return NewInterfaceSet()
func New(safe...bool) *Set {
return NewInterfaceSet(safe...)
}

View File

@ -10,16 +10,19 @@ package gset
import (
"fmt"
"sync"
"gitee.com/johng/gf/g/container/internal/rwmutex"
)
type IntSet struct {
mu sync.RWMutex
mu *rwmutex.RWMutex
m map[int]struct{}
}
func NewIntSet() *IntSet {
return &IntSet{m: make(map[int]struct{})}
func NewIntSet(safe...bool) *IntSet {
return &IntSet{
m : make(map[int]struct{}),
mu : rwmutex.New(safe...),
}
}
// 给定回调函数对原始内容进行遍历回调函数返回true表示继续遍历否则停止遍历

View File

@ -9,16 +9,19 @@ package gset
import (
"fmt"
"sync"
"gitee.com/johng/gf/g/container/internal/rwmutex"
)
type InterfaceSet struct {
mu sync.RWMutex
mu *rwmutex.RWMutex
m map[interface{}]struct{}
}
func NewInterfaceSet() *InterfaceSet {
return &InterfaceSet{m: make(map[interface{}]struct{})}
func NewInterfaceSet(safe...bool) *InterfaceSet {
return &InterfaceSet{
m : make(map[interface{}]struct{}),
mu : rwmutex.New(safe...),
}
}
// 给定回调函数对原始内容进行遍历回调函数返回true表示继续遍历否则停止遍历

View File

@ -9,16 +9,19 @@ package gset
import (
"fmt"
"sync"
"gitee.com/johng/gf/g/container/internal/rwmutex"
)
type StringSet struct {
mu sync.RWMutex
mu *rwmutex.RWMutex
m map[string]struct{}
}
func NewStringSet() *StringSet {
return &StringSet{m: make(map[string]struct{})}
func NewStringSet(safe...bool) *StringSet {
return &StringSet{
m : make(map[string]struct{}),
mu : rwmutex.New(safe...),
}
}
// 给定回调函数对原始内容进行遍历回调函数返回true表示继续遍历否则停止遍历

View File

@ -9,16 +9,19 @@ package gset
import (
"fmt"
"sync"
"gitee.com/johng/gf/g/container/internal/rwmutex"
)
type UintSet struct {
mu sync.RWMutex
mu *rwmutex.RWMutex
m map[uint]struct{}
}
func NewUintSet() *UintSet {
return &UintSet{m: make(map[uint]struct{})}
func NewUintSet(safe...bool) *UintSet {
return &UintSet{
m : make(map[uint]struct{}),
mu : rwmutex.New(safe...),
}
}
// 给定回调函数对原始内容进行遍历回调函数返回true表示继续遍历否则停止遍历

View File

@ -0,0 +1,44 @@
package rwmutex
import "sync"
// RWMutex的封装支持对并发安全开启/关闭的控制。
// 但是只能初始化时确定并发安全性,不能在运行时动态修改并发安全特性设置。
type RWMutex struct {
sync.RWMutex
safe bool
}
func New(safe...bool) *RWMutex {
mu := new(RWMutex)
if len(safe) > 0 {
mu.safe = safe[0]
} else {
mu.safe = true
}
return mu
}
func (mu *RWMutex) Lock() {
if mu.safe {
mu.RWMutex.Lock()
}
}
func (mu *RWMutex) Unlock() {
if mu.safe {
mu.RWMutex.Unlock()
}
}
func (mu *RWMutex) RLock() {
if mu.safe {
mu.RWMutex.RLock()
}
}
func (mu *RWMutex) RUnlock() {
if mu.safe {
mu.RWMutex.RUnlock()
}
}

View File

@ -0,0 +1,73 @@
package main
import (
"fmt"
"gitee.com/johng/gf/g/container/gmap"
)
func main() {
// 创建一个默认的gmap对象
// 默认情况下该gmap对象支持并发安全特性
// 初始化时可以给定false参数关闭并发安全特性当做一个普通的map使用。
m := gmap.New()
// 设置键值对
for i := 0; i < 10; i++ {
m.Set(i, i)
}
// 查询大小
fmt.Println(m.Size())
// 批量设置键值对(不同的数据类型对象参数不同)
m.BatchSet(map[interface{}]interface{}{
10 : 10,
11 : 11,
})
fmt.Println(m.Size())
// 查询是否存在
fmt.Println(m.Contains(1))
// 查询键值
fmt.Println(m.Get(1))
// 删除数据项
m.Remove(9)
fmt.Println(m.Size())
// 批量删除
m.BatchRemove([]interface{}{10, 11})
fmt.Println(m.Size())
// 当前键名列表(随机排序)
fmt.Println(m.Keys())
// 当前键值列表(随机排序)
fmt.Println(m.Values())
// 查询键名,当键值不存在时,写入给定的默认值
fmt.Println(m.GetWithDefault(100, 100))
// 删除键值对,并返回对应的键值
fmt.Println(m.GetAndRemove(100))
// 遍历map
m.Iterator(func(k interface{}, v interface{}) bool {
fmt.Printf("%v:%v ", k, v)
return true
})
// 自定义写锁操作
m.LockFunc(func(m map[interface{}]interface{}) {
m[99] = 99
})
// 自定义读锁操作
m.RLockFunc(func(m map[interface{}]interface{}) {
fmt.Println(m[99])
})
// 清空map
m.Clear()
// 判断map是否为空
fmt.Println(m.IsEmpty())
}

View File

@ -1,9 +1,7 @@
package main
import (
"fmt"
)
func main() {
fmt.Println(len([]rune("中国人")))
}