mirror of
https://gitee.com/johng/gf.git
synced 2024-11-29 18:57:44 +08:00
improve package gset
This commit is contained in:
parent
8e6018cfff
commit
b17e3a6804
@ -50,7 +50,7 @@ func NewFrom(items interface{}, safe ...bool) *Set {
|
||||
|
||||
// Iterator iterates the set with given callback function <f>,
|
||||
// if <f> returns true then continue iterating; or false to stop.
|
||||
func (set *Set) Iterator(f func(v interface{}) bool) *Set {
|
||||
func (set *Set) Iterator(f func(v interface{}) bool) {
|
||||
set.mu.RLock()
|
||||
defer set.mu.RUnlock()
|
||||
for k, _ := range set.data {
|
||||
@ -58,11 +58,10 @@ func (set *Set) Iterator(f func(v interface{}) bool) *Set {
|
||||
break
|
||||
}
|
||||
}
|
||||
return set
|
||||
}
|
||||
|
||||
// Add adds one or multiple items to the set.
|
||||
func (set *Set) Add(item ...interface{}) *Set {
|
||||
func (set *Set) Add(item ...interface{}) {
|
||||
set.mu.Lock()
|
||||
if set.data == nil {
|
||||
set.data = make(map[interface{}]struct{})
|
||||
@ -71,54 +70,81 @@ func (set *Set) Add(item ...interface{}) *Set {
|
||||
set.data[v] = struct{}{}
|
||||
}
|
||||
set.mu.Unlock()
|
||||
return set
|
||||
}
|
||||
|
||||
// AddIfNotExistFunc adds the returned value of callback function <f> to the set
|
||||
// if <item> does not exit in the set.
|
||||
func (set *Set) AddIfNotExistFunc(item interface{}, f func() interface{}) *Set {
|
||||
// AddIfNotExist checks whether item exists in the set,
|
||||
// it adds the item to set and returns true if it does not exists in the set,
|
||||
// or else it does nothing and returns false.
|
||||
//
|
||||
// Note that, if <item> is nil, it does nothing and returns false.
|
||||
func (set *Set) AddIfNotExist(item interface{}) bool {
|
||||
if item == nil {
|
||||
return false
|
||||
}
|
||||
if !set.Contains(item) {
|
||||
set.doAddWithLockCheck(item, f())
|
||||
}
|
||||
return set
|
||||
}
|
||||
|
||||
// AddIfNotExistFuncLock adds the returned value of callback function <f> to the set
|
||||
// if <item> does not exit in the set.
|
||||
//
|
||||
// Note that the callback function <f> is executed in the mutex.Lock of the set.
|
||||
func (set *Set) AddIfNotExistFuncLock(item interface{}, f func() interface{}) *Set {
|
||||
if !set.Contains(item) {
|
||||
set.doAddWithLockCheck(item, f)
|
||||
}
|
||||
return set
|
||||
}
|
||||
|
||||
// doAddWithLockCheck checks whether item exists with mutex.Lock,
|
||||
// if not exists, it adds item to the set or else just returns the existing value.
|
||||
//
|
||||
// If <value> is type of <func() interface {}>,
|
||||
// it will be executed with mutex.Lock of the set,
|
||||
// and its return value will be added to the set.
|
||||
//
|
||||
// It returns item successfully added..
|
||||
func (set *Set) doAddWithLockCheck(item interface{}, value interface{}) interface{} {
|
||||
set.mu.Lock()
|
||||
defer set.mu.Unlock()
|
||||
if set.data == nil {
|
||||
set.data = make(map[interface{}]struct{})
|
||||
}
|
||||
if _, ok := set.data[item]; !ok && value != nil {
|
||||
if f, ok := value.(func() interface{}); ok {
|
||||
item = f()
|
||||
} else {
|
||||
item = value
|
||||
set.mu.Lock()
|
||||
defer set.mu.Unlock()
|
||||
if set.data == nil {
|
||||
set.data = make(map[interface{}]struct{})
|
||||
}
|
||||
if _, ok := set.data[item]; !ok {
|
||||
set.data[item] = struct{}{}
|
||||
return true
|
||||
}
|
||||
}
|
||||
if item != nil {
|
||||
set.data[item] = struct{}{}
|
||||
return false
|
||||
}
|
||||
|
||||
// AddIfNotExistFunc checks whether item exists in the set,
|
||||
// it adds the item to set and returns true if it does not exists in the set and
|
||||
// function <f> returns true, or else it does nothing and returns false.
|
||||
//
|
||||
// Note that, if <item> is nil, it does nothing and returns false. The function <f>
|
||||
// is executed without writing lock.
|
||||
func (set *Set) AddIfNotExistFunc(item interface{}, f func() bool) bool {
|
||||
if item == nil {
|
||||
return false
|
||||
}
|
||||
return item
|
||||
if !set.Contains(item) {
|
||||
if f() {
|
||||
set.mu.Lock()
|
||||
defer set.mu.Unlock()
|
||||
if set.data == nil {
|
||||
set.data = make(map[interface{}]struct{})
|
||||
}
|
||||
if _, ok := set.data[item]; !ok {
|
||||
set.data[item] = struct{}{}
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// AddIfNotExistFunc checks whether item exists in the set,
|
||||
// it adds the item to set and returns true if it does not exists in the set and
|
||||
// function <f> returns true, or else it does nothing and returns false.
|
||||
//
|
||||
// Note that, if <item> is nil, it does nothing and returns false. The function <f>
|
||||
// is executed within writing lock.
|
||||
func (set *Set) AddIfNotExistFuncLock(item interface{}, f func() bool) bool {
|
||||
if item == nil {
|
||||
return false
|
||||
}
|
||||
if !set.Contains(item) {
|
||||
set.mu.Lock()
|
||||
defer set.mu.Unlock()
|
||||
if set.data == nil {
|
||||
set.data = make(map[interface{}]struct{})
|
||||
}
|
||||
if f() {
|
||||
if _, ok := set.data[item]; !ok {
|
||||
set.data[item] = struct{}{}
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Contains checks whether the set contains <item>.
|
||||
@ -133,13 +159,12 @@ func (set *Set) Contains(item interface{}) bool {
|
||||
}
|
||||
|
||||
// Remove deletes <item> from set.
|
||||
func (set *Set) Remove(item interface{}) *Set {
|
||||
func (set *Set) Remove(item interface{}) {
|
||||
set.mu.Lock()
|
||||
if set.data != nil {
|
||||
delete(set.data, item)
|
||||
}
|
||||
set.mu.Unlock()
|
||||
return set
|
||||
}
|
||||
|
||||
// Size returns the size of the set.
|
||||
@ -151,11 +176,10 @@ func (set *Set) Size() int {
|
||||
}
|
||||
|
||||
// Clear deletes all items of the set.
|
||||
func (set *Set) Clear() *Set {
|
||||
func (set *Set) Clear() {
|
||||
set.mu.Lock()
|
||||
set.data = make(map[interface{}]struct{})
|
||||
set.mu.Unlock()
|
||||
return set
|
||||
}
|
||||
|
||||
// Slice returns the a of items of the set as slice.
|
||||
|
@ -43,7 +43,7 @@ func NewIntSetFrom(items []int, safe ...bool) *IntSet {
|
||||
|
||||
// Iterator iterates the set with given callback function <f>,
|
||||
// if <f> returns true then continue iterating; or false to stop.
|
||||
func (set *IntSet) Iterator(f func(v int) bool) *IntSet {
|
||||
func (set *IntSet) Iterator(f func(v int) bool) {
|
||||
set.mu.RLock()
|
||||
defer set.mu.RUnlock()
|
||||
for k, _ := range set.data {
|
||||
@ -51,11 +51,10 @@ func (set *IntSet) Iterator(f func(v int) bool) *IntSet {
|
||||
break
|
||||
}
|
||||
}
|
||||
return set
|
||||
}
|
||||
|
||||
// Add adds one or multiple items to the set.
|
||||
func (set *IntSet) Add(item ...int) *IntSet {
|
||||
func (set *IntSet) Add(item ...int) {
|
||||
set.mu.Lock()
|
||||
if set.data == nil {
|
||||
set.data = make(map[int]struct{})
|
||||
@ -64,52 +63,70 @@ func (set *IntSet) Add(item ...int) *IntSet {
|
||||
set.data[v] = struct{}{}
|
||||
}
|
||||
set.mu.Unlock()
|
||||
return set
|
||||
}
|
||||
|
||||
// AddIfNotExistFunc adds the returned value of callback function <f> to the set
|
||||
// if <item> does not exit in the set.
|
||||
func (set *IntSet) AddIfNotExistFunc(item int, f func() int) *IntSet {
|
||||
// AddIfNotExist checks whether item exists in the set,
|
||||
// it adds the item to set and returns true if it does not exists in the set,
|
||||
// or else it does nothing and returns false.
|
||||
//
|
||||
// Note that, if <item> is nil, it does nothing and returns false.
|
||||
func (set *IntSet) AddIfNotExist(item int) bool {
|
||||
if !set.Contains(item) {
|
||||
set.doAddWithLockCheck(item, f())
|
||||
}
|
||||
return set
|
||||
}
|
||||
|
||||
// AddIfNotExistFuncLock adds the returned value of callback function <f> to the set
|
||||
// if <item> does not exit in the set.
|
||||
//
|
||||
// Note that the callback function <f> is executed in the mutex.Lock of the set.
|
||||
func (set *IntSet) AddIfNotExistFuncLock(item int, f func() int) *IntSet {
|
||||
if !set.Contains(item) {
|
||||
set.doAddWithLockCheck(item, f)
|
||||
}
|
||||
return set
|
||||
}
|
||||
|
||||
// doAddWithLockCheck checks whether item exists with mutex.Lock,
|
||||
// if not exists, it adds item to the set or else just returns the existing value.
|
||||
//
|
||||
// If <value> is type of <func() interface {}>,
|
||||
// it will be executed with mutex.Lock of the set,
|
||||
// and its return value will be added to the set.
|
||||
//
|
||||
// It returns item successfully added..
|
||||
func (set *IntSet) doAddWithLockCheck(item int, value interface{}) int {
|
||||
set.mu.Lock()
|
||||
defer set.mu.Unlock()
|
||||
if set.data == nil {
|
||||
set.data = make(map[int]struct{})
|
||||
}
|
||||
if _, ok := set.data[item]; !ok && value != nil {
|
||||
if f, ok := value.(func() int); ok {
|
||||
item = f()
|
||||
} else {
|
||||
item = value.(int)
|
||||
set.mu.Lock()
|
||||
defer set.mu.Unlock()
|
||||
if set.data == nil {
|
||||
set.data = make(map[int]struct{})
|
||||
}
|
||||
if _, ok := set.data[item]; !ok {
|
||||
set.data[item] = struct{}{}
|
||||
return true
|
||||
}
|
||||
}
|
||||
set.data[item] = struct{}{}
|
||||
return item
|
||||
return false
|
||||
}
|
||||
|
||||
// AddIfNotExistFunc checks whether item exists in the set,
|
||||
// it adds the item to set and returns true if it does not exists in the set and
|
||||
// function <f> returns true, or else it does nothing and returns false.
|
||||
//
|
||||
// Note that, the function <f> is executed without writing lock.
|
||||
func (set *IntSet) AddIfNotExistFunc(item int, f func() bool) bool {
|
||||
if !set.Contains(item) {
|
||||
if f() {
|
||||
set.mu.Lock()
|
||||
defer set.mu.Unlock()
|
||||
if set.data == nil {
|
||||
set.data = make(map[int]struct{})
|
||||
}
|
||||
if _, ok := set.data[item]; !ok {
|
||||
set.data[item] = struct{}{}
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// AddIfNotExistFunc checks whether item exists in the set,
|
||||
// it adds the item to set and returns true if it does not exists in the set and
|
||||
// function <f> returns true, or else it does nothing and returns false.
|
||||
//
|
||||
// Note that, the function <f> is executed without writing lock.
|
||||
func (set *IntSet) AddIfNotExistFuncLock(item int, f func() bool) bool {
|
||||
if !set.Contains(item) {
|
||||
set.mu.Lock()
|
||||
defer set.mu.Unlock()
|
||||
if set.data == nil {
|
||||
set.data = make(map[int]struct{})
|
||||
}
|
||||
if f() {
|
||||
if _, ok := set.data[item]; !ok {
|
||||
set.data[item] = struct{}{}
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Contains checks whether the set contains <item>.
|
||||
@ -124,13 +141,12 @@ func (set *IntSet) Contains(item int) bool {
|
||||
}
|
||||
|
||||
// Remove deletes <item> from set.
|
||||
func (set *IntSet) Remove(item int) *IntSet {
|
||||
func (set *IntSet) Remove(item int) {
|
||||
set.mu.Lock()
|
||||
if set.data != nil {
|
||||
delete(set.data, item)
|
||||
}
|
||||
set.mu.Unlock()
|
||||
return set
|
||||
}
|
||||
|
||||
// Size returns the size of the set.
|
||||
@ -142,11 +158,10 @@ func (set *IntSet) Size() int {
|
||||
}
|
||||
|
||||
// Clear deletes all items of the set.
|
||||
func (set *IntSet) Clear() *IntSet {
|
||||
func (set *IntSet) Clear() {
|
||||
set.mu.Lock()
|
||||
set.data = make(map[int]struct{})
|
||||
set.mu.Unlock()
|
||||
return set
|
||||
}
|
||||
|
||||
// Slice returns the a of items of the set as slice.
|
||||
|
@ -44,7 +44,7 @@ func NewStrSetFrom(items []string, safe ...bool) *StrSet {
|
||||
|
||||
// Iterator iterates the set with given callback function <f>,
|
||||
// if <f> returns true then continue iterating; or false to stop.
|
||||
func (set *StrSet) Iterator(f func(v string) bool) *StrSet {
|
||||
func (set *StrSet) Iterator(f func(v string) bool) {
|
||||
set.mu.RLock()
|
||||
defer set.mu.RUnlock()
|
||||
for k, _ := range set.data {
|
||||
@ -52,11 +52,10 @@ func (set *StrSet) Iterator(f func(v string) bool) *StrSet {
|
||||
break
|
||||
}
|
||||
}
|
||||
return set
|
||||
}
|
||||
|
||||
// Add adds one or multiple items to the set.
|
||||
func (set *StrSet) Add(item ...string) *StrSet {
|
||||
func (set *StrSet) Add(item ...string) {
|
||||
set.mu.Lock()
|
||||
if set.data == nil {
|
||||
set.data = make(map[string]struct{})
|
||||
@ -65,54 +64,68 @@ func (set *StrSet) Add(item ...string) *StrSet {
|
||||
set.data[v] = struct{}{}
|
||||
}
|
||||
set.mu.Unlock()
|
||||
return set
|
||||
}
|
||||
|
||||
// AddIfNotExistFunc adds the returned value of callback function <f> to the set
|
||||
// if <item> does not exit in the set.
|
||||
func (set *StrSet) AddIfNotExistFunc(item string, f func() string) *StrSet {
|
||||
// AddIfNotExist checks whether item exists in the set,
|
||||
// it adds the item to set and returns true if it does not exists in the set,
|
||||
// or else it does nothing and returns false.
|
||||
func (set *StrSet) AddIfNotExist(item string) bool {
|
||||
if !set.Contains(item) {
|
||||
set.doAddWithLockCheck(item, f())
|
||||
}
|
||||
return set
|
||||
}
|
||||
|
||||
// AddIfNotExistFuncLock adds the returned value of callback function <f> to the set
|
||||
// if <item> does not exit in the set.
|
||||
//
|
||||
// Note that the callback function <f> is executed in the mutex.Lock of the set.
|
||||
func (set *StrSet) AddIfNotExistFuncLock(item string, f func() string) *StrSet {
|
||||
if !set.Contains(item) {
|
||||
set.doAddWithLockCheck(item, f)
|
||||
}
|
||||
return set
|
||||
}
|
||||
|
||||
// doAddWithLockCheck checks whether item exists with mutex.Lock,
|
||||
// if not exists, it adds item to the set or else just returns the existing value.
|
||||
//
|
||||
// If <value> is type of <func() interface {}>,
|
||||
// it will be executed with mutex.Lock of the set,
|
||||
// and its return value will be added to the set.
|
||||
//
|
||||
// It returns item successfully added..
|
||||
func (set *StrSet) doAddWithLockCheck(item string, value interface{}) string {
|
||||
set.mu.Lock()
|
||||
defer set.mu.Unlock()
|
||||
if set.data == nil {
|
||||
set.data = make(map[string]struct{})
|
||||
}
|
||||
if _, ok := set.data[item]; !ok && value != nil {
|
||||
if f, ok := value.(func() string); ok {
|
||||
item = f()
|
||||
} else {
|
||||
item = value.(string)
|
||||
set.mu.Lock()
|
||||
defer set.mu.Unlock()
|
||||
if set.data == nil {
|
||||
set.data = make(map[string]struct{})
|
||||
}
|
||||
if _, ok := set.data[item]; !ok {
|
||||
set.data[item] = struct{}{}
|
||||
return true
|
||||
}
|
||||
}
|
||||
if item != "" {
|
||||
set.data[item] = struct{}{}
|
||||
return false
|
||||
}
|
||||
|
||||
// AddIfNotExistFunc checks whether item exists in the set,
|
||||
// it adds the item to set and returns true if it does not exists in the set and
|
||||
// function <f> returns true, or else it does nothing and returns false.
|
||||
//
|
||||
// Note that, the function <f> is executed without writing lock.
|
||||
func (set *StrSet) AddIfNotExistFunc(item string, f func() bool) bool {
|
||||
if !set.Contains(item) {
|
||||
if f() {
|
||||
set.mu.Lock()
|
||||
defer set.mu.Unlock()
|
||||
if set.data == nil {
|
||||
set.data = make(map[string]struct{})
|
||||
}
|
||||
if _, ok := set.data[item]; !ok {
|
||||
set.data[item] = struct{}{}
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return item
|
||||
return false
|
||||
}
|
||||
|
||||
// AddIfNotExistFunc checks whether item exists in the set,
|
||||
// it adds the item to set and returns true if it does not exists in the set and
|
||||
// function <f> returns true, or else it does nothing and returns false.
|
||||
//
|
||||
// Note that, the function <f> is executed without writing lock.
|
||||
func (set *StrSet) AddIfNotExistFuncLock(item string, f func() bool) bool {
|
||||
if !set.Contains(item) {
|
||||
set.mu.Lock()
|
||||
defer set.mu.Unlock()
|
||||
if set.data == nil {
|
||||
set.data = make(map[string]struct{})
|
||||
}
|
||||
if f() {
|
||||
if _, ok := set.data[item]; !ok {
|
||||
set.data[item] = struct{}{}
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Contains checks whether the set contains <item>.
|
||||
@ -127,13 +140,12 @@ func (set *StrSet) Contains(item string) bool {
|
||||
}
|
||||
|
||||
// Remove deletes <item> from set.
|
||||
func (set *StrSet) Remove(item string) *StrSet {
|
||||
func (set *StrSet) Remove(item string) {
|
||||
set.mu.Lock()
|
||||
if set.data != nil {
|
||||
delete(set.data, item)
|
||||
}
|
||||
set.mu.Unlock()
|
||||
return set
|
||||
}
|
||||
|
||||
// Size returns the size of the set.
|
||||
@ -145,11 +157,10 @@ func (set *StrSet) Size() int {
|
||||
}
|
||||
|
||||
// Clear deletes all items of the set.
|
||||
func (set *StrSet) Clear() *StrSet {
|
||||
func (set *StrSet) Clear() {
|
||||
set.mu.Lock()
|
||||
set.data = make(map[string]struct{})
|
||||
set.mu.Unlock()
|
||||
return set
|
||||
}
|
||||
|
||||
// Slice returns the a of items of the set as slice.
|
||||
|
@ -13,6 +13,8 @@ import (
|
||||
"github.com/gogf/gf/frame/g"
|
||||
"github.com/gogf/gf/util/gconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/container/garray"
|
||||
"github.com/gogf/gf/container/gset"
|
||||
@ -24,7 +26,7 @@ import (
|
||||
func TestSet_Var(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
var s gset.Set
|
||||
s.Add(1).Add(1).Add(2)
|
||||
s.Add(1, 1, 2)
|
||||
s.Add([]interface{}{3, 4}...)
|
||||
t.Assert(s.Size(), 4)
|
||||
t.AssertIN(1, s.Slice())
|
||||
@ -44,7 +46,7 @@ func TestSet_Var(t *testing.T) {
|
||||
func TestSet_New(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s := gset.New()
|
||||
s.Add(1).Add(1).Add(2)
|
||||
s.Add(1, 1, 2)
|
||||
s.Add([]interface{}{3, 4}...)
|
||||
t.Assert(s.Size(), 4)
|
||||
t.AssertIN(1, s.Slice())
|
||||
@ -64,7 +66,7 @@ func TestSet_New(t *testing.T) {
|
||||
func TestSet_Basic(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s := gset.NewSet()
|
||||
s.Add(1).Add(1).Add(2)
|
||||
s.Add(1, 1, 2)
|
||||
s.Add([]interface{}{3, 4}...)
|
||||
t.Assert(s.Size(), 4)
|
||||
t.AssertIN(1, s.Slice())
|
||||
@ -84,7 +86,7 @@ func TestSet_Basic(t *testing.T) {
|
||||
func TestSet_Iterator(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s := gset.NewSet()
|
||||
s.Add(1).Add(2).Add(3)
|
||||
s.Add(1, 2, 3)
|
||||
t.Assert(s.Size(), 3)
|
||||
|
||||
a1 := garray.New(true)
|
||||
@ -105,7 +107,7 @@ func TestSet_Iterator(t *testing.T) {
|
||||
func TestSet_LockFunc(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s := gset.NewSet()
|
||||
s.Add(1).Add(2).Add(3)
|
||||
s.Add(1, 2, 3)
|
||||
t.Assert(s.Size(), 3)
|
||||
s.LockFunc(func(m map[interface{}]struct{}) {
|
||||
delete(m, 1)
|
||||
@ -125,9 +127,9 @@ func TestSet_Equal(t *testing.T) {
|
||||
s1 := gset.NewSet()
|
||||
s2 := gset.NewSet()
|
||||
s3 := gset.NewSet()
|
||||
s1.Add(1).Add(2).Add(3)
|
||||
s2.Add(1).Add(2).Add(3)
|
||||
s3.Add(1).Add(2).Add(3).Add(4)
|
||||
s1.Add(1, 2, 3)
|
||||
s2.Add(1, 2, 3)
|
||||
s3.Add(1, 2, 3, 4)
|
||||
t.Assert(s1.Equal(s2), true)
|
||||
t.Assert(s1.Equal(s3), false)
|
||||
})
|
||||
@ -138,9 +140,9 @@ func TestSet_IsSubsetOf(t *testing.T) {
|
||||
s1 := gset.NewSet()
|
||||
s2 := gset.NewSet()
|
||||
s3 := gset.NewSet()
|
||||
s1.Add(1).Add(2)
|
||||
s2.Add(1).Add(2).Add(3)
|
||||
s3.Add(1).Add(2).Add(3).Add(4)
|
||||
s1.Add(1, 2)
|
||||
s2.Add(1, 2, 3)
|
||||
s3.Add(1, 2, 3, 4)
|
||||
t.Assert(s1.IsSubsetOf(s2), true)
|
||||
t.Assert(s2.IsSubsetOf(s3), true)
|
||||
t.Assert(s1.IsSubsetOf(s3), true)
|
||||
@ -153,8 +155,8 @@ func TestSet_Union(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s1 := gset.NewSet()
|
||||
s2 := gset.NewSet()
|
||||
s1.Add(1).Add(2)
|
||||
s2.Add(3).Add(4)
|
||||
s1.Add(1, 2)
|
||||
s2.Add(3, 4)
|
||||
s3 := s1.Union(s2)
|
||||
t.Assert(s3.Contains(1), true)
|
||||
t.Assert(s3.Contains(2), true)
|
||||
@ -167,8 +169,8 @@ func TestSet_Diff(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s1 := gset.NewSet()
|
||||
s2 := gset.NewSet()
|
||||
s1.Add(1).Add(2).Add(3)
|
||||
s2.Add(3).Add(4).Add(5)
|
||||
s1.Add(1, 2, 3)
|
||||
s2.Add(3, 4, 5)
|
||||
s3 := s1.Diff(s2)
|
||||
t.Assert(s3.Contains(1), true)
|
||||
t.Assert(s3.Contains(2), true)
|
||||
@ -181,8 +183,8 @@ func TestSet_Intersect(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s1 := gset.NewSet()
|
||||
s2 := gset.NewSet()
|
||||
s1.Add(1).Add(2).Add(3)
|
||||
s2.Add(3).Add(4).Add(5)
|
||||
s1.Add(1, 2, 3)
|
||||
s2.Add(3, 4, 5)
|
||||
s3 := s1.Intersect(s2)
|
||||
t.Assert(s3.Contains(1), false)
|
||||
t.Assert(s3.Contains(2), false)
|
||||
@ -195,8 +197,8 @@ func TestSet_Complement(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s1 := gset.NewSet()
|
||||
s2 := gset.NewSet()
|
||||
s1.Add(1).Add(2).Add(3)
|
||||
s2.Add(3).Add(4).Add(5)
|
||||
s1.Add(1, 2, 3)
|
||||
s2.Add(3, 4, 5)
|
||||
s3 := s1.Complement(s2)
|
||||
t.Assert(s3.Contains(1), false)
|
||||
t.Assert(s3.Contains(2), false)
|
||||
@ -223,9 +225,9 @@ func TestNewFrom(t *testing.T) {
|
||||
func TestNew(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s1 := gset.New()
|
||||
s1.Add("a").Add(2)
|
||||
s1.Add("a", 2)
|
||||
s2 := gset.New(true)
|
||||
s2.Add("b").Add(3)
|
||||
s2.Add("b", 3)
|
||||
t.Assert(s1.Contains("a"), true)
|
||||
|
||||
})
|
||||
@ -234,13 +236,13 @@ func TestNew(t *testing.T) {
|
||||
func TestSet_Join(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s1 := gset.New(true)
|
||||
s1.Add("a").Add("a1").Add("b").Add("c")
|
||||
s1.Add("a", "a1", "b", "c")
|
||||
str1 := s1.Join(",")
|
||||
t.Assert(strings.Contains(str1, "a1"), true)
|
||||
})
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s1 := gset.New(true)
|
||||
s1.Add("a").Add(`"b"`).Add(`\c`)
|
||||
s1.Add("a", `"b"`, `\c`)
|
||||
str1 := s1.Join(",")
|
||||
t.Assert(strings.Contains(str1, `"b"`), true)
|
||||
t.Assert(strings.Contains(str1, `\c`), true)
|
||||
@ -251,7 +253,7 @@ func TestSet_Join(t *testing.T) {
|
||||
func TestSet_String(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s1 := gset.New(true)
|
||||
s1.Add("a").Add("a2").Add("b").Add("c")
|
||||
s1.Add("a", "a2", "b", "c")
|
||||
str1 := s1.String()
|
||||
t.Assert(strings.Contains(str1, "["), true)
|
||||
t.Assert(strings.Contains(str1, "]"), true)
|
||||
@ -263,8 +265,8 @@ func TestSet_Merge(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s1 := gset.New(true)
|
||||
s2 := gset.New(true)
|
||||
s1.Add("a").Add("a2").Add("b").Add("c")
|
||||
s2.Add("b").Add("b1").Add("e").Add("f")
|
||||
s1.Add("a", "a2", "b", "c")
|
||||
s2.Add("b", "b1", "e", "f")
|
||||
ss := s1.Merge(s2)
|
||||
t.Assert(ss.Contains("a2"), true)
|
||||
t.Assert(ss.Contains("b1"), true)
|
||||
@ -275,7 +277,7 @@ func TestSet_Merge(t *testing.T) {
|
||||
func TestSet_Sum(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s1 := gset.New(true)
|
||||
s1.Add(1).Add(2).Add(3).Add(4)
|
||||
s1.Add(1, 2, 3, 4)
|
||||
t.Assert(s1.Sum(), int(10))
|
||||
|
||||
})
|
||||
@ -284,7 +286,7 @@ func TestSet_Sum(t *testing.T) {
|
||||
func TestSet_Pop(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s := gset.New(true)
|
||||
s.Add(1).Add(2).Add(3).Add(4)
|
||||
s.Add(1, 2, 3, 4)
|
||||
t.Assert(s.Size(), 4)
|
||||
t.AssertIN(s.Pop(), []int{1, 2, 3, 4})
|
||||
t.Assert(s.Size(), 3)
|
||||
@ -294,7 +296,7 @@ func TestSet_Pop(t *testing.T) {
|
||||
func TestSet_Pops(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s := gset.New(true)
|
||||
s.Add(1).Add(2).Add(3).Add(4)
|
||||
s.Add(1, 2, 3, 4)
|
||||
t.Assert(s.Size(), 4)
|
||||
t.Assert(s.Pops(0), nil)
|
||||
t.AssertIN(s.Pops(1), []int{1, 2, 3, 4})
|
||||
@ -344,43 +346,71 @@ func TestSet_Json(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestSet_AddIfNotExist(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s := gset.New(true)
|
||||
s.Add(1)
|
||||
t.Assert(s.Contains(1), true)
|
||||
t.Assert(s.AddIfNotExist(1), false)
|
||||
t.Assert(s.AddIfNotExist(2), true)
|
||||
t.Assert(s.Contains(2), true)
|
||||
t.Assert(s.AddIfNotExist(2), false)
|
||||
t.Assert(s.Contains(2), true)
|
||||
})
|
||||
}
|
||||
|
||||
func TestSet_AddIfNotExistFunc(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s := gset.New(true)
|
||||
s.Add(1)
|
||||
t.Assert(s.Contains(1), true)
|
||||
t.Assert(s.Contains(2), false)
|
||||
|
||||
s.AddIfNotExistFunc(2, func() interface{} {
|
||||
return 3
|
||||
})
|
||||
t.Assert(s.AddIfNotExistFunc(2, func() bool { return false }), false)
|
||||
t.Assert(s.Contains(2), false)
|
||||
t.Assert(s.Contains(3), true)
|
||||
|
||||
s.AddIfNotExistFunc(3, func() interface{} {
|
||||
return 4
|
||||
})
|
||||
t.Assert(s.Contains(3), true)
|
||||
t.Assert(s.Contains(4), false)
|
||||
t.Assert(s.AddIfNotExistFunc(2, func() bool { return true }), true)
|
||||
t.Assert(s.Contains(2), true)
|
||||
t.Assert(s.AddIfNotExistFunc(2, func() bool { return true }), false)
|
||||
t.Assert(s.Contains(2), true)
|
||||
})
|
||||
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s := gset.New(true)
|
||||
wg := sync.WaitGroup{}
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
r := s.AddIfNotExistFunc(1, func() bool {
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
return true
|
||||
})
|
||||
t.Assert(r, false)
|
||||
}()
|
||||
s.Add(1)
|
||||
t.Assert(s.Contains(1), true)
|
||||
t.Assert(s.Contains(2), false)
|
||||
wg.Wait()
|
||||
})
|
||||
}
|
||||
|
||||
s.AddIfNotExistFuncLock(2, func() interface{} {
|
||||
return 3
|
||||
})
|
||||
t.Assert(s.Contains(2), false)
|
||||
t.Assert(s.Contains(3), true)
|
||||
|
||||
s.AddIfNotExistFuncLock(3, func() interface{} {
|
||||
return 4
|
||||
})
|
||||
t.Assert(s.Contains(3), true)
|
||||
t.Assert(s.Contains(4), false)
|
||||
func TestSet_AddIfNotExistFuncLock(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s := gset.New(true)
|
||||
wg := sync.WaitGroup{}
|
||||
wg.Add(2)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
r := s.AddIfNotExistFuncLock(1, func() bool {
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
return true
|
||||
})
|
||||
t.Assert(r, true)
|
||||
}()
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
r := s.AddIfNotExistFuncLock(1, func() bool {
|
||||
return true
|
||||
})
|
||||
t.Assert(r, false)
|
||||
}()
|
||||
wg.Wait()
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,9 @@ import (
|
||||
"github.com/gogf/gf/frame/g"
|
||||
"github.com/gogf/gf/util/gconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/container/garray"
|
||||
"github.com/gogf/gf/container/gset"
|
||||
@ -23,7 +25,7 @@ import (
|
||||
func TestIntSet_Var(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
var s gset.IntSet
|
||||
s.Add(1).Add(1).Add(2)
|
||||
s.Add(1, 1, 2)
|
||||
s.Add([]int{3, 4}...)
|
||||
t.Assert(s.Size(), 4)
|
||||
t.AssertIN(1, s.Slice())
|
||||
@ -43,7 +45,7 @@ func TestIntSet_Var(t *testing.T) {
|
||||
func TestIntSet_Basic(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s := gset.NewIntSet()
|
||||
s.Add(1).Add(1).Add(2)
|
||||
s.Add(1, 1, 2)
|
||||
s.Add([]int{3, 4}...)
|
||||
t.Assert(s.Size(), 4)
|
||||
t.AssertIN(1, s.Slice())
|
||||
@ -63,7 +65,7 @@ func TestIntSet_Basic(t *testing.T) {
|
||||
func TestIntSet_Iterator(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s := gset.NewIntSet()
|
||||
s.Add(1).Add(2).Add(3)
|
||||
s.Add(1, 2, 3)
|
||||
t.Assert(s.Size(), 3)
|
||||
|
||||
a1 := garray.New(true)
|
||||
@ -84,7 +86,7 @@ func TestIntSet_Iterator(t *testing.T) {
|
||||
func TestIntSet_LockFunc(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s := gset.NewIntSet()
|
||||
s.Add(1).Add(2).Add(3)
|
||||
s.Add(1, 2, 3)
|
||||
t.Assert(s.Size(), 3)
|
||||
s.LockFunc(func(m map[int]struct{}) {
|
||||
delete(m, 1)
|
||||
@ -104,9 +106,9 @@ func TestIntSet_Equal(t *testing.T) {
|
||||
s1 := gset.NewIntSet()
|
||||
s2 := gset.NewIntSet()
|
||||
s3 := gset.NewIntSet()
|
||||
s1.Add(1).Add(2).Add(3)
|
||||
s2.Add(1).Add(2).Add(3)
|
||||
s3.Add(1).Add(2).Add(3).Add(4)
|
||||
s1.Add(1, 2, 3)
|
||||
s2.Add(1, 2, 3)
|
||||
s3.Add(1, 2, 3, 4)
|
||||
t.Assert(s1.Equal(s2), true)
|
||||
t.Assert(s1.Equal(s3), false)
|
||||
})
|
||||
@ -117,9 +119,9 @@ func TestIntSet_IsSubsetOf(t *testing.T) {
|
||||
s1 := gset.NewIntSet()
|
||||
s2 := gset.NewIntSet()
|
||||
s3 := gset.NewIntSet()
|
||||
s1.Add(1).Add(2)
|
||||
s2.Add(1).Add(2).Add(3)
|
||||
s3.Add(1).Add(2).Add(3).Add(4)
|
||||
s1.Add(1, 2)
|
||||
s2.Add(1, 2, 3)
|
||||
s3.Add(1, 2, 3, 4)
|
||||
t.Assert(s1.IsSubsetOf(s2), true)
|
||||
t.Assert(s2.IsSubsetOf(s3), true)
|
||||
t.Assert(s1.IsSubsetOf(s3), true)
|
||||
@ -132,8 +134,8 @@ func TestIntSet_Union(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s1 := gset.NewIntSet()
|
||||
s2 := gset.NewIntSet()
|
||||
s1.Add(1).Add(2)
|
||||
s2.Add(3).Add(4)
|
||||
s1.Add(1, 2)
|
||||
s2.Add(3, 4)
|
||||
s3 := s1.Union(s2)
|
||||
t.Assert(s3.Contains(1), true)
|
||||
t.Assert(s3.Contains(2), true)
|
||||
@ -146,8 +148,8 @@ func TestIntSet_Diff(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s1 := gset.NewIntSet()
|
||||
s2 := gset.NewIntSet()
|
||||
s1.Add(1).Add(2).Add(3)
|
||||
s2.Add(3).Add(4).Add(5)
|
||||
s1.Add(1, 2, 3)
|
||||
s2.Add(3, 4, 5)
|
||||
s3 := s1.Diff(s2)
|
||||
t.Assert(s3.Contains(1), true)
|
||||
t.Assert(s3.Contains(2), true)
|
||||
@ -160,8 +162,8 @@ func TestIntSet_Intersect(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s1 := gset.NewIntSet()
|
||||
s2 := gset.NewIntSet()
|
||||
s1.Add(1).Add(2).Add(3)
|
||||
s2.Add(3).Add(4).Add(5)
|
||||
s1.Add(1, 2, 3)
|
||||
s2.Add(3, 4, 5)
|
||||
s3 := s1.Intersect(s2)
|
||||
t.Assert(s3.Contains(1), false)
|
||||
t.Assert(s3.Contains(2), false)
|
||||
@ -174,8 +176,8 @@ func TestIntSet_Complement(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s1 := gset.NewIntSet()
|
||||
s2 := gset.NewIntSet()
|
||||
s1.Add(1).Add(2).Add(3)
|
||||
s2.Add(3).Add(4).Add(5)
|
||||
s1.Add(1, 2, 3)
|
||||
s2.Add(3, 4, 5)
|
||||
s3 := s1.Complement(s2)
|
||||
t.Assert(s3.Contains(1), false)
|
||||
t.Assert(s3.Contains(2), false)
|
||||
@ -187,7 +189,7 @@ func TestIntSet_Complement(t *testing.T) {
|
||||
func TestIntSet_Size(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s1 := gset.NewIntSet(true)
|
||||
s1.Add(1).Add(2).Add(3)
|
||||
s1.Add(1, 2, 3)
|
||||
t.Assert(s1.Size(), 3)
|
||||
|
||||
})
|
||||
@ -198,8 +200,8 @@ func TestIntSet_Merge(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s1 := gset.NewIntSet()
|
||||
s2 := gset.NewIntSet()
|
||||
s1.Add(1).Add(2).Add(3)
|
||||
s2.Add(3).Add(4).Add(5)
|
||||
s1.Add(1, 2, 3)
|
||||
s2.Add(3, 4, 5)
|
||||
s3 := s1.Merge(s2)
|
||||
t.Assert(s3.Contains(1), true)
|
||||
t.Assert(s3.Contains(5), true)
|
||||
@ -210,7 +212,7 @@ func TestIntSet_Merge(t *testing.T) {
|
||||
func TestIntSet_Join(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s1 := gset.NewIntSet()
|
||||
s1.Add(1).Add(2).Add(3)
|
||||
s1.Add(1, 2, 3)
|
||||
s3 := s1.Join(",")
|
||||
t.Assert(strings.Contains(s3, "1"), true)
|
||||
t.Assert(strings.Contains(s3, "2"), true)
|
||||
@ -221,7 +223,7 @@ func TestIntSet_Join(t *testing.T) {
|
||||
func TestIntSet_String(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s1 := gset.NewIntSet()
|
||||
s1.Add(1).Add(2).Add(3)
|
||||
s1.Add(1, 2, 3)
|
||||
s3 := s1.String()
|
||||
t.Assert(strings.Contains(s3, "["), true)
|
||||
t.Assert(strings.Contains(s3, "]"), true)
|
||||
@ -234,9 +236,9 @@ func TestIntSet_String(t *testing.T) {
|
||||
func TestIntSet_Sum(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s1 := gset.NewIntSet()
|
||||
s1.Add(1).Add(2).Add(3)
|
||||
s1.Add(1, 2, 3)
|
||||
s2 := gset.NewIntSet()
|
||||
s2.Add(5).Add(6).Add(7)
|
||||
s2.Add(5, 6, 7)
|
||||
t.Assert(s2.Sum(), 18)
|
||||
|
||||
})
|
||||
@ -246,7 +248,7 @@ func TestIntSet_Sum(t *testing.T) {
|
||||
func TestIntSet_Pop(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s := gset.NewIntSet()
|
||||
s.Add(4).Add(2).Add(3)
|
||||
s.Add(4, 2, 3)
|
||||
t.Assert(s.Size(), 3)
|
||||
t.AssertIN(s.Pop(), []int{4, 2, 3})
|
||||
t.AssertIN(s.Pop(), []int{4, 2, 3})
|
||||
@ -257,7 +259,7 @@ func TestIntSet_Pop(t *testing.T) {
|
||||
func TestIntSet_Pops(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s := gset.NewIntSet()
|
||||
s.Add(1).Add(4).Add(2).Add(3)
|
||||
s.Add(1, 4, 2, 3)
|
||||
t.Assert(s.Size(), 4)
|
||||
t.Assert(s.Pops(0), nil)
|
||||
t.AssertIN(s.Pops(1), []int{1, 4, 2, 3})
|
||||
@ -278,6 +280,74 @@ func TestIntSet_Pops(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestIntSet_AddIfNotExist(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s := gset.NewIntSet(true)
|
||||
s.Add(1)
|
||||
t.Assert(s.Contains(1), true)
|
||||
t.Assert(s.AddIfNotExist(1), false)
|
||||
t.Assert(s.AddIfNotExist(2), true)
|
||||
t.Assert(s.Contains(2), true)
|
||||
t.Assert(s.AddIfNotExist(2), false)
|
||||
t.Assert(s.Contains(2), true)
|
||||
})
|
||||
}
|
||||
|
||||
func TestIntSet_AddIfNotExistFunc(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s := gset.NewIntSet(true)
|
||||
s.Add(1)
|
||||
t.Assert(s.Contains(1), true)
|
||||
t.Assert(s.Contains(2), false)
|
||||
t.Assert(s.AddIfNotExistFunc(2, func() bool { return false }), false)
|
||||
t.Assert(s.Contains(2), false)
|
||||
t.Assert(s.AddIfNotExistFunc(2, func() bool { return true }), true)
|
||||
t.Assert(s.Contains(2), true)
|
||||
t.Assert(s.AddIfNotExistFunc(2, func() bool { return true }), false)
|
||||
t.Assert(s.Contains(2), true)
|
||||
})
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s := gset.NewIntSet(true)
|
||||
wg := sync.WaitGroup{}
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
r := s.AddIfNotExistFunc(1, func() bool {
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
return true
|
||||
})
|
||||
t.Assert(r, false)
|
||||
}()
|
||||
s.Add(1)
|
||||
wg.Wait()
|
||||
})
|
||||
}
|
||||
|
||||
func TestIntSet_AddIfNotExistFuncLock(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s := gset.NewIntSet(true)
|
||||
wg := sync.WaitGroup{}
|
||||
wg.Add(2)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
r := s.AddIfNotExistFuncLock(1, func() bool {
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
return true
|
||||
})
|
||||
t.Assert(r, true)
|
||||
}()
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
r := s.AddIfNotExistFuncLock(1, func() bool {
|
||||
return true
|
||||
})
|
||||
t.Assert(r, false)
|
||||
}()
|
||||
wg.Wait()
|
||||
})
|
||||
}
|
||||
|
||||
func TestIntSet_Json(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s1 := []int{1, 3, 2, 4}
|
||||
@ -307,46 +377,6 @@ func TestIntSet_Json(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestIntSet_AddIfNotExistFunc(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s := gset.NewIntSet(true)
|
||||
s.Add(1)
|
||||
t.Assert(s.Contains(1), true)
|
||||
t.Assert(s.Contains(2), false)
|
||||
|
||||
s.AddIfNotExistFunc(2, func() int {
|
||||
return 3
|
||||
})
|
||||
t.Assert(s.Contains(2), false)
|
||||
t.Assert(s.Contains(3), true)
|
||||
|
||||
s.AddIfNotExistFunc(3, func() int {
|
||||
return 4
|
||||
})
|
||||
t.Assert(s.Contains(3), true)
|
||||
t.Assert(s.Contains(4), false)
|
||||
})
|
||||
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s := gset.NewIntSet(true)
|
||||
s.Add(1)
|
||||
t.Assert(s.Contains(1), true)
|
||||
t.Assert(s.Contains(2), false)
|
||||
|
||||
s.AddIfNotExistFuncLock(2, func() int {
|
||||
return 3
|
||||
})
|
||||
t.Assert(s.Contains(2), false)
|
||||
t.Assert(s.Contains(3), true)
|
||||
|
||||
s.AddIfNotExistFuncLock(3, func() int {
|
||||
return 4
|
||||
})
|
||||
t.Assert(s.Contains(3), true)
|
||||
t.Assert(s.Contains(4), false)
|
||||
})
|
||||
}
|
||||
|
||||
func TestIntSet_UnmarshalValue(t *testing.T) {
|
||||
type V struct {
|
||||
Name string
|
||||
|
@ -13,7 +13,9 @@ import (
|
||||
"github.com/gogf/gf/frame/g"
|
||||
"github.com/gogf/gf/util/gconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/container/garray"
|
||||
"github.com/gogf/gf/container/gset"
|
||||
@ -23,7 +25,7 @@ import (
|
||||
func TestStrSet_Var(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
var s gset.StrSet
|
||||
s.Add("1").Add("1").Add("2")
|
||||
s.Add("1", "1", "2")
|
||||
s.Add([]string{"3", "4"}...)
|
||||
t.Assert(s.Size(), 4)
|
||||
t.AssertIN("1", s.Slice())
|
||||
@ -43,7 +45,7 @@ func TestStrSet_Var(t *testing.T) {
|
||||
func TestStrSet_Basic(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s := gset.NewStrSet()
|
||||
s.Add("1").Add("1").Add("2")
|
||||
s.Add("1", "1", "2")
|
||||
s.Add([]string{"3", "4"}...)
|
||||
t.Assert(s.Size(), 4)
|
||||
t.AssertIN("1", s.Slice())
|
||||
@ -63,7 +65,7 @@ func TestStrSet_Basic(t *testing.T) {
|
||||
func TestStrSet_Iterator(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s := gset.NewStrSet()
|
||||
s.Add("1").Add("2").Add("3")
|
||||
s.Add("1", "2", "3")
|
||||
t.Assert(s.Size(), 3)
|
||||
|
||||
a1 := garray.New(true)
|
||||
@ -84,7 +86,7 @@ func TestStrSet_Iterator(t *testing.T) {
|
||||
func TestStrSet_LockFunc(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s := gset.NewStrSet()
|
||||
s.Add("1").Add("2").Add("3")
|
||||
s.Add("1", "2", "3")
|
||||
t.Assert(s.Size(), 3)
|
||||
s.LockFunc(func(m map[string]struct{}) {
|
||||
delete(m, "1")
|
||||
@ -104,9 +106,9 @@ func TestStrSet_Equal(t *testing.T) {
|
||||
s1 := gset.NewStrSet()
|
||||
s2 := gset.NewStrSet()
|
||||
s3 := gset.NewStrSet()
|
||||
s1.Add("1").Add("2").Add("3")
|
||||
s2.Add("1").Add("2").Add("3")
|
||||
s3.Add("1").Add("2").Add("3").Add("4")
|
||||
s1.Add("1", "2", "3")
|
||||
s2.Add("1", "2", "3")
|
||||
s3.Add("1", "2", "3", "4")
|
||||
t.Assert(s1.Equal(s2), true)
|
||||
t.Assert(s1.Equal(s3), false)
|
||||
})
|
||||
@ -117,9 +119,9 @@ func TestStrSet_IsSubsetOf(t *testing.T) {
|
||||
s1 := gset.NewStrSet()
|
||||
s2 := gset.NewStrSet()
|
||||
s3 := gset.NewStrSet()
|
||||
s1.Add("1").Add("2")
|
||||
s2.Add("1").Add("2").Add("3")
|
||||
s3.Add("1").Add("2").Add("3").Add("4")
|
||||
s1.Add("1", "2")
|
||||
s2.Add("1", "2", "3")
|
||||
s3.Add("1", "2", "3", "4")
|
||||
t.Assert(s1.IsSubsetOf(s2), true)
|
||||
t.Assert(s2.IsSubsetOf(s3), true)
|
||||
t.Assert(s1.IsSubsetOf(s3), true)
|
||||
@ -132,8 +134,8 @@ func TestStrSet_Union(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s1 := gset.NewStrSet()
|
||||
s2 := gset.NewStrSet()
|
||||
s1.Add("1").Add("2")
|
||||
s2.Add("3").Add("4")
|
||||
s1.Add("1", "2")
|
||||
s2.Add("3", "4")
|
||||
s3 := s1.Union(s2)
|
||||
t.Assert(s3.Contains("1"), true)
|
||||
t.Assert(s3.Contains("2"), true)
|
||||
@ -146,8 +148,8 @@ func TestStrSet_Diff(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s1 := gset.NewStrSet()
|
||||
s2 := gset.NewStrSet()
|
||||
s1.Add("1").Add("2").Add("3")
|
||||
s2.Add("3").Add("4").Add("5")
|
||||
s1.Add("1", "2", "3")
|
||||
s2.Add("3", "4", "5")
|
||||
s3 := s1.Diff(s2)
|
||||
t.Assert(s3.Contains("1"), true)
|
||||
t.Assert(s3.Contains("2"), true)
|
||||
@ -160,8 +162,8 @@ func TestStrSet_Intersect(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s1 := gset.NewStrSet()
|
||||
s2 := gset.NewStrSet()
|
||||
s1.Add("1").Add("2").Add("3")
|
||||
s2.Add("3").Add("4").Add("5")
|
||||
s1.Add("1", "2", "3")
|
||||
s2.Add("3", "4", "5")
|
||||
s3 := s1.Intersect(s2)
|
||||
t.Assert(s3.Contains("1"), false)
|
||||
t.Assert(s3.Contains("2"), false)
|
||||
@ -174,8 +176,8 @@ func TestStrSet_Complement(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s1 := gset.NewStrSet()
|
||||
s2 := gset.NewStrSet()
|
||||
s1.Add("1").Add("2").Add("3")
|
||||
s2.Add("3").Add("4").Add("5")
|
||||
s1.Add("1", "2", "3")
|
||||
s2.Add("3", "4", "5")
|
||||
s3 := s1.Complement(s2)
|
||||
t.Assert(s3.Contains("1"), false)
|
||||
t.Assert(s3.Contains("2"), false)
|
||||
@ -199,8 +201,8 @@ func TestStrSet_Merge(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s1 := gset.NewStrSet()
|
||||
s2 := gset.NewStrSet()
|
||||
s1.Add("1").Add("2").Add("3")
|
||||
s2.Add("3").Add("4").Add("5")
|
||||
s1.Add("1", "2", "3")
|
||||
s2.Add("3", "4", "5")
|
||||
s3 := s1.Merge(s2)
|
||||
t.Assert(s3.Contains("1"), true)
|
||||
t.Assert(s3.Contains("6"), false)
|
||||
@ -227,7 +229,7 @@ func TestStrSet_Join(t *testing.T) {
|
||||
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s1 := gset.NewStrSet()
|
||||
s1.Add("a").Add(`"b"`).Add(`\c`)
|
||||
s1.Add("a", `"b"`, `\c`)
|
||||
str1 := s1.Join(",")
|
||||
t.Assert(strings.Contains(str1, `"b"`), true)
|
||||
t.Assert(strings.Contains(str1, `\c`), true)
|
||||
@ -245,7 +247,7 @@ func TestStrSet_String(t *testing.T) {
|
||||
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s1 := gset.New(true)
|
||||
s1.Add("a").Add("a2").Add("b").Add("c")
|
||||
s1.Add("a", "a2", "b", "c")
|
||||
str1 := s1.String()
|
||||
t.Assert(strings.Contains(str1, "["), true)
|
||||
t.Assert(strings.Contains(str1, "]"), true)
|
||||
@ -273,7 +275,7 @@ func TestStrSet_Size(t *testing.T) {
|
||||
func TestStrSet_Remove(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s1 := gset.NewStrSetFrom([]string{"a", "b", "c"}, true)
|
||||
s1 = s1.Remove("b")
|
||||
s1.Remove("b")
|
||||
t.Assert(s1.Contains("b"), false)
|
||||
t.Assert(s1.Contains("c"), true)
|
||||
})
|
||||
@ -314,6 +316,74 @@ func TestStrSet_Pops(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestStrSet_AddIfNotExist(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s := gset.NewStrSet(true)
|
||||
s.Add("1")
|
||||
t.Assert(s.Contains("1"), true)
|
||||
t.Assert(s.AddIfNotExist("1"), false)
|
||||
t.Assert(s.AddIfNotExist("2"), true)
|
||||
t.Assert(s.Contains("2"), true)
|
||||
t.Assert(s.AddIfNotExist("2"), false)
|
||||
t.Assert(s.Contains("2"), true)
|
||||
})
|
||||
}
|
||||
|
||||
func TestStrSet_AddIfNotExistFunc(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s := gset.NewStrSet(true)
|
||||
s.Add("1")
|
||||
t.Assert(s.Contains("1"), true)
|
||||
t.Assert(s.Contains("2"), false)
|
||||
t.Assert(s.AddIfNotExistFunc("2", func() bool { return false }), false)
|
||||
t.Assert(s.Contains("2"), false)
|
||||
t.Assert(s.AddIfNotExistFunc("2", func() bool { return true }), true)
|
||||
t.Assert(s.Contains("2"), true)
|
||||
t.Assert(s.AddIfNotExistFunc("2", func() bool { return true }), false)
|
||||
t.Assert(s.Contains("2"), true)
|
||||
})
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s := gset.NewStrSet(true)
|
||||
wg := sync.WaitGroup{}
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
r := s.AddIfNotExistFunc("1", func() bool {
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
return true
|
||||
})
|
||||
t.Assert(r, false)
|
||||
}()
|
||||
s.Add("1")
|
||||
wg.Wait()
|
||||
})
|
||||
}
|
||||
|
||||
func TestStrSet_AddIfNotExistFuncLock(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s := gset.NewStrSet(true)
|
||||
wg := sync.WaitGroup{}
|
||||
wg.Add(2)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
r := s.AddIfNotExistFuncLock("1", func() bool {
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
return true
|
||||
})
|
||||
t.Assert(r, true)
|
||||
}()
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
r := s.AddIfNotExistFuncLock("1", func() bool {
|
||||
return true
|
||||
})
|
||||
t.Assert(r, false)
|
||||
}()
|
||||
wg.Wait()
|
||||
})
|
||||
}
|
||||
|
||||
func TestStrSet_Json(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s1 := []string{"a", "b", "d", "c"}
|
||||
@ -343,46 +413,6 @@ func TestStrSet_Json(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestStrSet_AddIfNotExistFunc(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s := gset.NewStrSet(true)
|
||||
s.Add("1")
|
||||
t.Assert(s.Contains("1"), true)
|
||||
t.Assert(s.Contains("2"), false)
|
||||
|
||||
s.AddIfNotExistFunc("2", func() string {
|
||||
return "3"
|
||||
})
|
||||
t.Assert(s.Contains("2"), false)
|
||||
t.Assert(s.Contains("3"), true)
|
||||
|
||||
s.AddIfNotExistFunc("3", func() string {
|
||||
return "4"
|
||||
})
|
||||
t.Assert(s.Contains("3"), true)
|
||||
t.Assert(s.Contains("4"), false)
|
||||
})
|
||||
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s := gset.NewStrSet(true)
|
||||
s.Add("1")
|
||||
t.Assert(s.Contains("1"), true)
|
||||
t.Assert(s.Contains("2"), false)
|
||||
|
||||
s.AddIfNotExistFuncLock("2", func() string {
|
||||
return "3"
|
||||
})
|
||||
t.Assert(s.Contains("2"), false)
|
||||
t.Assert(s.Contains("3"), true)
|
||||
|
||||
s.AddIfNotExistFuncLock("3", func() string {
|
||||
return "4"
|
||||
})
|
||||
t.Assert(s.Contains("3"), true)
|
||||
t.Assert(s.Contains("4"), false)
|
||||
})
|
||||
}
|
||||
|
||||
func TestStrSet_UnmarshalValue(t *testing.T) {
|
||||
type V struct {
|
||||
Name string
|
||||
|
@ -12,8 +12,8 @@ import (
|
||||
)
|
||||
|
||||
// IsEmpty checks whether given <value> empty.
|
||||
// It returns true if <value> is in: 0, nil, false, "", len(slice/map/chan) == 0.
|
||||
// Or else it returns true.
|
||||
// It returns true if <value> is in: 0, nil, false, "", len(slice/map/chan) == 0,
|
||||
// or else it returns false.
|
||||
func IsEmpty(value interface{}) bool {
|
||||
if value == nil {
|
||||
return true
|
||||
@ -49,6 +49,8 @@ func IsEmpty(value interface{}) bool {
|
||||
return value == ""
|
||||
case []byte:
|
||||
return len(value) == 0
|
||||
case []rune:
|
||||
return len(value) == 0
|
||||
default:
|
||||
// Finally using reflect.
|
||||
var rv reflect.Value
|
||||
|
@ -9,6 +9,7 @@
|
||||
package ghttp
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/internal/intlog"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
@ -26,14 +27,16 @@ func handleProcessSignal() {
|
||||
syscall.SIGQUIT,
|
||||
syscall.SIGKILL,
|
||||
syscall.SIGTERM,
|
||||
syscall.SIGABRT,
|
||||
syscall.SIGUSR1,
|
||||
syscall.SIGUSR2,
|
||||
)
|
||||
for {
|
||||
sig = <-procSignalChan
|
||||
intlog.Printf(`signal received: %s`, sig.String())
|
||||
switch sig {
|
||||
// 进程终止,停止所有子进程运行
|
||||
case syscall.SIGINT, syscall.SIGQUIT, syscall.SIGKILL, syscall.SIGTERM:
|
||||
case syscall.SIGINT, syscall.SIGQUIT, syscall.SIGKILL, syscall.SIGTERM, syscall.SIGABRT:
|
||||
shutdownWebServers(sig.String())
|
||||
return
|
||||
|
||||
|
@ -42,7 +42,7 @@ var (
|
||||
|
||||
func init() {
|
||||
// Initialize internal package variable: tempDir.
|
||||
if !Exists(tempDir) {
|
||||
if Separator == "/" && !Exists(tempDir) {
|
||||
tempDir = os.TempDir()
|
||||
}
|
||||
// Initialize internal package variable: selfPath.
|
||||
|
@ -26,11 +26,11 @@ func (w *Watcher) Add(path string, callbackFunc func(event *Event), recursive ..
|
||||
//
|
||||
// The optional parameter <recursive> specifies whether monitoring the <path> recursively, which is true in default.
|
||||
func (w *Watcher) AddOnce(name, path string, callbackFunc func(event *Event), recursive ...bool) (callback *Callback, err error) {
|
||||
w.nameSet.AddIfNotExistFuncLock(name, func() string {
|
||||
w.nameSet.AddIfNotExistFuncLock(name, func() bool {
|
||||
// Firstly add the path to watcher.
|
||||
callback, err = w.addWithCallbackFunc(name, path, callbackFunc, recursive...)
|
||||
if err != nil {
|
||||
return ""
|
||||
return false
|
||||
}
|
||||
// If it's recursive adding, it then adds all sub-folders to the monitor.
|
||||
// NOTE:
|
||||
@ -49,7 +49,7 @@ func (w *Watcher) AddOnce(name, path string, callbackFunc func(event *Event), re
|
||||
}
|
||||
}
|
||||
}
|
||||
return name
|
||||
return true
|
||||
})
|
||||
return
|
||||
}
|
||||
|
@ -116,10 +116,12 @@ func (p *Process) Kill() error {
|
||||
p.Manager.processes.Remove(p.Pid())
|
||||
}
|
||||
if runtime.GOOS != "windows" {
|
||||
p.Process.Release()
|
||||
if err = p.Process.Release(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
p.Process.Wait()
|
||||
return nil
|
||||
_, err = p.Process.Wait()
|
||||
return err
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user