diff --git a/.example/other/test.go b/.example/other/test.go index c1e9ba98d..2c8a90f3d 100644 --- a/.example/other/test.go +++ b/.example/other/test.go @@ -2,18 +2,20 @@ package main import ( "fmt" - "github.com/gogf/gf/frame/g" ) -func main() { - c := g.Client() - c.SetCookieMap(g.MapStrStr{ - "name": "john", - "score": "100", - }) - if r, e := c.Get("http://127.0.0.1:8199/"); e != nil { - panic(e) - } else { - fmt.Println(r.ReadAllString()) - } +func Test() (int, int) { + return 1, 1 +} + +func Assert(v1, v2, v3 interface{}) { + fmt.Println(v1) +} + +func F(v ...interface{}) []interface{} { + return v +} + +func main() { + Assert(F(Test()), 2, 3) } diff --git a/container/garray/garray_normal_any.go b/container/garray/garray_normal_any.go index ab2e6b059..12d952585 100644 --- a/container/garray/garray_normal_any.go +++ b/container/garray/garray_normal_any.go @@ -9,6 +9,7 @@ package garray import ( "bytes" "encoding/json" + "errors" "fmt" "github.com/gogf/gf/internal/empty" "github.com/gogf/gf/text/gstr" @@ -20,6 +21,7 @@ import ( "github.com/gogf/gf/util/grand" ) +// Array is a golang array with rich features. type Array struct { mu *rwmutex.RWMutex array []interface{} @@ -94,21 +96,26 @@ func NewArrayFromCopy(array []interface{}, safe ...bool) *Array { } } -// Get returns the value of the specified index, -// the caller should notice the boundary of the array. -func (a *Array) Get(index int) interface{} { +// Get returns the value by the specified index. +// If the given is out of range of the array, the is false. +func (a *Array) Get(index int) (value interface{}, found bool) { a.mu.RLock() defer a.mu.RUnlock() - value := a.array[index] - return value + if index < 0 || index >= len(a.array) { + return nil, false + } + return a.array[index], true } // Set sets value to specified index. -func (a *Array) Set(index int, value interface{}) *Array { +func (a *Array) Set(index int, value interface{}) error { a.mu.Lock() defer a.mu.Unlock() + if index < 0 || index >= len(a.array) { + return errors.New(fmt.Sprintf("index %d out of array range %d", index, len(a.array))) + } a.array[index] = value - return a + return nil } // SetArray sets the underlying slice array with the given . @@ -154,48 +161,60 @@ func (a *Array) SortFunc(less func(v1, v2 interface{}) bool) *Array { } // InsertBefore inserts the to the front of . -func (a *Array) InsertBefore(index int, value interface{}) *Array { - a.mu.Lock() - defer a.mu.Unlock() - rear := append([]interface{}{}, a.array[index:]...) - a.array = append(a.array[0:index], value) - a.array = append(a.array, rear...) - return a -} - -// InsertAfter inserts the to the back of . -func (a *Array) InsertAfter(index int, value interface{}) *Array { - a.mu.Lock() - defer a.mu.Unlock() - rear := append([]interface{}{}, a.array[index+1:]...) - a.array = append(a.array[0:index+1], value) - a.array = append(a.array, rear...) - return a -} - -// Remove removes an item by index. -func (a *Array) Remove(index int) interface{} { +func (a *Array) InsertBefore(index int, value interface{}) error { a.mu.Lock() defer a.mu.Unlock() if index < 0 || index >= len(a.array) { - return nil + return errors.New(fmt.Sprintf("index %d out of array range %d", index, len(a.array))) } - // Determine array boundaries when deleting to improve deletion efficiency。 + rear := append([]interface{}{}, a.array[index:]...) + a.array = append(a.array[0:index], value) + a.array = append(a.array, rear...) + return nil +} + +// InsertAfter inserts the to the back of . +func (a *Array) InsertAfter(index int, value interface{}) error { + a.mu.Lock() + defer a.mu.Unlock() + if index < 0 || index >= len(a.array) { + return errors.New(fmt.Sprintf("index %d out of array range %d", index, len(a.array))) + } + rear := append([]interface{}{}, a.array[index+1:]...) + a.array = append(a.array[0:index+1], value) + a.array = append(a.array, rear...) + return nil +} + +// Remove removes an item by index. +// If the given is out of range of the array, the is false. +func (a *Array) Remove(index int) (value interface{}, found bool) { + a.mu.Lock() + defer a.mu.Unlock() + return a.doRemoveWithoutLock(index) +} + +// doRemoveWithoutLock removes an item by index without lock. +func (a *Array) doRemoveWithoutLock(index int) (value interface{}, found bool) { + if index < 0 || index >= len(a.array) { + return nil, false + } + // Determine array boundaries when deleting to improve deletion efficiency. if index == 0 { value := a.array[0] a.array = a.array[1:] - return value + return value, true } else if index == len(a.array)-1 { value := a.array[index] a.array = a.array[:index] - return value + return value, true } // If it is a non-boundary delete, // it will involve the creation of an array, // then the deletion is less efficient. - value := a.array[index] + value = a.array[index] a.array = append(a.array[:index], a.array[index+1:]...) - return value + return value, true } // RemoveValue removes an item by value. @@ -226,64 +245,68 @@ func (a *Array) PushRight(value ...interface{}) *Array { } // PopRand randomly pops and return an item out of array. -func (a *Array) PopRand() interface{} { - return a.Remove(grand.Intn(len(a.array))) +// Note that if the array is empty, the is false. +func (a *Array) PopRand() (value interface{}, found bool) { + a.mu.Lock() + defer a.mu.Unlock() + return a.doRemoveWithoutLock(grand.Intn(len(a.array))) } // PopRands randomly pops and returns items out of array. func (a *Array) PopRands(size int) []interface{} { a.mu.Lock() defer a.mu.Unlock() - if size > len(a.array) { - size = len(a.array) - } - if size == 0 { + if size <= 0 || len(a.array) == 0 { return nil } + if size >= len(a.array) { + size = len(a.array) + } array := make([]interface{}, size) for i := 0; i < size; i++ { - index := grand.Intn(len(a.array)) - array[i] = a.array[index] - a.array = append(a.array[:index], a.array[index+1:]...) + array[i], _ = a.doRemoveWithoutLock(grand.Intn(len(a.array))) } return array } // PopLeft pops and returns an item from the beginning of array. -func (a *Array) PopLeft() interface{} { +// Note that if the array is empty, the is false. +func (a *Array) PopLeft() (value interface{}, found bool) { a.mu.Lock() defer a.mu.Unlock() if len(a.array) == 0 { - return nil + return nil, false } - value := a.array[0] + value = a.array[0] a.array = a.array[1:] - return value + return value, true } // PopRight pops and returns an item from the end of array. -func (a *Array) PopRight() interface{} { +// Note that if the array is empty, the is false. +func (a *Array) PopRight() (value interface{}, found bool) { a.mu.Lock() defer a.mu.Unlock() index := len(a.array) - 1 if index <= 0 { - return nil + return nil, false } - value := a.array[index] + value = a.array[index] a.array = a.array[:index] - return value + return value, true } // PopLefts pops and returns items from the beginning of array. func (a *Array) PopLefts(size int) []interface{} { a.mu.Lock() defer a.mu.Unlock() - length := len(a.array) - if length == 0 { + if size <= 0 || len(a.array) == 0 { return nil } - if size > length { - size = length + if size >= len(a.array) { + array := a.array + a.array = a.array[:0] + return array } value := a.array[0:size] a.array = a.array[size:] @@ -294,12 +317,14 @@ func (a *Array) PopLefts(size int) []interface{} { func (a *Array) PopRights(size int) []interface{} { a.mu.Lock() defer a.mu.Unlock() - if len(a.array) == 0 { + if size <= 0 || len(a.array) == 0 { return nil } index := len(a.array) - size - if index < 0 { - index = 0 + if index <= 0 { + array := a.array + a.array = a.array[:0] + return array } value := a.array[index:] a.array = a.array[:index] @@ -529,11 +554,11 @@ func (a *Array) Merge(array interface{}) *Array { // Fill fills an array with num entries of the value , // keys starting at the parameter. -func (a *Array) Fill(startIndex int, num int, value interface{}) *Array { +func (a *Array) Fill(startIndex int, num int, value interface{}) error { a.mu.Lock() defer a.mu.Unlock() - if startIndex < 0 { - startIndex = 0 + if startIndex < 0 || startIndex > len(a.array) { + return errors.New(fmt.Sprintf("index %d out of array range %d", startIndex, len(a.array))) } for i := startIndex; i < startIndex+num; i++ { if i > len(a.array)-1 { @@ -542,7 +567,7 @@ func (a *Array) Fill(startIndex int, num int, value interface{}) *Array { a.array[i] = value } } - return a + return nil } // Chunk splits an array into multiple arrays, @@ -596,27 +621,27 @@ func (a *Array) Pad(size int, val interface{}) *Array { } // Rand randomly returns one item from array(no deleting). -func (a *Array) Rand() interface{} { +func (a *Array) Rand() (value interface{}, found bool) { a.mu.RLock() defer a.mu.RUnlock() - return a.array[grand.Intn(len(a.array))] + if len(a.array) == 0 { + return nil, false + } + return a.array[grand.Intn(len(a.array))], true } // Rands randomly returns items from array(no deleting). func (a *Array) Rands(size int) []interface{} { a.mu.RLock() defer a.mu.RUnlock() - if size > len(a.array) { - size = len(a.array) + if size <= 0 || len(a.array) == 0 { + return nil } - n := make([]interface{}, size) - for i, v := range grand.Perm(len(a.array)) { - n[i] = a.array[v] - if i == size-1 { - break - } + array := make([]interface{}, size) + for i := 0; i < size; i++ { + array[i] = a.array[grand.Intn(len(a.array))] } - return n + return array } // Shuffle randomly shuffles the array. diff --git a/container/garray/garray_normal_int.go b/container/garray/garray_normal_int.go index 8030cd129..19f5ead97 100644 --- a/container/garray/garray_normal_int.go +++ b/container/garray/garray_normal_int.go @@ -9,6 +9,7 @@ package garray import ( "bytes" "encoding/json" + "errors" "fmt" "math" "sort" @@ -77,21 +78,26 @@ func NewIntArrayFromCopy(array []int, safe ...bool) *IntArray { } } -// Get returns the value of the specified index, -// the caller should notice the boundary of the array. -func (a *IntArray) Get(index int) int { +// Get returns the value by the specified index. +// If the given is out of range of the array, the is false. +func (a *IntArray) Get(index int) (value int, found bool) { a.mu.RLock() defer a.mu.RUnlock() - value := a.array[index] - return value + if index < 0 || index >= len(a.array) { + return 0, false + } + return a.array[index], true } // Set sets value to specified index. -func (a *IntArray) Set(index int, value int) *IntArray { +func (a *IntArray) Set(index int, value int) error { a.mu.Lock() defer a.mu.Unlock() + if index < 0 || index >= len(a.array) { + return errors.New(fmt.Sprintf("index %d out of array range %d", index, len(a.array))) + } a.array[index] = value - return a + return nil } // SetArray sets the underlying slice array with the given . @@ -127,8 +133,7 @@ func (a *IntArray) Sum() (sum int) { } // Sort sorts the array in increasing order. -// The parameter controls whether sort -// in increasing order(default) or decreasing order +// The parameter controls whether sort in increasing order(default) or decreasing order. func (a *IntArray) Sort(reverse ...bool) *IntArray { a.mu.Lock() defer a.mu.Unlock() @@ -156,57 +161,68 @@ func (a *IntArray) SortFunc(less func(v1, v2 int) bool) *IntArray { } // InsertBefore inserts the to the front of . -func (a *IntArray) InsertBefore(index int, value int) *IntArray { - a.mu.Lock() - defer a.mu.Unlock() - rear := append([]int{}, a.array[index:]...) - a.array = append(a.array[0:index], value) - a.array = append(a.array, rear...) - return a -} - -// InsertAfter inserts the to the back of . -func (a *IntArray) InsertAfter(index int, value int) *IntArray { - a.mu.Lock() - defer a.mu.Unlock() - rear := append([]int{}, a.array[index+1:]...) - a.array = append(a.array[0:index+1], value) - a.array = append(a.array, rear...) - return a -} - -// Remove removes an item by index. -// Note that if the index is out of range of array, it returns 0. -func (a *IntArray) Remove(index int) int { +func (a *IntArray) InsertBefore(index int, value int) error { a.mu.Lock() defer a.mu.Unlock() if index < 0 || index >= len(a.array) { - return 0 + return errors.New(fmt.Sprintf("index %d out of array range %d", index, len(a.array))) + } + rear := append([]int{}, a.array[index:]...) + a.array = append(a.array[0:index], value) + a.array = append(a.array, rear...) + return nil +} + +// InsertAfter inserts the to the back of . +func (a *IntArray) InsertAfter(index int, value int) error { + a.mu.Lock() + defer a.mu.Unlock() + if index < 0 || index >= len(a.array) { + return errors.New(fmt.Sprintf("index %d out of array range %d", index, len(a.array))) + } + rear := append([]int{}, a.array[index+1:]...) + a.array = append(a.array[0:index+1], value) + a.array = append(a.array, rear...) + return nil +} + +// Remove removes an item by index. +// If the given is out of range of the array, the is false. +func (a *IntArray) Remove(index int) (value int, found bool) { + a.mu.Lock() + defer a.mu.Unlock() + return a.doRemoveWithoutLock(index) +} + +// doRemoveWithoutLock removes an item by index without lock. +func (a *IntArray) doRemoveWithoutLock(index int) (value int, found bool) { + if index < 0 || index >= len(a.array) { + return 0, false } // Determine array boundaries when deleting to improve deletion efficiency. if index == 0 { value := a.array[0] a.array = a.array[1:] - return value + return value, true } else if index == len(a.array)-1 { value := a.array[index] a.array = a.array[:index] - return value + return value, true } // If it is a non-boundary delete, // it will involve the creation of an array, // then the deletion is less efficient. - value := a.array[index] + value = a.array[index] a.array = append(a.array[:index], a.array[index+1:]...) - return value + return value, true } // RemoveValue removes an item by value. // It returns true if value is found in the array, or else false if not found. func (a *IntArray) RemoveValue(value int) bool { if i := a.Search(value); i != -1 { - a.Remove(i) - return true + _, found := a.Remove(i) + return found } return false } @@ -229,72 +245,72 @@ func (a *IntArray) PushRight(value ...int) *IntArray { } // PopLeft pops and returns an item from the beginning of array. -// Note that if the array is empty, it returns 0. -// Be very careful when use this function in loop statement. -// You can use IsEmpty() of Len() == 0 checks if this array empty. -func (a *IntArray) PopLeft() int { +// Note that if the array is empty, the is false. +func (a *IntArray) PopLeft() (value int, found bool) { a.mu.Lock() defer a.mu.Unlock() if len(a.array) == 0 { - return 0 + return 0, false } - value := a.array[0] + value = a.array[0] a.array = a.array[1:] - return value + return value, true } // PopRight pops and returns an item from the end of array. -// Note that if the array is empty, it returns 0. -// Be very careful when use this function in loop statement. -// You can use IsEmpty() of Len() == 0 checks if this array empty. -func (a *IntArray) PopRight() int { +// Note that if the array is empty, the is false. +func (a *IntArray) PopRight() (value int, found bool) { a.mu.Lock() defer a.mu.Unlock() index := len(a.array) - 1 if index <= 0 { - return 0 + return 0, false } - value := a.array[index] + value = a.array[index] a.array = a.array[:index] - return value + return value, true } // PopRand randomly pops and return an item out of array. -// Be very careful when use this function in loop statement. -// You can use IsEmpty() of Len() == 0 checks if this array empty. -func (a *IntArray) PopRand() int { - return a.Remove(grand.Intn(len(a.array))) +// Note that if the array is empty, the is false. +func (a *IntArray) PopRand() (value int, found bool) { + a.mu.Lock() + defer a.mu.Unlock() + return a.doRemoveWithoutLock(grand.Intn(len(a.array))) } // PopRands randomly pops and returns items out of array. +// If the given is greater than size of the array, it returns all elements of the array. +// Note that if given <= 0 or the array is empty, it returns nil. func (a *IntArray) PopRands(size int) []int { a.mu.Lock() defer a.mu.Unlock() - if size > len(a.array) { - size = len(a.array) - } - if size == 0 { + if size <= 0 || len(a.array) == 0 { return nil } + if size >= len(a.array) { + size = len(a.array) + } array := make([]int, size) for i := 0; i < size; i++ { - index := grand.Intn(len(a.array)) - array[i] = a.array[index] - a.array = append(a.array[:index], a.array[index+1:]...) + array[i], _ = a.doRemoveWithoutLock(grand.Intn(len(a.array))) } return array } // PopLefts pops and returns items from the beginning of array. +// If the given is greater than size of the array, it returns all elements of the array. +// Note that if given <= 0 or the array is empty, it returns nil. func (a *IntArray) PopLefts(size int) []int { a.mu.Lock() defer a.mu.Unlock() - length := len(a.array) - if length == 0 { + if size <= 0 || len(a.array) == 0 { return nil } - if size > length { - size = length + if size >= len(a.array) { + array := a.array + a.array = a.array[:0] + return array } value := a.array[0:size] a.array = a.array[size:] @@ -302,15 +318,19 @@ func (a *IntArray) PopLefts(size int) []int { } // PopRights pops and returns items from the end of array. +// If the given is greater than size of the array, it returns all elements of the array. +// Note that if given <= 0 or the array is empty, it returns nil. func (a *IntArray) PopRights(size int) []int { a.mu.Lock() defer a.mu.Unlock() - if len(a.array) == 0 { + if size <= 0 || len(a.array) == 0 { return nil } index := len(a.array) - size - if index < 0 { - index = 0 + if index <= 0 { + array := a.array + a.array = a.array[:0] + return array } value := a.array[index:] a.array = a.array[:index] @@ -535,11 +555,11 @@ func (a *IntArray) Merge(array interface{}) *IntArray { // Fill fills an array with num entries of the value , // keys starting at the parameter. -func (a *IntArray) Fill(startIndex int, num int, value int) *IntArray { +func (a *IntArray) Fill(startIndex int, num int, value int) error { a.mu.Lock() defer a.mu.Unlock() - if startIndex < 0 { - startIndex = 0 + if startIndex < 0 || startIndex > len(a.array) { + return errors.New(fmt.Sprintf("index %d out of array range %d", startIndex, len(a.array))) } for i := startIndex; i < startIndex+num; i++ { if i > len(a.array)-1 { @@ -548,7 +568,7 @@ func (a *IntArray) Fill(startIndex int, num int, value int) *IntArray { a.array[i] = value } } - return a + return nil } // Chunk splits an array into multiple arrays, @@ -602,27 +622,27 @@ func (a *IntArray) Pad(size int, value int) *IntArray { } // Rand randomly returns one item from array(no deleting). -func (a *IntArray) Rand() int { +func (a *IntArray) Rand() (value int, found bool) { a.mu.RLock() defer a.mu.RUnlock() - return a.array[grand.Intn(len(a.array))] + if len(a.array) == 0 { + return 0, false + } + return a.array[grand.Intn(len(a.array))], true } // Rands randomly returns items from array(no deleting). func (a *IntArray) Rands(size int) []int { a.mu.RLock() defer a.mu.RUnlock() - if size > len(a.array) { - size = len(a.array) + if size <= 0 || len(a.array) == 0 { + return nil } - n := make([]int, size) - for i, v := range grand.Perm(len(a.array)) { - n[i] = a.array[v] - if i == size-1 { - break - } + array := make([]int, size) + for i := 0; i < size; i++ { + array[i] = a.array[grand.Intn(len(a.array))] } - return n + return array } // Shuffle randomly shuffles the array. diff --git a/container/garray/garray_normal_str.go b/container/garray/garray_normal_str.go index aaf9959ff..f2a6b7a1b 100644 --- a/container/garray/garray_normal_str.go +++ b/container/garray/garray_normal_str.go @@ -9,6 +9,8 @@ package garray import ( "bytes" "encoding/json" + "errors" + "fmt" "github.com/gogf/gf/text/gstr" "math" "sort" @@ -63,21 +65,26 @@ func NewStrArrayFromCopy(array []string, safe ...bool) *StrArray { } } -// Get returns the value of the specified index, -// the caller should notice the boundary of the array. -func (a *StrArray) Get(index int) string { +// Get returns the value by the specified index. +// If the given is out of range of the array, the is false. +func (a *StrArray) Get(index int) (value string, found bool) { a.mu.RLock() defer a.mu.RUnlock() - value := a.array[index] - return value + if index < 0 || index >= len(a.array) { + return "", false + } + return a.array[index], true } // Set sets value to specified index. -func (a *StrArray) Set(index int, value string) *StrArray { +func (a *StrArray) Set(index int, value string) error { a.mu.Lock() defer a.mu.Unlock() + if index < 0 || index >= len(a.array) { + return errors.New(fmt.Sprintf("index %d out of array range %d", index, len(a.array))) + } a.array[index] = value - return a + return nil } // SetArray sets the underlying slice array with the given . @@ -142,57 +149,68 @@ func (a *StrArray) SortFunc(less func(v1, v2 string) bool) *StrArray { } // InsertBefore inserts the to the front of . -func (a *StrArray) InsertBefore(index int, value string) *StrArray { - a.mu.Lock() - defer a.mu.Unlock() - rear := append([]string{}, a.array[index:]...) - a.array = append(a.array[0:index], value) - a.array = append(a.array, rear...) - return a -} - -// InsertAfter inserts the to the back of . -func (a *StrArray) InsertAfter(index int, value string) *StrArray { - a.mu.Lock() - defer a.mu.Unlock() - rear := append([]string{}, a.array[index+1:]...) - a.array = append(a.array[0:index+1], value) - a.array = append(a.array, rear...) - return a -} - -// Remove removes an item by index. -// Note that if the index is out of range of array, it returns an empty string. -func (a *StrArray) Remove(index int) string { +func (a *StrArray) InsertBefore(index int, value string) error { a.mu.Lock() defer a.mu.Unlock() if index < 0 || index >= len(a.array) { - return "" + return errors.New(fmt.Sprintf("index %d out of array range %d", index, len(a.array))) } - // Determine array boundaries when deleting to improve deletion efficiency。 + rear := append([]string{}, a.array[index:]...) + a.array = append(a.array[0:index], value) + a.array = append(a.array, rear...) + return nil +} + +// InsertAfter inserts the to the back of . +func (a *StrArray) InsertAfter(index int, value string) error { + a.mu.Lock() + defer a.mu.Unlock() + if index < 0 || index >= len(a.array) { + return errors.New(fmt.Sprintf("index %d out of array range %d", index, len(a.array))) + } + rear := append([]string{}, a.array[index+1:]...) + a.array = append(a.array[0:index+1], value) + a.array = append(a.array, rear...) + return nil +} + +// Remove removes an item by index. +// If the given is out of range of the array, the is false. +func (a *StrArray) Remove(index int) (value string, found bool) { + a.mu.Lock() + defer a.mu.Unlock() + return a.doRemoveWithoutLock(index) +} + +// doRemoveWithoutLock removes an item by index without lock. +func (a *StrArray) doRemoveWithoutLock(index int) (value string, found bool) { + if index < 0 || index >= len(a.array) { + return "", false + } + // Determine array boundaries when deleting to improve deletion efficiency. if index == 0 { value := a.array[0] a.array = a.array[1:] - return value + return value, true } else if index == len(a.array)-1 { value := a.array[index] a.array = a.array[:index] - return value + return value, true } // If it is a non-boundary delete, // it will involve the creation of an array, // then the deletion is less efficient. - value := a.array[index] + value = a.array[index] a.array = append(a.array[:index], a.array[index+1:]...) - return value + return value, true } // RemoveValue removes an item by value. // It returns true if value is found in the array, or else false if not found. func (a *StrArray) RemoveValue(value string) bool { if i := a.Search(value); i != -1 { - a.Remove(i) - return true + _, found := a.Remove(i) + return found } return false } @@ -215,89 +233,92 @@ func (a *StrArray) PushRight(value ...string) *StrArray { } // PopLeft pops and returns an item from the beginning of array. -// Note that if the array is empty, it returns an empty string. -// Be very careful when use this function in loop statement. -// You can use IsEmpty() of Len() == 0 checks if this array empty. -func (a *StrArray) PopLeft() string { +// Note that if the array is empty, the is false. +func (a *StrArray) PopLeft() (value string, found bool) { a.mu.Lock() defer a.mu.Unlock() if len(a.array) == 0 { - return "" + return "", false } - value := a.array[0] + value = a.array[0] a.array = a.array[1:] - return value + return value, true } // PopRight pops and returns an item from the end of array. -// Note that if the array is empty, it returns an empty string. -// Be very careful when use this function in loop statement. -// You can use IsEmpty() of Len() == 0 checks if this array empty. -func (a *StrArray) PopRight() string { +// Note that if the array is empty, the is false. +func (a *StrArray) PopRight() (value string, found bool) { a.mu.Lock() defer a.mu.Unlock() index := len(a.array) - 1 if index <= 0 { - return "" + return "", false } - value := a.array[index] + value = a.array[index] a.array = a.array[:index] - return value + return value, true } // PopRand randomly pops and return an item out of array. -// Note that if the array is empty, it returns an empty string. -// Be very careful when use this function in loop statement. -// You can use IsEmpty() of Len() == 0 checks if this array empty. -func (a *StrArray) PopRand() string { - return a.Remove(grand.Intn(len(a.array))) +// Note that if the array is empty, the is false. +func (a *StrArray) PopRand() (value string, found bool) { + a.mu.Lock() + defer a.mu.Unlock() + return a.doRemoveWithoutLock(grand.Intn(len(a.array))) } // PopRands randomly pops and returns items out of array. +// If the given is greater than size of the array, it returns all elements of the array. +// Note that if given <= 0 or the array is empty, it returns nil. func (a *StrArray) PopRands(size int) []string { a.mu.Lock() defer a.mu.Unlock() - if size > len(a.array) { - size = len(a.array) - } - if size == 0 { + if size <= 0 || len(a.array) == 0 { return nil } + if size >= len(a.array) { + size = len(a.array) + } array := make([]string, size) for i := 0; i < size; i++ { - index := grand.Intn(len(a.array)) - array[i] = a.array[index] - a.array = append(a.array[:index], a.array[index+1:]...) + array[i], _ = a.doRemoveWithoutLock(grand.Intn(len(a.array))) } return array } // PopLefts pops and returns items from the beginning of array. +// If the given is greater than size of the array, it returns all elements of the array. +// Note that if given <= 0 or the array is empty, it returns nil. func (a *StrArray) PopLefts(size int) []string { a.mu.Lock() defer a.mu.Unlock() - length := len(a.array) - if size > length { - size = length - } - if size == 0 { + if size <= 0 || len(a.array) == 0 { return nil } + if size >= len(a.array) { + array := a.array + a.array = a.array[:0] + return array + } value := a.array[0:size] a.array = a.array[size:] return value } // PopRights pops and returns items from the end of array. +// If the given is greater than size of the array, it returns all elements of the array. +// Note that if given <= 0 or the array is empty, it returns nil. func (a *StrArray) PopRights(size int) []string { a.mu.Lock() defer a.mu.Unlock() - if len(a.array) == 0 { + if size <= 0 || len(a.array) == 0 { return nil } index := len(a.array) - size - if index < 0 { - index = 0 + if index <= 0 { + array := a.array + a.array = a.array[:0] + return array } value := a.array[index:] a.array = a.array[:index] @@ -525,11 +546,11 @@ func (a *StrArray) Merge(array interface{}) *StrArray { // Fill fills an array with num entries of the value , // keys starting at the parameter. -func (a *StrArray) Fill(startIndex int, num int, value string) *StrArray { +func (a *StrArray) Fill(startIndex int, num int, value string) error { a.mu.Lock() defer a.mu.Unlock() - if startIndex < 0 { - startIndex = 0 + if startIndex < 0 || startIndex > len(a.array) { + return errors.New(fmt.Sprintf("index %d out of array range %d", startIndex, len(a.array))) } for i := startIndex; i < startIndex+num; i++ { if i > len(a.array)-1 { @@ -538,7 +559,7 @@ func (a *StrArray) Fill(startIndex int, num int, value string) *StrArray { a.array[i] = value } } - return a + return nil } // Chunk splits an array into multiple arrays, @@ -592,27 +613,27 @@ func (a *StrArray) Pad(size int, value string) *StrArray { } // Rand randomly returns one item from array(no deleting). -func (a *StrArray) Rand() string { +func (a *StrArray) Rand() (value string, found bool) { a.mu.RLock() defer a.mu.RUnlock() - return a.array[grand.Intn(len(a.array))] + if len(a.array) == 0 { + return "", false + } + return a.array[grand.Intn(len(a.array))], true } // Rands randomly returns items from array(no deleting). func (a *StrArray) Rands(size int) []string { a.mu.RLock() defer a.mu.RUnlock() - if size > len(a.array) { - size = len(a.array) + if size <= 0 || len(a.array) == 0 { + return nil } - n := make([]string, size) - for i, v := range grand.Perm(len(a.array)) { - n[i] = a.array[v] - if i == size-1 { - break - } + array := make([]string, size) + for i := 0; i < size; i++ { + array[i] = a.array[grand.Intn(len(a.array))] } - return n + return array } // Shuffle randomly shuffles the array. diff --git a/container/garray/garray_sorted_any.go b/container/garray/garray_sorted_any.go index 536b28a83..9ea9d71b6 100644 --- a/container/garray/garray_sorted_any.go +++ b/container/garray/garray_sorted_any.go @@ -148,38 +148,46 @@ func (a *SortedArray) Add(values ...interface{}) *SortedArray { return a } -// Get returns the value of the specified index, -// the caller should notice the boundary of the array. -func (a *SortedArray) Get(index int) interface{} { +// Get returns the value by the specified index. +// If the given is out of range of the array, the is false. +func (a *SortedArray) Get(index int) (value interface{}, found bool) { a.mu.RLock() defer a.mu.RUnlock() - value := a.array[index] - return value + if index < 0 || index >= len(a.array) { + return nil, false + } + return a.array[index], true } // Remove removes an item by index. -func (a *SortedArray) Remove(index int) interface{} { +// If the given is out of range of the array, the is false. +func (a *SortedArray) Remove(index int) (value interface{}, found bool) { a.mu.Lock() defer a.mu.Unlock() + return a.doRemoveWithoutLock(index) +} + +// doRemoveWithoutLock removes an item by index without lock. +func (a *SortedArray) doRemoveWithoutLock(index int) (value interface{}, found bool) { if index < 0 || index >= len(a.array) { - return nil + return nil, false } // Determine array boundaries when deleting to improve deletion efficiency. if index == 0 { value := a.array[0] a.array = a.array[1:] - return value + return value, true } else if index == len(a.array)-1 { value := a.array[index] a.array = a.array[:index] - return value + return value, true } // If it is a non-boundary delete, // it will involve the creation of an array, // then the deletion is less efficient. - value := a.array[index] + value = a.array[index] a.array = append(a.array[:index], a.array[index+1:]...) - return value + return value, true } // RemoveValue removes an item by value. @@ -193,50 +201,53 @@ func (a *SortedArray) RemoveValue(value interface{}) bool { } // PopLeft pops and returns an item from the beginning of array. -func (a *SortedArray) PopLeft() interface{} { +// Note that if the array is empty, the is false. +func (a *SortedArray) PopLeft() (value interface{}, found bool) { a.mu.Lock() defer a.mu.Unlock() if len(a.array) == 0 { - return nil + return nil, false } - value := a.array[0] + value = a.array[0] a.array = a.array[1:] - return value + return value, true } // PopRight pops and returns an item from the end of array. -func (a *SortedArray) PopRight() interface{} { +// Note that if the array is empty, the is false. +func (a *SortedArray) PopRight() (value interface{}, found bool) { a.mu.Lock() defer a.mu.Unlock() index := len(a.array) - 1 if index <= 0 { - return nil + return nil, false } - value := a.array[index] + value = a.array[index] a.array = a.array[:index] - return value + return value, true } // PopRand randomly pops and return an item out of array. -func (a *SortedArray) PopRand() interface{} { - return a.Remove(grand.Intn(len(a.array))) +// Note that if the array is empty, the is false. +func (a *SortedArray) PopRand() (value interface{}, found bool) { + a.mu.Lock() + defer a.mu.Unlock() + return a.doRemoveWithoutLock(grand.Intn(len(a.array))) } // PopRands randomly pops and returns items out of array. func (a *SortedArray) PopRands(size int) []interface{} { a.mu.Lock() defer a.mu.Unlock() - if size > len(a.array) { - size = len(a.array) - } - if size == 0 { + if size <= 0 || len(a.array) == 0 { return nil } + if size >= len(a.array) { + size = len(a.array) + } array := make([]interface{}, size) for i := 0; i < size; i++ { - index := grand.Intn(len(a.array)) - array[i] = a.array[index] - a.array = append(a.array[:index], a.array[index+1:]...) + array[i], _ = a.doRemoveWithoutLock(grand.Intn(len(a.array))) } return array } @@ -245,13 +256,14 @@ func (a *SortedArray) PopRands(size int) []interface{} { func (a *SortedArray) PopLefts(size int) []interface{} { a.mu.Lock() defer a.mu.Unlock() - length := len(a.array) - if size > length { - size = length - } - if size == 0 { + if size <= 0 || len(a.array) == 0 { return nil } + if size >= len(a.array) { + array := a.array + a.array = a.array[:0] + return array + } value := a.array[0:size] a.array = a.array[size:] return value @@ -261,12 +273,14 @@ func (a *SortedArray) PopLefts(size int) []interface{} { func (a *SortedArray) PopRights(size int) []interface{} { a.mu.Lock() defer a.mu.Unlock() - if len(a.array) == 0 { + if size <= 0 || len(a.array) == 0 { return nil } index := len(a.array) - size - if index < 0 { - index = 0 + if index <= 0 { + array := a.array + a.array = a.array[:0] + return array } value := a.array[index:] a.array = a.array[:index] @@ -554,27 +568,27 @@ func (a *SortedArray) Chunk(size int) [][]interface{} { } // Rand randomly returns one item from array(no deleting). -func (a *SortedArray) Rand() interface{} { +func (a *SortedArray) Rand() (value interface{}, found bool) { a.mu.RLock() defer a.mu.RUnlock() - return a.array[grand.Intn(len(a.array))] + if len(a.array) == 0 { + return nil, false + } + return a.array[grand.Intn(len(a.array))], true } // Rands randomly returns items from array(no deleting). func (a *SortedArray) Rands(size int) []interface{} { a.mu.RLock() defer a.mu.RUnlock() - if size > len(a.array) { - size = len(a.array) + if size <= 0 || len(a.array) == 0 { + return nil } - n := make([]interface{}, size) - for i, v := range grand.Perm(len(a.array)) { - n[i] = a.array[v] - if i == size-1 { - break - } + array := make([]interface{}, size) + for i := 0; i < size; i++ { + array[i] = a.array[grand.Intn(len(a.array))] } - return n + return array } // Join joins array elements with a string . diff --git a/container/garray/garray_sorted_int.go b/container/garray/garray_sorted_int.go index f0761ddf0..66d2df88a 100644 --- a/container/garray/garray_sorted_int.go +++ b/container/garray/garray_sorted_int.go @@ -133,135 +133,145 @@ func (a *SortedIntArray) Add(values ...int) *SortedIntArray { return a } -// Get returns the value of the specified index, -// the caller should notice the boundary of the array. -func (a *SortedIntArray) Get(index int) int { +// Get returns the value by the specified index. +// If the given is out of range of the array, the is false. +func (a *SortedIntArray) Get(index int) (value int, found bool) { a.mu.RLock() defer a.mu.RUnlock() - value := a.array[index] - return value + if index < 0 || index >= len(a.array) { + return 0, false + } + return a.array[index], true } // Remove removes an item by index. -// Note that if the index is out of range of array, it returns 0. -func (a *SortedIntArray) Remove(index int) int { +// If the given is out of range of the array, the is false. +func (a *SortedIntArray) Remove(index int) (value int, found bool) { a.mu.Lock() defer a.mu.Unlock() + return a.doRemoveWithoutLock(index) +} + +// doRemoveWithoutLock removes an item by index without lock. +func (a *SortedIntArray) doRemoveWithoutLock(index int) (value int, found bool) { if index < 0 || index >= len(a.array) { - return 0 + return 0, false } // Determine array boundaries when deleting to improve deletion efficiency. if index == 0 { value := a.array[0] a.array = a.array[1:] - return value + return value, true } else if index == len(a.array)-1 { value := a.array[index] a.array = a.array[:index] - return value + return value, true } // If it is a non-boundary delete, // it will involve the creation of an array, // then the deletion is less efficient. - value := a.array[index] + value = a.array[index] a.array = append(a.array[:index], a.array[index+1:]...) - return value + return value, true } // RemoveValue removes an item by value. // It returns true if value is found in the array, or else false if not found. func (a *SortedIntArray) RemoveValue(value int) bool { if i := a.Search(value); i != -1 { - a.Remove(i) - return true + _, found := a.Remove(i) + return found } return false } // PopLeft pops and returns an item from the beginning of array. -// Note that if the array is empty, it returns 0. -// Be very careful when use this function in loop statement. -// You can use IsEmpty() of Len() == 0 checks if this array empty. -func (a *SortedIntArray) PopLeft() int { +// Note that if the array is empty, the is false. +func (a *SortedIntArray) PopLeft() (value int, found bool) { a.mu.Lock() defer a.mu.Unlock() if len(a.array) == 0 { - return 0 + return 0, false } - value := a.array[0] + value = a.array[0] a.array = a.array[1:] - return value + return value, true } // PopRight pops and returns an item from the end of array. -// Note that if the array is empty, it returns 0. -// Be very careful when use this function in loop statement. -// You can use IsEmpty() of Len() == 0 checks if this array empty. -func (a *SortedIntArray) PopRight() int { +// Note that if the array is empty, the is false. +func (a *SortedIntArray) PopRight() (value int, found bool) { a.mu.Lock() defer a.mu.Unlock() index := len(a.array) - 1 if index <= 0 { - return 0 + return 0, false } - value := a.array[index] + value = a.array[index] a.array = a.array[:index] - return value + return value, true } // PopRand randomly pops and return an item out of array. -// Note that if the array is empty, it returns 0. -// Be very careful when use this function in loop statement. -// You can use IsEmpty() of Len() == 0 checks if this array empty. -func (a *SortedIntArray) PopRand() int { - return a.Remove(grand.Intn(len(a.array))) +// Note that if the array is empty, the is false. +func (a *SortedIntArray) PopRand() (value int, found bool) { + a.mu.Lock() + defer a.mu.Unlock() + return a.doRemoveWithoutLock(grand.Intn(len(a.array))) } // PopRands randomly pops and returns items out of array. +// If the given is greater than size of the array, it returns all elements of the array. +// Note that if given <= 0 or the array is empty, it returns nil. func (a *SortedIntArray) PopRands(size int) []int { a.mu.Lock() defer a.mu.Unlock() - if size > len(a.array) { - size = len(a.array) - } - if size == 0 { + if size <= 0 || len(a.array) == 0 { return nil } + if size >= len(a.array) { + size = len(a.array) + } array := make([]int, size) for i := 0; i < size; i++ { - index := grand.Intn(len(a.array)) - array[i] = a.array[index] - a.array = append(a.array[:index], a.array[index+1:]...) + array[i], _ = a.doRemoveWithoutLock(grand.Intn(len(a.array))) } return array } // PopLefts pops and returns items from the beginning of array. +// If the given is greater than size of the array, it returns all elements of the array. +// Note that if given <= 0 or the array is empty, it returns nil. func (a *SortedIntArray) PopLefts(size int) []int { a.mu.Lock() defer a.mu.Unlock() - length := len(a.array) - if size > length { - size = length - } - if size == 0 { + if size <= 0 || len(a.array) == 0 { return nil } + if size >= len(a.array) { + array := a.array + a.array = a.array[:0] + return array + } value := a.array[0:size] a.array = a.array[size:] return value } // PopRights pops and returns items from the end of array. +// If the given is greater than size of the array, it returns all elements of the array. +// Note that if given <= 0 or the array is empty, it returns nil. func (a *SortedIntArray) PopRights(size int) []int { a.mu.Lock() defer a.mu.Unlock() - if len(a.array) == 0 { + if size <= 0 || len(a.array) == 0 { return nil } index := len(a.array) - size - if index < 0 { - index = 0 + if index <= 0 { + array := a.array + a.array = a.array[:0] + return array } value := a.array[index:] a.array = a.array[:index] @@ -555,27 +565,27 @@ func (a *SortedIntArray) Chunk(size int) [][]int { } // Rand randomly returns one item from array(no deleting). -func (a *SortedIntArray) Rand() int { +func (a *SortedIntArray) Rand() (value int, found bool) { a.mu.RLock() defer a.mu.RUnlock() - return a.array[grand.Intn(len(a.array))] + if len(a.array) == 0 { + return 0, false + } + return a.array[grand.Intn(len(a.array))], true } // Rands randomly returns items from array(no deleting). func (a *SortedIntArray) Rands(size int) []int { a.mu.RLock() defer a.mu.RUnlock() - if size > len(a.array) { - size = len(a.array) + if size <= 0 || len(a.array) == 0 { + return nil } - n := make([]int, size) - for i, v := range grand.Perm(len(a.array)) { - n[i] = a.array[v] - if i == size-1 { - break - } + array := make([]int, size) + for i := 0; i < size; i++ { + array[i] = a.array[grand.Intn(len(a.array))] } - return n + return array } // Join joins array elements with a string . diff --git a/container/garray/garray_sorted_str.go b/container/garray/garray_sorted_str.go index a5e8395d9..19ce248c8 100644 --- a/container/garray/garray_sorted_str.go +++ b/container/garray/garray_sorted_str.go @@ -118,39 +118,46 @@ func (a *SortedStrArray) Add(values ...string) *SortedStrArray { return a } -// Get returns the value of the specified index, -// the caller should notice the boundary of the array. -func (a *SortedStrArray) Get(index int) string { +// Get returns the value by the specified index. +// If the given is out of range of the array, the is false. +func (a *SortedStrArray) Get(index int) (value string, found bool) { a.mu.RLock() defer a.mu.RUnlock() - value := a.array[index] - return value + if index < 0 || index >= len(a.array) { + return "", false + } + return a.array[index], true } // Remove removes an item by index. -// Note that if the index is out of range of array, it returns an empty string. -func (a *SortedStrArray) Remove(index int) string { +// If the given is out of range of the array, the is false. +func (a *SortedStrArray) Remove(index int) (value string, found bool) { a.mu.Lock() defer a.mu.Unlock() + return a.doRemoveWithoutLock(index) +} + +// doRemoveWithoutLock removes an item by index without lock. +func (a *SortedStrArray) doRemoveWithoutLock(index int) (value string, found bool) { if index < 0 || index >= len(a.array) { - return "" + return "", false } // Determine array boundaries when deleting to improve deletion efficiency. if index == 0 { value := a.array[0] a.array = a.array[1:] - return value + return value, true } else if index == len(a.array)-1 { value := a.array[index] a.array = a.array[:index] - return value + return value, true } // If it is a non-boundary delete, // it will involve the creation of an array, // then the deletion is less efficient. - value := a.array[index] + value = a.array[index] a.array = append(a.array[:index], a.array[index+1:]...) - return value + return value, true } // RemoveValue removes an item by value. @@ -164,89 +171,92 @@ func (a *SortedStrArray) RemoveValue(value string) bool { } // PopLeft pops and returns an item from the beginning of array. -// Note that if the array is empty, it returns an empty string. -// Be very careful when use this function in loop statement. -// You can use IsEmpty() of Len() == 0 checks if this array empty. -func (a *SortedStrArray) PopLeft() string { +// Note that if the array is empty, the is false. +func (a *SortedStrArray) PopLeft() (value string, found bool) { a.mu.Lock() defer a.mu.Unlock() if len(a.array) == 0 { - return "" + return "", false } - value := a.array[0] + value = a.array[0] a.array = a.array[1:] - return value + return value, true } // PopRight pops and returns an item from the end of array. -// Note that if the array is empty, it returns an empty string. -// Be very careful when use this function in loop statement. -// You can use IsEmpty() of Len() == 0 checks if this array empty. -func (a *SortedStrArray) PopRight() string { +// Note that if the array is empty, the is false. +func (a *SortedStrArray) PopRight() (value string, found bool) { a.mu.Lock() defer a.mu.Unlock() index := len(a.array) - 1 if index <= 0 { - return "" + return "", false } - value := a.array[index] + value = a.array[index] a.array = a.array[:index] - return value + return value, true } // PopRand randomly pops and return an item out of array. -// Note that if the array is empty, it returns an empty string. -// Be very careful when use this function in loop statement. -// You can use IsEmpty() of Len() == 0 checks if this array empty. -func (a *SortedStrArray) PopRand() string { - return a.Remove(grand.Intn(len(a.array))) +// Note that if the array is empty, the is false. +func (a *SortedStrArray) PopRand() (value string, found bool) { + a.mu.Lock() + defer a.mu.Unlock() + return a.doRemoveWithoutLock(grand.Intn(len(a.array))) } // PopRands randomly pops and returns items out of array. +// If the given is greater than size of the array, it returns all elements of the array. +// Note that if given <= 0 or the array is empty, it returns nil. func (a *SortedStrArray) PopRands(size int) []string { a.mu.Lock() defer a.mu.Unlock() - if size > len(a.array) { - size = len(a.array) - } - if size == 0 { + if size <= 0 || len(a.array) == 0 { return nil } + if size >= len(a.array) { + size = len(a.array) + } array := make([]string, size) for i := 0; i < size; i++ { - index := grand.Intn(len(a.array)) - array[i] = a.array[index] - a.array = append(a.array[:index], a.array[index+1:]...) + array[i], _ = a.doRemoveWithoutLock(grand.Intn(len(a.array))) } return array } // PopLefts pops and returns items from the beginning of array. +// If the given is greater than size of the array, it returns all elements of the array. +// Note that if given <= 0 or the array is empty, it returns nil. func (a *SortedStrArray) PopLefts(size int) []string { a.mu.Lock() defer a.mu.Unlock() - length := len(a.array) - if size > length { - size = length - } - if size == 0 { + if size <= 0 || len(a.array) == 0 { return nil } + if size >= len(a.array) { + array := a.array + a.array = a.array[:0] + return array + } value := a.array[0:size] a.array = a.array[size:] return value } // PopRights pops and returns items from the end of array. +// If the given is greater than size of the array, it returns all elements of the array. +// Note that if given <= 0 or the array is empty, it returns nil. func (a *SortedStrArray) PopRights(size int) []string { a.mu.Lock() defer a.mu.Unlock() - if len(a.array) == 0 { + if size <= 0 || len(a.array) == 0 { return nil } index := len(a.array) - size - if index < 0 { - index = 0 + if index <= 0 { + array := a.array + a.array = a.array[:0] + return array } value := a.array[index:] a.array = a.array[:index] @@ -540,27 +550,27 @@ func (a *SortedStrArray) Chunk(size int) [][]string { } // Rand randomly returns one item from array(no deleting). -func (a *SortedStrArray) Rand() string { +func (a *SortedStrArray) Rand() (value string, found bool) { a.mu.RLock() defer a.mu.RUnlock() - return a.array[grand.Intn(len(a.array))] + if len(a.array) == 0 { + return "", false + } + return a.array[grand.Intn(len(a.array))], true } // Rands randomly returns items from array(no deleting). func (a *SortedStrArray) Rands(size int) []string { a.mu.RLock() defer a.mu.RUnlock() - if size > len(a.array) { - size = len(a.array) + if size <= 0 || len(a.array) == 0 { + return nil } - n := make([]string, size) - for i, v := range grand.Perm(len(a.array)) { - n[i] = a.array[v] - if i == size-1 { - break - } + array := make([]string, size) + for i := 0; i < size; i++ { + array[i] = a.array[grand.Intn(len(a.array))] } - return n + return array } // Join joins array elements with a string . diff --git a/container/garray/garray_z_example_test.go b/container/garray/garray_z_example_test.go index 1b8a03f82..2dbe37d8c 100644 --- a/container/garray/garray_z_example_test.go +++ b/container/garray/garray_z_example_test.go @@ -61,7 +61,7 @@ func Example_basic() { // Output: // 10 // [0 1 2 3 4 5 6 7 8 9] - // 6 + // 6 true // true // false // [0 1 2 3 4 5 6 7 8 9 10 11] @@ -95,9 +95,9 @@ func Example_popItem() { fmt.Println(array.PopRights(2)) // Output: - // 1 + // 1 true // [2 3] - // 9 + // 9 true // [7 8] } diff --git a/container/garray/garray_z_unit_normal_any_array_test.go b/container/garray/garray_z_unit_normal_any_array_test.go index 0a7f1494a..a1447c8ab 100644 --- a/container/garray/garray_z_unit_normal_any_array_test.go +++ b/container/garray/garray_z_unit_normal_any_array_test.go @@ -28,17 +28,38 @@ func Test_Array_Basic(t *testing.T) { t.Assert(array.Slice(), expect) t.Assert(array.Interfaces(), expect) array.Set(0, 100) - t.Assert(array.Get(0), 100) - t.Assert(array.Get(1), 1) + + v, ok := array.Get(0) + t.Assert(v, 100) + t.Assert(ok, true) + + v, ok = array.Get(1) + t.Assert(v, 1) + t.Assert(ok, true) + t.Assert(array.Search(100), 0) t.Assert(array3.Search(100), -1) t.Assert(array.Contains(100), true) - t.Assert(array.Remove(0), 100) - t.Assert(array.Remove(-1), nil) - t.Assert(array.Remove(100000), nil) - t.Assert(array2.Remove(3), 3) - t.Assert(array2.Remove(1), 1) + v, ok = array.Remove(0) + t.Assert(v, 100) + t.Assert(ok, true) + + v, ok = array.Remove(-1) + t.Assert(v, nil) + t.Assert(ok, false) + + v, ok = array.Remove(100000) + t.Assert(v, nil) + t.Assert(ok, false) + + v, ok = array2.Remove(3) + t.Assert(v, 3) + t.Assert(ok, true) + + v, ok = array2.Remove(1) + t.Assert(v, 1) + t.Assert(ok, true) t.Assert(array.Contains(100), false) array.Append(4) @@ -85,10 +106,23 @@ func TestArray_PushAndPop(t *testing.T) { expect := []interface{}{0, 1, 2, 3} array := garray.NewArrayFrom(expect) t.Assert(array.Slice(), expect) - t.Assert(array.PopLeft(), 0) - t.Assert(array.PopRight(), 3) - t.AssertIN(array.PopRand(), []interface{}{1, 2}) - t.AssertIN(array.PopRand(), []interface{}{1, 2}) + + v, ok := array.PopLeft() + t.Assert(v, 0) + t.Assert(ok, true) + + v, ok = array.PopRight() + t.Assert(v, 3) + t.Assert(ok, true) + + v, ok = array.PopRand() + t.AssertIN(v, []interface{}{1, 2}) + t.Assert(ok, true) + + v, ok = array.PopRand() + t.AssertIN(v, []interface{}{1, 2}) + t.Assert(ok, true) + t.Assert(array.Len(), 0) array.PushLeft(1).PushRight(2) t.Assert(array.Slice(), []interface{}{1, 2}) @@ -106,11 +140,19 @@ func TestArray_PopRands(t *testing.T) { func TestArray_PopLeftsAndPopRights(t *testing.T) { gtest.C(t, func(t *gtest.T) { array := garray.New() - t.Assert(array.PopLeft(), nil) + v, ok := array.PopLeft() + t.Assert(v, nil) + t.Assert(ok, false) t.Assert(array.PopLefts(10), nil) - t.Assert(array.PopRight(), nil) + + v, ok = array.PopRight() + t.Assert(v, nil) + t.Assert(ok, false) t.Assert(array.PopRights(10), nil) - t.Assert(array.PopRand(), nil) + + v, ok = array.PopRand() + t.Assert(v, nil) + t.Assert(ok, false) t.Assert(array.PopRands(10), nil) }) @@ -185,9 +227,15 @@ func TestArray_Fill(t *testing.T) { a2 := []interface{}{0} array1 := garray.NewArrayFrom(a1) array2 := garray.NewArrayFrom(a2, true) - t.Assert(array1.Fill(1, 2, 100).Slice(), []interface{}{0, 100, 100}) - t.Assert(array2.Fill(0, 2, 100).Slice(), []interface{}{100, 100}) - t.Assert(array2.Fill(-1, 2, 100).Slice(), []interface{}{100, 100}) + + t.Assert(array1.Fill(1, 2, 100), nil) + t.Assert(array1.Slice(), []interface{}{0, 100, 100}) + + t.Assert(array2.Fill(0, 2, 100), nil) + t.Assert(array2.Slice(), []interface{}{100, 100}) + + t.AssertNE(array2.Fill(-1, 2, 100), nil) + t.Assert(array2.Slice(), []interface{}{100, 100}) }) } @@ -263,14 +311,15 @@ func TestArray_Rand(t *testing.T) { a1 := []interface{}{0, 1, 2, 3, 4, 5, 6} array1 := garray.NewArrayFrom(a1) t.Assert(len(array1.Rands(2)), 2) - t.Assert(len(array1.Rands(10)), 7) + t.Assert(len(array1.Rands(10)), 10) t.AssertIN(array1.Rands(1)[0], a1) }) gtest.C(t, func(t *gtest.T) { s1 := []interface{}{"a", "b", "c", "d"} a1 := garray.NewArrayFrom(s1) - i1 := a1.Rand() + i1, ok := a1.Rand() + t.Assert(ok, true) t.Assert(a1.Contains(i1), true) t.Assert(a1.Len(), 4) }) diff --git a/container/garray/garray_z_unit_normal_int_array_test.go b/container/garray/garray_z_unit_normal_int_array_test.go index 39a18af65..112de3db7 100644 --- a/container/garray/garray_z_unit_normal_int_array_test.go +++ b/container/garray/garray_z_unit_normal_int_array_test.go @@ -29,14 +29,31 @@ func Test_IntArray_Basic(t *testing.T) { t.Assert(array.Slice(), expect) t.Assert(array.Interfaces(), expect) array.Set(0, 100) - t.Assert(array.Get(0), 100) - t.Assert(array.Get(1), 1) + + v, ok := array.Get(0) + t.Assert(v, 100) + t.Assert(ok, true) + + v, ok = array.Get(1) + t.Assert(v, 1) + t.Assert(ok, true) + t.Assert(array.Search(100), 0) t.Assert(array2.Search(100), -1) t.Assert(array.Contains(100), true) - t.Assert(array.Remove(0), 100) - t.Assert(array.Remove(-1), 0) - t.Assert(array.Remove(100000), 0) + + v, ok = array.Remove(0) + t.Assert(v, 100) + t.Assert(ok, true) + + v, ok = array.Remove(-1) + t.Assert(v, 0) + t.Assert(ok, false) + + v, ok = array.Remove(100000) + t.Assert(v, 0) + t.Assert(ok, false) + t.Assert(array.Contains(100), false) array.Append(4) t.Assert(array.Len(), 4) @@ -81,10 +98,27 @@ func TestIntArray_PushAndPop(t *testing.T) { expect := []int{0, 1, 2, 3} array := garray.NewIntArrayFrom(expect) t.Assert(array.Slice(), expect) - t.Assert(array.PopLeft(), 0) - t.Assert(array.PopRight(), 3) - t.AssertIN(array.PopRand(), []int{1, 2}) - t.AssertIN(array.PopRand(), []int{1, 2}) + + v, ok := array.PopLeft() + t.Assert(v, 0) + t.Assert(ok, true) + + v, ok = array.PopRight() + t.Assert(v, 3) + t.Assert(ok, true) + + v, ok = array.PopRand() + t.AssertIN(v, []int{1, 2}) + t.Assert(ok, true) + + v, ok = array.PopRand() + t.AssertIN(v, []int{1, 2}) + t.Assert(ok, true) + + v, ok = array.PopRand() + t.Assert(v, 0) + t.Assert(ok, false) + t.Assert(array.Len(), 0) array.PushLeft(1).PushRight(2) t.Assert(array.Slice(), []int{1, 2}) @@ -94,11 +128,23 @@ func TestIntArray_PushAndPop(t *testing.T) { func TestIntArray_PopLeftsAndPopRights(t *testing.T) { gtest.C(t, func(t *gtest.T) { array := garray.NewIntArray() - t.Assert(array.PopLeft(), 0) + + v, ok := array.PopLeft() + t.Assert(v, 0) + t.Assert(ok, false) + t.Assert(array.PopLefts(10), nil) - t.Assert(array.PopRight(), 0) + + v, ok = array.PopRight() + t.Assert(v, 0) + t.Assert(ok, false) + t.Assert(array.PopRights(10), nil) - t.Assert(array.PopRand(), 0) + + v, ok = array.PopRand() + t.Assert(v, 0) + t.Assert(ok, false) + t.Assert(array.PopRands(10), nil) }) @@ -173,9 +219,14 @@ func TestIntArray_Fill(t *testing.T) { a2 := []int{0} array1 := garray.NewIntArrayFrom(a1) array2 := garray.NewIntArrayFrom(a2) - t.Assert(array1.Fill(1, 2, 100).Slice(), []int{0, 100, 100}) - t.Assert(array2.Fill(0, 2, 100).Slice(), []int{100, 100}) - t.Assert(array2.Fill(-1, 2, 100).Slice(), []int{100, 100}) + t.Assert(array1.Fill(1, 2, 100), nil) + t.Assert(array1.Slice(), []int{0, 100, 100}) + + t.Assert(array2.Fill(0, 2, 100), nil) + t.Assert(array2.Slice(), []int{100, 100}) + + t.AssertNE(array2.Fill(-1, 2, 100), nil) + t.Assert(array2.Slice(), []int{100, 100}) }) } @@ -259,9 +310,12 @@ func TestIntArray_Rand(t *testing.T) { a1 := []int{0, 1, 2, 3, 4, 5, 6} array1 := garray.NewIntArrayFrom(a1) t.Assert(len(array1.Rands(2)), 2) - t.Assert(len(array1.Rands(10)), 7) + t.Assert(len(array1.Rands(10)), 10) t.AssertIN(array1.Rands(1)[0], a1) - t.AssertIN(array1.Rand(), a1) + + v, ok := array1.Rand() + t.AssertIN(v, a1) + t.Assert(ok, true) }) } @@ -358,7 +412,9 @@ func TestArray_Get(t *testing.T) { gtest.C(t, func(t *gtest.T) { a1 := []int{1, 2, 3, 5} array1 := garray.NewIntArrayFrom(a1) - t.Assert(array1.Get(2), 3) + v, ok := array1.Get(2) + t.Assert(v, 3) + t.Assert(ok, true) t.Assert(array1.Len(), 4) }) } @@ -395,16 +451,19 @@ func TestIntArray_Remove(t *testing.T) { gtest.C(t, func(t *gtest.T) { a1 := []int{1, 2, 3, 5, 4} array1 := garray.NewIntArrayFrom(a1) - n1 := array1.Remove(1) - t.Assert(n1, 2) + v, ok := array1.Remove(1) + t.Assert(v, 2) + t.Assert(ok, true) t.Assert(array1.Len(), 4) - n1 = array1.Remove(0) - t.Assert(n1, 1) + v, ok = array1.Remove(0) + t.Assert(v, 1) + t.Assert(ok, true) t.Assert(array1.Len(), 3) - n1 = array1.Remove(2) - t.Assert(n1, 4) + v, ok = array1.Remove(2) + t.Assert(v, 4) + t.Assert(ok, true) t.Assert(array1.Len(), 2) }) } diff --git a/container/garray/garray_z_unit_normal_str_array_test.go b/container/garray/garray_z_unit_normal_str_array_test.go index 5347dc665..090705224 100644 --- a/container/garray/garray_z_unit_normal_str_array_test.go +++ b/container/garray/garray_z_unit_normal_str_array_test.go @@ -29,13 +29,26 @@ func Test_StrArray_Basic(t *testing.T) { t.Assert(array.Slice(), expect) t.Assert(array.Interfaces(), expect) array.Set(0, "100") - t.Assert(array.Get(0), 100) - t.Assert(array.Get(1), 1) + + v, ok := array.Get(0) + t.Assert(v, 100) + t.Assert(ok, true) + t.Assert(array.Search("100"), 0) t.Assert(array.Contains("100"), true) - t.Assert(array.Remove(0), 100) - t.Assert(array.Remove(-1), "") - t.Assert(array.Remove(100000), "") + + v, ok = array.Remove(0) + t.Assert(v, 100) + t.Assert(ok, true) + + v, ok = array.Remove(-1) + t.Assert(v, "") + t.Assert(ok, false) + + v, ok = array.Remove(100000) + t.Assert(v, "") + t.Assert(ok, false) + t.Assert(array.Contains("100"), false) array.Append("4") t.Assert(array.Len(), 4) @@ -79,10 +92,27 @@ func TestStrArray_PushAndPop(t *testing.T) { expect := []string{"0", "1", "2", "3"} array := garray.NewStrArrayFrom(expect) t.Assert(array.Slice(), expect) - t.Assert(array.PopLeft(), "0") - t.Assert(array.PopRight(), "3") - t.AssertIN(array.PopRand(), []string{"1", "2"}) - t.AssertIN(array.PopRand(), []string{"1", "2"}) + + v, ok := array.PopLeft() + t.Assert(v, "0") + t.Assert(ok, true) + + v, ok = array.PopRight() + t.Assert(v, "3") + t.Assert(ok, true) + + v, ok = array.PopRand() + t.AssertIN(v, []string{"1", "2"}) + t.Assert(ok, true) + + v, ok = array.PopRand() + t.AssertIN(v, []string{"1", "2"}) + t.Assert(ok, true) + + v, ok = array.PopRand() + t.Assert(v, "") + t.Assert(ok, false) + t.Assert(array.Len(), 0) array.PushLeft("1").PushRight("2") t.Assert(array.Slice(), []string{"1", "2"}) @@ -92,11 +122,19 @@ func TestStrArray_PushAndPop(t *testing.T) { func TestStrArray_PopLeftsAndPopRights(t *testing.T) { gtest.C(t, func(t *gtest.T) { array := garray.NewStrArray() - t.Assert(array.PopLeft(), nil) + v, ok := array.PopLeft() + t.Assert(v, "") + t.Assert(ok, false) t.Assert(array.PopLefts(10), nil) - t.Assert(array.PopRight(), nil) + + v, ok = array.PopRight() + t.Assert(v, "") + t.Assert(ok, false) t.Assert(array.PopRights(10), nil) - t.Assert(array.PopRand(), nil) + + v, ok = array.PopRand() + t.Assert(v, "") + t.Assert(ok, false) t.Assert(array.PopRands(10), nil) }) @@ -171,10 +209,12 @@ func TestStrArray_Fill(t *testing.T) { a2 := []string{"0"} array1 := garray.NewStrArrayFrom(a1) array2 := garray.NewStrArrayFrom(a2) - t.Assert(array1.Fill(1, 2, "100").Slice(), []string{"0", "100", "100"}) - t.Assert(array2.Fill(0, 2, "100").Slice(), []string{"100", "100"}) - s1 := array2.Fill(-1, 2, "100") - t.Assert(s1.Len(), 2) + t.Assert(array1.Fill(1, 2, "100"), nil) + t.Assert(array1.Slice(), []string{"0", "100", "100"}) + t.Assert(array2.Fill(0, 2, "100"), nil) + t.Assert(array2.Slice(), []string{"100", "100"}) + t.AssertNE(array2.Fill(-1, 2, "100"), nil) + t.Assert(array2.Len(), 2) }) } @@ -250,10 +290,11 @@ func TestStrArray_Rand(t *testing.T) { a1 := []string{"0", "1", "2", "3", "4", "5", "6"} array1 := garray.NewStrArrayFrom(a1) t.Assert(len(array1.Rands(2)), "2") - t.Assert(len(array1.Rands(10)), "7") + t.Assert(len(array1.Rands(10)), 10) t.AssertIN(array1.Rands(1)[0], a1) - t.Assert(len(array1.Rand()), 1) - t.AssertIN(array1.Rand(), a1) + v, ok := array1.Rand() + t.Assert(ok, true) + t.AssertIN(v, a1) }) } @@ -373,9 +414,10 @@ func TestStrArray_PopRand(t *testing.T) { gtest.C(t, func(t *gtest.T) { a1 := []string{"0", "1", "2", "3", "4", "5", "6"} array1 := garray.NewStrArrayFrom(a1) - str1 := array1.PopRand() + str1, ok := array1.PopRand() t.Assert(strings.Contains("0,1,2,3,4,5,6", str1), true) t.Assert(array1.Len(), 6) + t.Assert(ok, true) }) } @@ -405,11 +447,13 @@ func TestStrArray_Remove(t *testing.T) { gtest.C(t, func(t *gtest.T) { a1 := []string{"e", "a", "d", "a", "c"} array1 := garray.NewStrArrayFrom(a1) - s1 := array1.Remove(1) + s1, ok := array1.Remove(1) t.Assert(s1, "a") + t.Assert(ok, true) t.Assert(array1.Len(), 4) - s1 = array1.Remove(3) + s1, ok = array1.Remove(3) t.Assert(s1, "c") + t.Assert(ok, true) t.Assert(array1.Len(), 3) }) } diff --git a/container/garray/garray_z_unit_sorted_any_array_test.go b/container/garray/garray_z_unit_sorted_any_array_test.go index c7bd4ad0a..bd639235b 100644 --- a/container/garray/garray_z_unit_sorted_any_array_test.go +++ b/container/garray/garray_z_unit_sorted_any_array_test.go @@ -99,8 +99,13 @@ func TestSortedArray_Get(t *testing.T) { return strings.Compare(gconv.String(v1), gconv.String(v2)) } array1 := garray.NewSortedArrayFrom(a1, func1) - t.Assert(array1.Get(2), "f") - t.Assert(array1.Get(1), "c") + v, ok := array1.Get(2) + t.Assert(v, "f") + t.Assert(ok, true) + + v, ok = array1.Get(1) + t.Assert(v, "c") + t.Assert(ok, true) }) } @@ -112,20 +117,28 @@ func TestSortedArray_Remove(t *testing.T) { return strings.Compare(gconv.String(v1), gconv.String(v2)) } array1 := garray.NewSortedArrayFrom(a1, func1) - i1 := array1.Remove(1) + i1, ok := array1.Remove(1) + t.Assert(ok, true) t.Assert(gconv.String(i1), "b") t.Assert(array1.Len(), 3) t.Assert(array1.Contains("b"), false) - t.Assert(array1.Remove(-1), nil) - t.Assert(array1.Remove(100000), nil) + v, ok := array1.Remove(-1) + t.Assert(v, nil) + t.Assert(ok, false) - i2 := array1.Remove(0) + v, ok = array1.Remove(100000) + t.Assert(v, nil) + t.Assert(ok, false) + + i2, ok := array1.Remove(0) + t.Assert(ok, true) t.Assert(gconv.String(i2), "a") t.Assert(array1.Len(), 2) t.Assert(array1.Contains("a"), false) - i3 := array1.Remove(1) + i3, ok := array1.Remove(1) + t.Assert(ok, true) t.Assert(gconv.String(i3), "d") t.Assert(array1.Len(), 1) t.Assert(array1.Contains("d"), false) @@ -140,7 +153,8 @@ func TestSortedArray_PopLeft(t *testing.T) { return strings.Compare(gconv.String(v1), gconv.String(v2)) } array1 := garray.NewSortedArrayFrom(a1, func1) - i1 := array1.PopLeft() + i1, ok := array1.PopLeft() + t.Assert(ok, true) t.Assert(gconv.String(i1), "a") t.Assert(array1.Len(), 3) t.Assert(array1, []interface{}{"b", "c", "d"}) @@ -155,7 +169,8 @@ func TestSortedArray_PopRight(t *testing.T) { return strings.Compare(gconv.String(v1), gconv.String(v2)) } array1 := garray.NewSortedArrayFrom(a1, func1) - i1 := array1.PopRight() + i1, ok := array1.PopRight() + t.Assert(ok, true) t.Assert(gconv.String(i1), "d") t.Assert(array1.Len(), 3) t.Assert(array1, []interface{}{"a", "b", "c"}) @@ -170,7 +185,8 @@ func TestSortedArray_PopRand(t *testing.T) { return strings.Compare(gconv.String(v1), gconv.String(v2)) } array1 := garray.NewSortedArrayFrom(a1, func1) - i1 := array1.PopRand() + i1, ok := array1.PopRand() + t.Assert(ok, true) t.AssertIN(i1, []interface{}{"a", "d", "c", "b"}) t.Assert(array1.Len(), 3) @@ -200,11 +216,19 @@ func TestSortedArray_PopRands(t *testing.T) { func TestSortedArray_Empty(t *testing.T) { gtest.C(t, func(t *gtest.T) { array := garray.NewSortedArray(gutil.ComparatorInt) - t.Assert(array.PopLeft(), nil) + v, ok := array.PopLeft() + t.Assert(v, nil) + t.Assert(ok, false) t.Assert(array.PopLefts(10), nil) - t.Assert(array.PopRight(), nil) + + v, ok = array.PopRight() + t.Assert(v, nil) + t.Assert(ok, false) t.Assert(array.PopRights(10), nil) - t.Assert(array.PopRand(), nil) + + v, ok = array.PopRand() + t.Assert(v, nil) + t.Assert(ok, false) t.Assert(array.PopRands(10), nil) }) } @@ -406,7 +430,8 @@ func TestSortedArray_Rand(t *testing.T) { return strings.Compare(gconv.String(v1), gconv.String(v2)) } array1 := garray.NewSortedArrayFrom(a1, func1) - i1 := array1.Rand() + i1, ok := array1.Rand() + t.Assert(ok, true) t.AssertIN(i1, []interface{}{"a", "d", "c"}) t.Assert(array1.Len(), 3) }) @@ -426,7 +451,7 @@ func TestSortedArray_Rands(t *testing.T) { t.Assert(array1.Len(), 3) i1 = array1.Rands(4) - t.Assert(len(i1), 3) + t.Assert(len(i1), 4) }) } @@ -625,9 +650,22 @@ func TestSortedArray_Json(t *testing.T) { t.Assert(user.Name, data["Name"]) t.AssertNE(user.Scores, nil) t.Assert(user.Scores.Len(), 3) - t.AssertIN(user.Scores.PopLeft(), data["Scores"]) - t.AssertIN(user.Scores.PopLeft(), data["Scores"]) - t.AssertIN(user.Scores.PopLeft(), data["Scores"]) + + v, ok := user.Scores.PopLeft() + t.AssertIN(v, data["Scores"]) + t.Assert(ok, true) + + v, ok = user.Scores.PopLeft() + t.AssertIN(v, data["Scores"]) + t.Assert(ok, true) + + v, ok = user.Scores.PopLeft() + t.AssertIN(v, data["Scores"]) + t.Assert(ok, true) + + v, ok = user.Scores.PopLeft() + t.Assert(v, nil) + t.Assert(ok, false) }) } diff --git a/container/garray/garray_z_unit_sorted_int_array_test.go b/container/garray/garray_z_unit_sorted_int_array_test.go index f76bf9b8d..4265ddb08 100644 --- a/container/garray/garray_z_unit_sorted_int_array_test.go +++ b/container/garray/garray_z_unit_sorted_int_array_test.go @@ -68,9 +68,17 @@ func TestSortedIntArray_Get(t *testing.T) { gtest.C(t, func(t *gtest.T) { a1 := []int{1, 3, 5, 0} array1 := garray.NewSortedIntArrayFrom(a1) - t.Assert(array1.Get(0), 0) - t.Assert(array1.Get(1), 1) - t.Assert(array1.Get(3), 5) + v, ok := array1.Get(0) + t.Assert(v, 0) + t.Assert(ok, true) + + v, ok = array1.Get(1) + t.Assert(v, 1) + t.Assert(ok, true) + + v, ok = array1.Get(3) + t.Assert(v, 5) + t.Assert(ok, true) }) } @@ -79,26 +87,39 @@ func TestSortedIntArray_Remove(t *testing.T) { a1 := []int{1, 3, 5, 0} array1 := garray.NewSortedIntArrayFrom(a1) - t.Assert(array1.Remove(-1), 0) - t.Assert(array1.Remove(100000), 0) + v, ok := array1.Remove(-1) + t.Assert(v, 0) + t.Assert(ok, false) + + v, ok = array1.Remove(-100000) + t.Assert(v, 0) + t.Assert(ok, false) + + v, ok = array1.Remove(2) + t.Assert(v, 3) + t.Assert(ok, true) - i1 := array1.Remove(2) - t.Assert(i1, 3) t.Assert(array1.Search(5), 2) - // 再次删除剩下的数组中的第一个 - i2 := array1.Remove(0) - t.Assert(i2, 0) + v, ok = array1.Remove(0) + t.Assert(v, 0) + t.Assert(ok, true) + t.Assert(array1.Search(5), 1) a2 := []int{1, 3, 4} array2 := garray.NewSortedIntArrayFrom(a2) - i3 := array2.Remove(1) + + v, ok = array2.Remove(1) + t.Assert(v, 3) + t.Assert(ok, true) t.Assert(array2.Search(1), 0) - t.Assert(i3, 3) - i3 = array2.Remove(1) + + v, ok = array2.Remove(1) + t.Assert(v, 4) + t.Assert(ok, true) + t.Assert(array2.Search(4), -1) - t.Assert(i3, 4) }) } @@ -106,8 +127,9 @@ func TestSortedIntArray_PopLeft(t *testing.T) { gtest.C(t, func(t *gtest.T) { a1 := []int{1, 3, 5, 2} array1 := garray.NewSortedIntArrayFrom(a1) - i1 := array1.PopLeft() - t.Assert(i1, 1) + v, ok := array1.PopLeft() + t.Assert(v, 1) + t.Assert(ok, true) t.Assert(array1.Len(), 3) t.Assert(array1.Search(1), -1) }) @@ -117,8 +139,9 @@ func TestSortedIntArray_PopRight(t *testing.T) { gtest.C(t, func(t *gtest.T) { a1 := []int{1, 3, 5, 2} array1 := garray.NewSortedIntArrayFrom(a1) - i1 := array1.PopRight() - t.Assert(i1, 5) + v, ok := array1.PopRight() + t.Assert(v, 5) + t.Assert(ok, true) t.Assert(array1.Len(), 3) t.Assert(array1.Search(5), -1) }) @@ -128,7 +151,8 @@ func TestSortedIntArray_PopRand(t *testing.T) { gtest.C(t, func(t *gtest.T) { a1 := []int{1, 3, 5, 2} array1 := garray.NewSortedIntArrayFrom(a1) - i1 := array1.PopRand() + i1, ok := array1.PopRand() + t.Assert(ok, true) t.Assert(array1.Len(), 3) t.Assert(array1.Search(i1), -1) t.AssertIN(i1, []int{1, 3, 5, 2}) @@ -155,11 +179,19 @@ func TestSortedIntArray_PopRands(t *testing.T) { func TestSortedIntArray_Empty(t *testing.T) { gtest.C(t, func(t *gtest.T) { array := garray.NewSortedIntArray() - t.Assert(array.PopLeft(), 0) + v, ok := array.PopLeft() + t.Assert(v, 0) + t.Assert(ok, false) t.Assert(array.PopLefts(10), nil) - t.Assert(array.PopRight(), 0) + + v, ok = array.PopRight() + t.Assert(v, 0) + t.Assert(ok, false) t.Assert(array.PopRights(10), nil) - t.Assert(array.PopRand(), 0) + + v, ok = array.PopRand() + t.Assert(v, 0) + t.Assert(ok, false) t.Assert(array.PopRands(10), nil) }) } @@ -340,8 +372,9 @@ func TestSortedIntArray_Rand(t *testing.T) { gtest.C(t, func(t *gtest.T) { a1 := []int{1, 2, 3, 4, 5} array1 := garray.NewSortedIntArrayFrom(a1) - ns1 := array1.Rand() //按每几个元素切成一个数组 + ns1, ok := array1.Rand() t.AssertIN(ns1, a1) + t.Assert(ok, true) }) } @@ -349,13 +382,12 @@ func TestSortedIntArray_Rands(t *testing.T) { gtest.C(t, func(t *gtest.T) { a1 := []int{1, 2, 3, 4, 5} array1 := garray.NewSortedIntArrayFrom(a1) - ns1 := array1.Rands(2) //按每几个元素切成一个数组 + ns1 := array1.Rands(2) t.AssertIN(ns1, a1) t.Assert(len(ns1), 2) - ns2 := array1.Rands(6) //按每几个元素切成一个数组 - t.AssertIN(ns2, a1) - t.Assert(len(ns2), 5) + ns2 := array1.Rands(6) + t.Assert(len(ns2), 6) }) } diff --git a/container/garray/garray_z_unit_sorted_str_array_test.go b/container/garray/garray_z_unit_sorted_str_array_test.go index ab77dba54..0981add81 100644 --- a/container/garray/garray_z_unit_sorted_str_array_test.go +++ b/container/garray/garray_z_unit_sorted_str_array_test.go @@ -68,8 +68,13 @@ func TestSortedStrArray_Get(t *testing.T) { gtest.C(t, func(t *gtest.T) { a1 := []string{"a", "d", "c", "b"} array1 := garray.NewSortedStrArrayFrom(a1) - t.Assert(array1.Get(2), "c") - t.Assert(array1.Get(0), "a") + v, ok := array1.Get(2) + t.Assert(v, "c") + t.Assert(ok, true) + + v, ok = array1.Get(0) + t.Assert(v, "a") + t.Assert(ok, true) }) } @@ -78,20 +83,36 @@ func TestSortedStrArray_Remove(t *testing.T) { a1 := []string{"a", "d", "c", "b"} array1 := garray.NewSortedStrArrayFrom(a1) - t.Assert(array1.Remove(-1), "") - t.Assert(array1.Remove(100000), "") + v, ok := array1.Remove(-1) + t.Assert(v, "") + t.Assert(ok, false) + + v, ok = array1.Remove(100000) + t.Assert(v, "") + t.Assert(ok, false) + + v, ok = array1.Remove(2) + t.Assert(v, "c") + t.Assert(ok, true) + + v, ok = array1.Get(2) + t.Assert(v, "d") + t.Assert(ok, true) - t.Assert(array1.Remove(2), "c") - t.Assert(array1.Get(2), "d") t.Assert(array1.Len(), 3) t.Assert(array1.Contains("c"), false) - t.Assert(array1.Remove(0), "a") + v, ok = array1.Remove(0) + t.Assert(v, "a") + t.Assert(ok, true) + t.Assert(array1.Len(), 2) t.Assert(array1.Contains("a"), false) - // 此时array1里的元素只剩下2个 - t.Assert(array1.Remove(1), "d") + v, ok = array1.Remove(1) + t.Assert(v, "d") + t.Assert(ok, true) + t.Assert(array1.Len(), 1) }) } @@ -100,8 +121,9 @@ func TestSortedStrArray_PopLeft(t *testing.T) { gtest.C(t, func(t *gtest.T) { a1 := []string{"e", "a", "d", "c", "b"} array1 := garray.NewSortedStrArrayFrom(a1) - s1 := array1.PopLeft() - t.Assert(s1, "a") + v, ok := array1.PopLeft() + t.Assert(v, "a") + t.Assert(ok, true) t.Assert(array1.Len(), 4) t.Assert(array1.Contains("a"), false) }) @@ -111,8 +133,9 @@ func TestSortedStrArray_PopRight(t *testing.T) { gtest.C(t, func(t *gtest.T) { a1 := []string{"e", "a", "d", "c", "b"} array1 := garray.NewSortedStrArrayFrom(a1) - s1 := array1.PopRight() - t.Assert(s1, "e") + v, ok := array1.PopRight() + t.Assert(v, "e") + t.Assert(ok, ok) t.Assert(array1.Len(), 4) t.Assert(array1.Contains("e"), false) }) @@ -122,7 +145,8 @@ func TestSortedStrArray_PopRand(t *testing.T) { gtest.C(t, func(t *gtest.T) { a1 := []string{"e", "a", "d", "c", "b"} array1 := garray.NewSortedStrArrayFrom(a1) - s1 := array1.PopRand() + s1, ok := array1.PopRand() + t.Assert(ok, true) t.AssertIN(s1, []string{"e", "a", "d", "c", "b"}) t.Assert(array1.Len(), 4) t.Assert(array1.Contains(s1), false) @@ -147,11 +171,19 @@ func TestSortedStrArray_PopRands(t *testing.T) { func TestSortedStrArray_Empty(t *testing.T) { gtest.C(t, func(t *gtest.T) { array := garray.NewSortedStrArray() - t.Assert(array.PopLeft(), nil) + v, ok := array.PopLeft() + t.Assert(v, "") + t.Assert(ok, false) t.Assert(array.PopLefts(10), nil) - t.Assert(array.PopRight(), nil) + + v, ok = array.PopRight() + t.Assert(v, "") + t.Assert(ok, false) t.Assert(array.PopRights(10), nil) - t.Assert(array.PopRand(), nil) + + v, ok = array.PopRand() + t.Assert(v, "") + t.Assert(ok, false) t.Assert(array.PopRands(10), nil) }) } @@ -283,7 +315,9 @@ func TestSortedStrArray_Rand(t *testing.T) { gtest.C(t, func(t *gtest.T) { a1 := []string{"e", "a", "d"} array1 := garray.NewSortedStrArrayFrom(a1) - t.AssertIN(array1.Rand(), []string{"e", "a", "d"}) + v, ok := array1.Rand() + t.AssertIN(v, []string{"e", "a", "d"}) + t.Assert(ok, true) }) } @@ -297,8 +331,7 @@ func TestSortedStrArray_Rands(t *testing.T) { t.Assert(len(s1), 2) s1 = array1.Rands(4) - t.AssertIN(s1, []string{"e", "a", "d"}) - t.Assert(len(s1), 3) + t.Assert(len(s1), 4) }) } diff --git a/os/glog/glog_logger_rotate.go b/os/glog/glog_logger_rotate.go index c3efcf190..ac1ca49fc 100644 --- a/os/glog/glog_logger_rotate.go +++ b/os/glog/glog_logger_rotate.go @@ -187,9 +187,9 @@ func (l *Logger) rotateChecksTimely() { for _, array := range backupFilesMap { diff := array.Len() - l.config.RotateBackupLimit for i := 0; i < diff; i++ { - path := array.PopLeft().(string) + path, _ := array.PopLeft() intlog.Printf(`remove exceeded backup limit file: %s`, path) - if err := gfile.Remove(path); err != nil { + if err := gfile.Remove(path.(string)); err != nil { intlog.Print(err) } } diff --git a/os/gtimer/gtimer.go b/os/gtimer/gtimer.go index 1147ae078..748bd5239 100644 --- a/os/gtimer/gtimer.go +++ b/os/gtimer/gtimer.go @@ -11,7 +11,8 @@ // between gtimer and gcron are as follows: // 1. package gcron is implemented based on package gtimer. // 2. gtimer is designed for high performance and for millions of timing jobs. -// 3. gcron supports configuration pattern grammar like linux crontab, which is more manually readable. +// 3. gcron supports configuration pattern grammar like linux crontab, which is more manually +// readable. // 4. gtimer's benchmark OP is measured in nanoseconds, and gcron's benchmark OP is measured // in microseconds. // diff --git a/util/grand/grand.go b/util/grand/grand.go index 5e622bed3..c62413359 100644 --- a/util/grand/grand.go +++ b/util/grand/grand.go @@ -105,6 +105,7 @@ func Symbols(n int) string { } // Perm returns, as a slice of n int numbers, a pseudo-random permutation of the integers [0,n). +// TODO performance improving for large slice producing. func Perm(n int) []int { m := make([]int, n) for i := 0; i < n; i++ { diff --git a/util/grand/grand_z_bench_test.go b/util/grand/grand_z_bench_test.go index 10d21861f..7790ba982 100644 --- a/util/grand/grand_z_bench_test.go +++ b/util/grand/grand_z_bench_test.go @@ -18,13 +18,31 @@ import ( var buffer = make([]byte, 8) -func Benchmark_Rand1(b *testing.B) { +func Benchmark_Rand_Intn(b *testing.B) { for i := 0; i < b.N; i++ { grand.N(0, 99) } } -func Benchmark_Rand2(b *testing.B) { +func Benchmark_Perm10(b *testing.B) { + for i := 0; i < b.N; i++ { + grand.Perm(10) + } +} + +func Benchmark_Perm100(b *testing.B) { + for i := 0; i < b.N; i++ { + grand.Perm(100) + } +} + +func Benchmark_Rand_N1(b *testing.B) { + for i := 0; i < b.N; i++ { + grand.N(0, 99) + } +} + +func Benchmark_Rand_N2(b *testing.B) { for i := 0; i < b.N; i++ { grand.N(0, 999999999) }