Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 87 additions & 0 deletions container/gmap/gmap_hash_k_v_map.go
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,54 @@ func (m *KVMap[K, V]) GetVarOrSetFuncLock(key K, f func() V) *gvar.Var {
return gvar.New(m.GetOrSetFuncLock(key, f))
}

// GetOrSetFuncWithError returns the value by key,
// or sets value with returned value of callback function `f` if it does not exist
// and then returns this value.
//
// Note that, it does not add the value to the map if the returned value of `f` is nil
// or if `f` returns a non-nil error.
func (m *KVMap[K, V]) GetOrSetFuncWithError(key K, f func() (V, error)) (V, error) {
if v, ok := m.Search(key); ok {
return v, nil
}
value, err := f()
if err != nil {
var zero V
return zero, err
}
v, _ := m.doSetWithLockCheck(key, value)
return v, nil
}

// GetOrSetFuncLockWithError returns the value by key,
// or sets value with returned value of callback function `f` if it does not exist
// and then returns this value.
//
// GetOrSetFuncLockWithError differs with GetOrSetFuncWithError function is that it executes function `f`
// with mutex.Lock of the hash map.
//
// Note that, it does not add the value to the map if the returned value of `f` is nil
// or if `f` returns a non-nil error.
func (m *KVMap[K, V]) GetOrSetFuncLockWithError(key K, f func() (V, error)) (V, error) {
m.mu.Lock()
defer m.mu.Unlock()
if m.data == nil {
m.data = make(map[K]V)
}
if v, ok := m.data[key]; ok {
return v, nil
}
value, err := f()
if err != nil {
var zero V
return zero, err
}
if !m.isNil(value) {
m.data[key] = value
}
return value, nil
}
Comment thread
LanceAdd marked this conversation as resolved.

// SetIfNotExist sets `value` to the map if the `key` does not exist, and then returns true.
// It returns false if `key` exists, and `value` would be ignored.
func (m *KVMap[K, V]) SetIfNotExist(key K, value V) bool {
Expand Down Expand Up @@ -375,6 +423,45 @@ func (m *KVMap[K, V]) SetIfNotExistFuncLock(key K, f func() V) bool {
return false
}

// SetIfNotExistFuncWithError sets value with return value of callback function `f`, and then returns true.
// It returns false if `key` exists, and `value` would be ignored.
// It returns (false, error) if `f` returns a non-nil error, and `value` would not be stored.
func (m *KVMap[K, V]) SetIfNotExistFuncWithError(key K, f func() (V, error)) (bool, error) {
if m.Contains(key) {
return false, nil
}
value, err := f()
if err != nil {
return false, err
}
Comment thread
LanceAdd marked this conversation as resolved.
return m.SetIfNotExist(key, value), nil
}

// SetIfNotExistFuncLockWithError sets value with return value of callback function `f`, and then returns true.
// It returns false if `key` exists, and `value` would be ignored.
// It returns (false, error) if `f` returns a non-nil error, and `value` would not be stored.
Comment thread
LanceAdd marked this conversation as resolved.
//
// SetIfNotExistFuncLockWithError differs with SetIfNotExistFuncWithError function is that
// it executes function `f` with mutex.Lock of the hash map.
func (m *KVMap[K, V]) SetIfNotExistFuncLockWithError(key K, f func() (V, error)) (bool, error) {
m.mu.Lock()
defer m.mu.Unlock()
if m.data == nil {
m.data = make(map[K]V)
}
if _, ok := m.data[key]; ok {
return false, nil
}
value, err := f()
if err != nil {
return false, err
}
if !m.isNil(value) {
m.data[key] = value
}
return true, nil
}

// Remove deletes value from map by given `key`, and return this deleted value.
func (m *KVMap[K, V]) Remove(key K) (value V) {
m.mu.Lock()
Expand Down
94 changes: 88 additions & 6 deletions container/gmap/gmap_list_k_v_map.go
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,54 @@ func (m *ListKVMap[K, V]) GetVarOrSetFuncLock(key K, f func() V) *gvar.Var {
return gvar.New(m.GetOrSetFuncLock(key, f))
}

// GetOrSetFuncWithError returns the value by key,
// or sets value with returned value of callback function `f` if it does not exist
// and then returns this value.
//
// Note that, it does not add the value to the map if the returned value of `f` is nil
// or if `f` returns a non-nil error.
func (m *ListKVMap[K, V]) GetOrSetFuncWithError(key K, f func() (V, error)) (V, error) {
if v, ok := m.Search(key); ok {
return v, nil
}
value, err := f()
if err != nil {
var zero V
return zero, err
}
return m.doSetWithLockCheck(key, value), nil
}

// GetOrSetFuncLockWithError returns the value by key,
// or sets value with returned value of callback function `f` if it does not exist
// and then returns this value.
//
// GetOrSetFuncLockWithError differs with GetOrSetFuncWithError function is that it executes function `f`
// with mutex.Lock of the map.
//
// Note that, it does not add the value to the map if the returned value of `f` is nil
// or if `f` returns a non-nil error.
func (m *ListKVMap[K, V]) GetOrSetFuncLockWithError(key K, f func() (V, error)) (V, error) {
m.mu.Lock()
defer m.mu.Unlock()
if m.data == nil {
m.data = make(map[K]*glist.TElement[*gListKVMapNode[K, V]])
m.list = glist.NewT[*gListKVMapNode[K, V]]()
}
if e, ok := m.data[key]; ok {
return e.Value.value, nil
}
value, err := f()
if err != nil {
var zero V
return zero, err
}
if !m.isNil(value) {
m.data[key] = m.list.PushBack(&gListKVMapNode[K, V]{key, value})
}
return value, nil
}

// SetIfNotExist sets `value` to the map if the `key` does not exist, and then returns true.
// It returns false if `key` exists, and `value` would be ignored.
//
Expand All @@ -426,6 +474,20 @@ func (m *ListKVMap[K, V]) SetIfNotExist(key K, value V) bool {
//
// Note that, it does not add the value to the map if the returned value of `f` is nil.
func (m *ListKVMap[K, V]) SetIfNotExistFunc(key K, f func() V) bool {
if m.Contains(key) {
return false
}
return m.SetIfNotExist(key, f())
}

// SetIfNotExistFuncLock sets value with return value of callback function `f`, and then returns true.
// It returns false if `key` exists, and `value` would be ignored.
//
// SetIfNotExistFuncLock differs with SetIfNotExistFunc function is that
// it executes function `f` with mutex.Lock of the map.
//
// Note that, it does not add the value to the map if the returned value of `f` is nil.
func (m *ListKVMap[K, V]) SetIfNotExistFuncLock(key K, f func() V) bool {
m.mu.Lock()
defer m.mu.Unlock()

Expand All @@ -443,14 +505,31 @@ func (m *ListKVMap[K, V]) SetIfNotExistFunc(key K, f func() V) bool {
return true
}

// SetIfNotExistFuncLock sets value with return value of callback function `f`, and then returns true.
// SetIfNotExistFuncWithError sets value with return value of callback function `f`, and then returns true.
// It returns false if `key` exists, and `value` would be ignored.
// It returns (false, error) if `f` returns a non-nil error, and `value` would not be stored.
//
// SetIfNotExistFuncLock differs with SetIfNotExistFunc function is that
// Note that, it does not add the value to the map if the returned value of `f` is nil.
func (m *ListKVMap[K, V]) SetIfNotExistFuncWithError(key K, f func() (V, error)) (bool, error) {
if m.Contains(key) {
return false, nil
}
value, err := f()
if err != nil {
return false, err
}
return m.SetIfNotExist(key, value), nil
}

// SetIfNotExistFuncLockWithError sets value with return value of callback function `f`, and then returns true.
// It returns false if `key` exists, and `value` would be ignored.
// It returns (false, error) if `f` returns a non-nil error, and `value` would not be stored.
//
// SetIfNotExistFuncLockWithError differs with SetIfNotExistFuncWithError function is that
// it executes function `f` with mutex.Lock of the map.
//
// Note that, it does not add the value to the map if the returned value of `f` is nil.
func (m *ListKVMap[K, V]) SetIfNotExistFuncLock(key K, f func() V) bool {
func (m *ListKVMap[K, V]) SetIfNotExistFuncLockWithError(key K, f func() (V, error)) (bool, error) {
m.mu.Lock()
defer m.mu.Unlock()

Expand All @@ -459,13 +538,16 @@ func (m *ListKVMap[K, V]) SetIfNotExistFuncLock(key K, f func() V) bool {
m.list = glist.NewT[*gListKVMapNode[K, V]]()
}
if _, ok := m.data[key]; ok {
return false
return false, nil
}
value, err := f()
if err != nil {
return false, err
}
value := f()
if !m.isNil(value) {
m.data[key] = m.list.PushBack(&gListKVMapNode[K, V]{key, value})
}
return true
return true, nil
}
Comment thread
LanceAdd marked this conversation as resolved.

// Remove deletes value from map by given `key`, and return this deleted value.
Expand Down
11 changes: 3 additions & 8 deletions database/gdb/gdb.go
Original file line number Diff line number Diff line change
Expand Up @@ -990,19 +990,14 @@ func newDBByConfigNode(node *ConfigNode, group string) (db DB, err error) {
// Instance returns an instance for DB operations.
// The parameter `name` specifies the configuration group name,
// which is DefaultGroupName in default.
func Instance(name ...string) (db DB, err error) {
func Instance(name ...string) (DB, error) {
group := configs.group
if len(name) > 0 && name[0] != "" {
group = name[0]
}
v := instances.GetOrSetFuncLock(group, func() DB {
db, err = NewByGroup(group)
return db
return instances.GetOrSetFuncLockWithError(group, func() (DB, error) {
return NewByGroup(group)
})
if v != nil {
return v, nil
}
return nil, err
}

// getConfigNodeByGroup calculates and returns a configuration node of given group. It
Expand Down
Loading