Files
gf/container/gset/gset_int_set.go

285 lines
7.3 KiB
Go
Raw Permalink Normal View History

2021-01-17 21:46:25 +08:00
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
2017-12-29 16:03:30 +08:00
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
2017-12-29 16:03:30 +08:00
//
2017-12-31 18:19:58 +08:00
2017-11-23 10:21:28 +08:00
package gset
import (
"sync"
2017-11-23 10:21:28 +08:00
)
// IntSet is consisted of int items.
2017-11-23 10:21:28 +08:00
type IntSet struct {
*TSet[int]
once sync.Once
2017-11-23 10:21:28 +08:00
}
// NewIntSet create and returns a new set, which contains un-repeated items.
// The parameter `safe` is used to specify whether using set in concurrent-safety,
2019-04-24 18:15:50 +08:00
// which is false in default.
func NewIntSet(safe ...bool) *IntSet {
return &IntSet{
TSet: NewTSet[int](safe...),
}
2017-11-23 10:21:28 +08:00
}
// NewIntSetFrom returns a new set from `items`.
func NewIntSetFrom(items []int, safe ...bool) *IntSet {
return &IntSet{
TSet: NewTSetFrom(items, safe...),
}
}
// lazyInit lazily initializes the set.
func (a *IntSet) lazyInit() {
a.once.Do(func() {
if a.TSet == nil {
a.TSet = NewTSet[int]()
}
})
}
// Iterator iterates the set readonly with given callback function `f`,
// if `f` returns true then continue iterating; or false to stop.
2020-04-13 23:44:43 +08:00
func (set *IntSet) Iterator(f func(v int) bool) {
set.lazyInit()
set.TSet.Iterator(f)
}
2019-04-24 18:15:50 +08:00
// Add adds one or multiple items to the set.
2020-04-13 23:44:43 +08:00
func (set *IntSet) Add(item ...int) {
set.lazyInit()
set.TSet.Add(item...)
2017-11-23 10:21:28 +08:00
}
2020-04-13 23:44:43 +08:00
// 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.
2020-04-13 23:44:43 +08:00
func (set *IntSet) AddIfNotExist(item int) bool {
set.lazyInit()
return set.TSet.AddIfNotExist(item)
}
2020-04-13 23:44:43 +08:00
// 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.
2020-04-13 23:44:43 +08:00
func (set *IntSet) AddIfNotExistFunc(item int, f func() bool) bool {
set.lazyInit()
return set.TSet.AddIfNotExistFunc(item, f)
}
// AddIfNotExistFuncLock checks whether item exists in the set,
2020-04-13 23:44:43 +08:00
// 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.
2020-04-13 23:44:43 +08:00
func (set *IntSet) AddIfNotExistFuncLock(item int, f func() bool) bool {
set.lazyInit()
return set.TSet.AddIfNotExistFuncLock(item, f)
}
// Contains checks whether the set contains `item`.
func (set *IntSet) Contains(item int) bool {
set.lazyInit()
return set.TSet.Contains(item)
2017-11-23 10:21:28 +08:00
}
// Remove deletes `item` from set.
2020-04-13 23:44:43 +08:00
func (set *IntSet) Remove(item int) {
set.lazyInit()
set.TSet.Remove(item)
2017-11-23 10:21:28 +08:00
}
2019-04-24 18:15:50 +08:00
// Size returns the size of the set.
func (set *IntSet) Size() int {
set.lazyInit()
return set.TSet.Size()
2017-11-23 10:21:28 +08:00
}
2019-04-24 18:15:50 +08:00
// Clear deletes all items of the set.
2020-04-13 23:44:43 +08:00
func (set *IntSet) Clear() {
set.lazyInit()
set.TSet.Clear()
2017-11-23 10:21:28 +08:00
}
// Slice returns the an of items of the set as slice.
func (set *IntSet) Slice() []int {
set.lazyInit()
return set.TSet.Slice()
2017-11-23 10:21:28 +08:00
}
// Join joins items with a string `glue`.
2019-02-02 15:16:45 +08:00
func (set *IntSet) Join(glue string) string {
set.lazyInit()
return set.TSet.Join(glue)
2019-02-02 15:16:45 +08:00
}
// String returns items as a string, which implements like json.Marshal does.
func (set *IntSet) String() string {
2022-03-21 22:04:15 +08:00
if set == nil {
return ""
}
set.lazyInit()
return set.TSet.String()
2017-11-23 10:21:28 +08:00
}
// LockFunc locks writing with callback function `f`.
func (set *IntSet) LockFunc(f func(m map[int]struct{})) {
set.lazyInit()
set.TSet.LockFunc(f)
}
// RLockFunc locks reading with callback function `f`.
func (set *IntSet) RLockFunc(f func(m map[int]struct{})) {
set.lazyInit()
set.TSet.RLockFunc(f)
}
2019-04-24 18:15:50 +08:00
// Equal checks whether the two sets equal.
func (set *IntSet) Equal(other *IntSet) bool {
set.lazyInit()
other.lazyInit()
return set.TSet.Equal(other.TSet)
}
// IsSubsetOf checks whether the current set is a sub-set of `other`.
2019-01-31 21:15:39 +08:00
func (set *IntSet) IsSubsetOf(other *IntSet) bool {
2019-06-19 09:06:52 +08:00
if set == other {
return true
}
set.lazyInit()
other.lazyInit()
return set.TSet.IsSubsetOf(other.TSet)
}
// Union returns a new set which is the union of `set` and `other`.
// Which means, all the items in `newSet` are in `set` or in `other`.
2019-06-19 09:06:52 +08:00
func (set *IntSet) Union(others ...*IntSet) (newSet *IntSet) {
set.lazyInit()
return &IntSet{
TSet: set.TSet.Union(set.toTSetSlice(others)...),
2019-06-19 09:06:52 +08:00
}
}
// Diff returns a new set which is the difference set from `set` to `other`.
// Which means, all the items in `newSet` are in `set` but not in `other`.
2019-06-19 09:06:52 +08:00
func (set *IntSet) Diff(others ...*IntSet) (newSet *IntSet) {
set.lazyInit()
return &IntSet{
TSet: set.TSet.Diff(set.toTSetSlice(others)...),
2019-06-19 09:06:52 +08:00
}
}
// Intersect returns a new set which is the intersection from `set` to `other`.
// Which means, all the items in `newSet` are in `set` and also in `other`.
2019-06-19 09:06:52 +08:00
func (set *IntSet) Intersect(others ...*IntSet) (newSet *IntSet) {
set.lazyInit()
return &IntSet{
TSet: set.TSet.Intersect(set.toTSetSlice(others)...),
2019-06-19 09:06:52 +08:00
}
}
// Complement returns a new set which is the complement from `set` to `full`.
// Which means, all the items in `newSet` are in `full` and not in `set`.
2019-02-02 15:16:45 +08:00
//
// It returns the difference between `full` and `set`
// if the given set `full` is not the full set of `set`.
func (set *IntSet) Complement(full *IntSet) (newSet *IntSet) {
set.lazyInit()
if full == nil {
return &IntSet{
TSet: NewTSet[int](),
2019-06-19 09:06:52 +08:00
}
}
full.lazyInit()
return &IntSet{
TSet: set.TSet.Complement(full.TSet),
}
2019-02-01 17:30:23 +08:00
}
2019-04-24 18:15:50 +08:00
// Merge adds items from `others` sets into `set`.
2019-06-19 09:06:52 +08:00
func (set *IntSet) Merge(others ...*IntSet) *IntSet {
set.lazyInit()
set.TSet.Merge(set.toTSetSlice(others)...)
2019-04-24 18:15:50 +08:00
return set
}
// Sum sums items.
// Note: The items should be converted to int type,
// or you'd get a result that you unexpected.
func (set *IntSet) Sum() (sum int) {
set.lazyInit()
return set.TSet.Sum()
2019-04-26 08:57:48 +08:00
}
// Pop randomly pops an item from set.
func (set *IntSet) Pop() int {
set.lazyInit()
return set.TSet.Pop()
2019-04-26 08:57:48 +08:00
}
// Pops randomly pops `size` items from set.
// It returns all items if size == -1.
2019-04-26 08:57:48 +08:00
func (set *IntSet) Pops(size int) []int {
set.lazyInit()
return set.TSet.Pops(size)
2019-06-19 09:06:52 +08:00
}
// Walk applies a user supplied function `f` to every item of set.
func (set *IntSet) Walk(f func(item int) int) *IntSet {
set.lazyInit()
set.TSet.Walk(f)
return set
}
// MarshalJSON implements the interface MarshalJSON for json.Marshal.
func (set IntSet) MarshalJSON() ([]byte, error) {
set.lazyInit()
return set.TSet.MarshalJSON()
}
2019-09-30 14:37:05 +08:00
// UnmarshalJSON implements the interface UnmarshalJSON for json.Unmarshal.
func (set *IntSet) UnmarshalJSON(b []byte) error {
set.lazyInit()
return set.TSet.UnmarshalJSON(b)
2019-09-30 14:37:05 +08:00
}
// UnmarshalValue is an interface implement which sets any type of value for set.
refactor: interface{} to any and reflect.Ptr to reflect.Pointer (#4395) This pull request standardizes the use of the Go 1.18+ `any` type alias instead of `interface{}` throughout the codebase. The change improves code readability and aligns with modern Go best practices. The update touches many files, including core data structures, code generation templates, logging utilities, and test data, ensuring consistency across all usages. **Type alias migration to `any`:** * Replaced all instances of `interface{}` with `any` in core data structures such as `garray` and in generated model structs (e.g., `TableUser`, `User1`, `User2`) to modernize type usage. [[1]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L31-R31) [[2]](diffhunk://#diff-6c19859cb32c7516ea95ddc8f8235460818eb2f24d2204308e0d9e1b19e7d90fL15-R19) [[3]](diffhunk://#diff-a15ba2f5e830b4833c47b902515a4f9e5a4f83a3707698f3229b307ec3776b41L15-R18) [[4]](diffhunk://#diff-52e0837e84d49221d1b810d88fdf78221f36cffcd664fb42f8aba49a79b974dcL15-R19) [[5]](diffhunk://#diff-11c3457d1a23a4ca6ecd00d6b856289774936b6a708384cf03aff164044e7546L15-R19) [[6]](diffhunk://#diff-2cff9cf8e6a0cc34087326d8c8149c3bbaf74c76fdbdf5a73daed13cc04249e1L15-R19) * Updated function signatures, method parameters, and return types from `interface{}` to `any` in various parts of the codebase, including code generation, service logic, and logging utilities (e.g., `mlog`). [[1]](diffhunk://#diff-175edfeea54490b8fe4e18ffcbea5835efaf8f0b8acf623359073987cae7eb76L48-R55) [[2]](diffhunk://#diff-2b1953fb78cf3593d8c2c7d911e95b65fd0b847c30ed0b4d167d16fe6d781235L54-R74) [[3]](diffhunk://#diff-e001b7a4b63603b9b14f00de78a4d570bb76c5f57d856a24643f071032e12356L66-R73) [[4]](diffhunk://#diff-5582954e8a9983988dc8854ad82067fb2ac6269b988e07357ad8db1dfec5f1a0L39-R41) [[5]](diffhunk://#diff-c5d51d56f487779a2b6207c7ad26c7a20bbadcc846ce094fe60ab4cabff58c51L107-R107) [[6]](diffhunk://#diff-f96e6a9fdb416eb1804ceaba1fe0ac637bff22c43837f8bb849c2366ce72d4a1L116-R121) [[7]](diffhunk://#diff-f94c83a1b08ae060d9346f4a6031fc4a7b9a0b894e02d9afaa09018b6598eac0L112-R112) [[8]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L36-R36) [[9]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L74-R74) [[10]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L96-R96) **Generated code and templates:** * Adjusted generated files and code generation templates to output `any` instead of `interface{}` for relevant struct fields and function signatures, ensuring that new code generation aligns with the updated convention. [[1]](diffhunk://#diff-6c19859cb32c7516ea95ddc8f8235460818eb2f24d2204308e0d9e1b19e7d90fL15-R19) [[2]](diffhunk://#diff-a15ba2f5e830b4833c47b902515a4f9e5a4f83a3707698f3229b307ec3776b41L15-R18) [[3]](diffhunk://#diff-52e0837e84d49221d1b810d88fdf78221f36cffcd664fb42f8aba49a79b974dcL15-R19) [[4]](diffhunk://#diff-11c3457d1a23a4ca6ecd00d6b856289774936b6a708384cf03aff164044e7546L15-R19) [[5]](diffhunk://#diff-2cff9cf8e6a0cc34087326d8c8149c3bbaf74c76fdbdf5a73daed13cc04249e1L15-R19) [[6]](diffhunk://#diff-175edfeea54490b8fe4e18ffcbea5835efaf8f0b8acf623359073987cae7eb76L48-R55) [[7]](diffhunk://#diff-e001b7a4b63603b9b14f00de78a4d570bb76c5f57d856a24643f071032e12356L66-R73) [[8]](diffhunk://#diff-5582954e8a9983988dc8854ad82067fb2ac6269b988e07357ad8db1dfec5f1a0L39-R41) **Container and utility updates:** * Refactored the `garray` container implementation and related constructors/methods to use `[]any` instead of `[]interface{}`, along with corresponding function signatures. [[1]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L31-R31) [[2]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L52-R52) [[3]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L62-R62) [[4]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L73-R86) [[5]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L96-R97) [[6]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L107-R114) [[7]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L124-R124) [[8]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L135-R143) [[9]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L167-R167) These changes collectively modernize the codebase and prepare it for future Go developments by using the idiomatic `any` type.
2025-08-28 16:53:19 +08:00
func (set *IntSet) UnmarshalValue(value any) (err error) {
set.lazyInit()
return set.TSet.UnmarshalValue(value)
}
2022-05-23 16:51:10 +08:00
// DeepCopy implements interface for deep copy of current type.
refactor: interface{} to any and reflect.Ptr to reflect.Pointer (#4395) This pull request standardizes the use of the Go 1.18+ `any` type alias instead of `interface{}` throughout the codebase. The change improves code readability and aligns with modern Go best practices. The update touches many files, including core data structures, code generation templates, logging utilities, and test data, ensuring consistency across all usages. **Type alias migration to `any`:** * Replaced all instances of `interface{}` with `any` in core data structures such as `garray` and in generated model structs (e.g., `TableUser`, `User1`, `User2`) to modernize type usage. [[1]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L31-R31) [[2]](diffhunk://#diff-6c19859cb32c7516ea95ddc8f8235460818eb2f24d2204308e0d9e1b19e7d90fL15-R19) [[3]](diffhunk://#diff-a15ba2f5e830b4833c47b902515a4f9e5a4f83a3707698f3229b307ec3776b41L15-R18) [[4]](diffhunk://#diff-52e0837e84d49221d1b810d88fdf78221f36cffcd664fb42f8aba49a79b974dcL15-R19) [[5]](diffhunk://#diff-11c3457d1a23a4ca6ecd00d6b856289774936b6a708384cf03aff164044e7546L15-R19) [[6]](diffhunk://#diff-2cff9cf8e6a0cc34087326d8c8149c3bbaf74c76fdbdf5a73daed13cc04249e1L15-R19) * Updated function signatures, method parameters, and return types from `interface{}` to `any` in various parts of the codebase, including code generation, service logic, and logging utilities (e.g., `mlog`). [[1]](diffhunk://#diff-175edfeea54490b8fe4e18ffcbea5835efaf8f0b8acf623359073987cae7eb76L48-R55) [[2]](diffhunk://#diff-2b1953fb78cf3593d8c2c7d911e95b65fd0b847c30ed0b4d167d16fe6d781235L54-R74) [[3]](diffhunk://#diff-e001b7a4b63603b9b14f00de78a4d570bb76c5f57d856a24643f071032e12356L66-R73) [[4]](diffhunk://#diff-5582954e8a9983988dc8854ad82067fb2ac6269b988e07357ad8db1dfec5f1a0L39-R41) [[5]](diffhunk://#diff-c5d51d56f487779a2b6207c7ad26c7a20bbadcc846ce094fe60ab4cabff58c51L107-R107) [[6]](diffhunk://#diff-f96e6a9fdb416eb1804ceaba1fe0ac637bff22c43837f8bb849c2366ce72d4a1L116-R121) [[7]](diffhunk://#diff-f94c83a1b08ae060d9346f4a6031fc4a7b9a0b894e02d9afaa09018b6598eac0L112-R112) [[8]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L36-R36) [[9]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L74-R74) [[10]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L96-R96) **Generated code and templates:** * Adjusted generated files and code generation templates to output `any` instead of `interface{}` for relevant struct fields and function signatures, ensuring that new code generation aligns with the updated convention. [[1]](diffhunk://#diff-6c19859cb32c7516ea95ddc8f8235460818eb2f24d2204308e0d9e1b19e7d90fL15-R19) [[2]](diffhunk://#diff-a15ba2f5e830b4833c47b902515a4f9e5a4f83a3707698f3229b307ec3776b41L15-R18) [[3]](diffhunk://#diff-52e0837e84d49221d1b810d88fdf78221f36cffcd664fb42f8aba49a79b974dcL15-R19) [[4]](diffhunk://#diff-11c3457d1a23a4ca6ecd00d6b856289774936b6a708384cf03aff164044e7546L15-R19) [[5]](diffhunk://#diff-2cff9cf8e6a0cc34087326d8c8149c3bbaf74c76fdbdf5a73daed13cc04249e1L15-R19) [[6]](diffhunk://#diff-175edfeea54490b8fe4e18ffcbea5835efaf8f0b8acf623359073987cae7eb76L48-R55) [[7]](diffhunk://#diff-e001b7a4b63603b9b14f00de78a4d570bb76c5f57d856a24643f071032e12356L66-R73) [[8]](diffhunk://#diff-5582954e8a9983988dc8854ad82067fb2ac6269b988e07357ad8db1dfec5f1a0L39-R41) **Container and utility updates:** * Refactored the `garray` container implementation and related constructors/methods to use `[]any` instead of `[]interface{}`, along with corresponding function signatures. [[1]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L31-R31) [[2]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L52-R52) [[3]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L62-R62) [[4]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L73-R86) [[5]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L96-R97) [[6]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L107-R114) [[7]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L124-R124) [[8]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L135-R143) [[9]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L167-R167) These changes collectively modernize the codebase and prepare it for future Go developments by using the idiomatic `any` type.
2025-08-28 16:53:19 +08:00
func (set *IntSet) DeepCopy() any {
if set == nil {
return nil
}
set.lazyInit()
return &IntSet{
TSet: set.TSet.DeepCopy().(*TSet[int]),
}
}
// toTSetSlice converts []*IntSet to []*TSet[int]
func (set *IntSet) toTSetSlice(sets []*IntSet) (tSets []*TSet[int]) {
tSets = make([]*TSet[int], len(sets))
for i, v := range sets {
if v == nil {
continue
}
v.lazyInit()
tSets[i] = v.TSet
2022-05-23 16:51:10 +08:00
}
return
2022-05-23 16:51:10 +08:00
}