Skip to content

Commit

Permalink
Merge branch 'master' of github.com:webx-top/com
Browse files Browse the repository at this point in the history
  • Loading branch information
admpub committed Sep 28, 2024
2 parents 0c897ae + d773548 commit 8d773cf
Show file tree
Hide file tree
Showing 5 changed files with 189 additions and 67 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ testdata
*.exe
debug.test
go.sum
go.mod
tower-app-*
.DS_Store
/test/process/process
11 changes: 8 additions & 3 deletions cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -666,10 +666,15 @@ func ParseCmdArgs(inputArgs ...string) map[string]string {
}
key := strings.TrimPrefix(arg, `-`)
key = strings.TrimPrefix(key, `-`)
if idx < maxi {
args[key] = _inputArgs[idx+1]
parts := strings.SplitN(key, `=`, 2)
if len(parts) == 2 {
args[parts[0]] = parts[1]
} else {
args[key] = ``
if idx < maxi {
args[key] = _inputArgs[idx+1]
} else {
args[key] = ``
}
}
}
return args
Expand Down
27 changes: 27 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
module github.com/webx-top/com

go 1.21

require (
github.com/admpub/color v1.8.1
github.com/admpub/fsnotify v1.7.0
github.com/admpub/pp v0.0.7
github.com/francoispqt/gojay v1.2.13
github.com/goccy/go-json v0.10.3
github.com/hashicorp/go-version v1.7.0
github.com/json-iterator/go v1.1.12
github.com/stretchr/testify v1.9.0
golang.org/x/crypto v0.27.0
golang.org/x/text v0.18.0
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/sys v0.25.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
215 changes: 152 additions & 63 deletions safemap.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,96 +4,161 @@ import (
"sync"
)

type SafeMap struct {
lock *sync.RWMutex
bm map[interface{}]interface{}
func InitSafeMap[K comparable, V any]() SafeMap[K, V] {
return SafeMap[K, V]{
lock: new(sync.RWMutex),
bm: make(map[K]V),
}
}

func NewSafeMap() *SafeMap {
return &SafeMap{
func NewSafeMap[K comparable, V any]() *SafeMap[K, V] {
return &SafeMap[K, V]{
lock: new(sync.RWMutex),
bm: make(map[interface{}]interface{}),
bm: make(map[K]V),
}
}

//Get from maps return the k's value
func (m *SafeMap) Get(k interface{}) interface{} {
type SafeMap[K comparable, V any] struct {
lock *sync.RWMutex
bm map[K]V
}

func (m *SafeMap[K, V]) Size() int {
m.lock.RLock()
size := len(m.bm)
m.lock.RUnlock()
return size
}

func (m *SafeMap[K, V]) GetOk(k K) (V, bool) {
m.lock.RLock()
r, y := m.bm[k]
m.lock.RUnlock()
return r, y
}

// Get from maps return the k's value
func (m *SafeMap[K, V]) Get(k K) V {
m.lock.RLock()
r := m.bm[k]
m.lock.RUnlock()
return r
}

func (m *SafeMap[K, V]) Gets(keys ...K) []V {
m.lock.RLock()
defer m.lock.RUnlock()
if val, ok := m.bm[k]; ok {
return val
res := make([]V, 0, len(keys))
for _, key := range keys {
val, ok := m.bm[key]
if ok {
res = append(res, val)
}
}
return nil
m.lock.RUnlock()
return res
}

// Set maps the given key and value. Returns false
// if the key is already in the map and changes nothing.
func (m *SafeMap) Set(k interface{}, v interface{}) bool {
func (m *SafeMap[K, V]) Remove(keys ...K) {
m.lock.Lock()
defer m.lock.Unlock()
if val, ok := m.bm[k]; !ok {
m.bm[k] = v
} else if val != v {
m.bm[k] = v
} else {
return false
for _, key := range keys {
delete(m.bm, key)
}
return true
m.lock.Unlock()
}

// Check returns true if k is exist in the map.
func (m *SafeMap) Check(k interface{}) bool {
func (m *SafeMap[K, V]) Range(f func(key K, val V) bool) {
m.lock.RLock()
defer m.lock.RUnlock()
if _, ok := m.bm[k]; !ok {
return false
for key, val := range m.bm {
if !f(key, val) {
break
}
}
return true
m.lock.RUnlock()
}

func (m *SafeMap) Delete(k interface{}) {
func (m *SafeMap[K, V]) ClearEmpty(f func(key K, val V) bool) {
m.lock.Lock()
for key, val := range m.bm {
if f(key, val) {
delete(m.bm, key)
}
}
m.lock.Unlock()
}

func (m *SafeMap[K, V]) Reset() {
m.lock.Lock()
clear(m.bm)
m.lock.Unlock()
}

// Set maps the given key and value. Returns false
// if the key is already in the map and changes nothing.
func (m *SafeMap[K, V]) Set(k K, v V) {
m.lock.Lock()
m.bm[k] = v
m.lock.Unlock()
}

// Exists returns true if k is exist in the map.
func (m *SafeMap[K, V]) Exists(k K) bool {
m.lock.RLock()
_, ok := m.bm[k]
m.lock.RUnlock()
return ok
}

func (m *SafeMap[K, V]) Delete(k K) {
m.lock.Lock()
defer m.lock.Unlock()
delete(m.bm, k)
m.lock.Unlock()
}

func (m *SafeMap) Items() map[interface{}]interface{} {
func (m *SafeMap[K, V]) Items() map[K]V {
m.lock.RLock()
defer m.lock.RUnlock()
return m.bm
r := m.bm
m.lock.RUnlock()
return r
}

func NewOrderlySafeMap() *OrderlySafeMap {
return &OrderlySafeMap{
SafeMap: NewSafeMap(),
keys: make([]interface{}, 0),
func InitOrderlySafeMap[K comparable, V any]() OrderlySafeMap[K, V] {
return OrderlySafeMap[K, V]{
SafeMap: NewSafeMap[K, V](),
keys: []K{},
}
}

type OrderlySafeMap struct {
*SafeMap
keys []interface{} // map keys
values []interface{} // map values
func NewOrderlySafeMap[K comparable, V any]() *OrderlySafeMap[K, V] {
return &OrderlySafeMap[K, V]{
SafeMap: NewSafeMap[K, V](),
keys: []K{},
}
}

func (m *OrderlySafeMap) Set(k interface{}, v interface{}) bool {
type OrderlySafeMap[K comparable, V any] struct {
*SafeMap[K, V]
keys []K // map keys
}

func (m *OrderlySafeMap[K, V]) Set(k K, v V) {
m.lock.Lock()
defer m.lock.Unlock()
if val, ok := m.bm[k]; !ok {
if _, ok := m.bm[k]; !ok {
m.bm[k] = v
m.keys = append(m.keys, k)
} else if val != v {
m.bm[k] = v
} else {
return false
m.bm[k] = v
}
return true
m.lock.Unlock()
}

func (m *OrderlySafeMap) Delete(k interface{}) {
func (m *OrderlySafeMap[K, V]) Delete(k K) {
m.lock.Lock()
defer m.lock.Unlock()
delete(m.bm, k)
m.removeKey(k)
m.lock.Unlock()
}

func (m *OrderlySafeMap[K, V]) removeKey(k K) {
endIndex := len(m.keys) - 1
for index, mapKey := range m.keys {
if mapKey != k {
Expand All @@ -108,33 +173,57 @@ func (m *OrderlySafeMap) Delete(k interface{}) {
break
}
m.keys = append(m.keys[0:index], m.keys[index+1:]...)
break
return
}
}

func (m *OrderlySafeMap[K, V]) Remove(keys ...K) {
m.lock.Lock()
for _, k := range keys {
delete(m.bm, k)
m.removeKey(k)
}
m.lock.Unlock()
}

func (m *OrderlySafeMap) Keys() []interface{} {
func (m *OrderlySafeMap[K, V]) Keys() []K {
m.lock.Lock()
defer m.lock.Unlock()
return m.keys
}

func (m *OrderlySafeMap) Values(force ...bool) []interface{} {
func (m *OrderlySafeMap[K, V]) ClearEmpty(f func(key K, val V) bool) {
m.lock.Lock()
defer m.lock.Unlock()
if (len(force) == 0 || !force[0]) && m.values != nil {
return m.values
for key, val := range m.bm {
if f(key, val) {
delete(m.bm, key)
m.removeKey(key)
}
}
m.values = []interface{}{}
m.lock.Unlock()
}

func (m *OrderlySafeMap[K, V]) Reset() {
m.lock.Lock()
clear(m.bm)
clear(m.keys)
m.lock.Unlock()
}

func (m *OrderlySafeMap[K, V]) Values(force ...bool) []V {
m.lock.RLock()
values := make([]V, 0, len(m.keys))
for _, mapKey := range m.keys {
m.values = append(m.values, m.bm[mapKey])
values = append(values, m.bm[mapKey])
}
return m.values
m.lock.RUnlock()
return values
}

func (m *OrderlySafeMap) VisitAll(callback func(int, interface{}, interface{})) {
m.lock.Lock()
func (m *OrderlySafeMap[K, V]) VisitAll(callback func(int, K, V)) {
m.lock.RLock()
for index, mapKey := range m.keys {
callback(index, mapKey, m.bm[mapKey])
}
m.lock.Unlock()
m.lock.RUnlock()
}
2 changes: 2 additions & 0 deletions test/process/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import (
)

func main() {
args := com.ParseCmdArgs()
com.Dump(args)
ctx := context.Background()
// Listen to keypress of "return" and restart the app automatically
go func() {
Expand Down

0 comments on commit 8d773cf

Please sign in to comment.