Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
10 changes: 6 additions & 4 deletions database/gdb/gdb.go
Original file line number Diff line number Diff line change
Expand Up @@ -863,8 +863,10 @@ const (
)

var (
// checker is the checker function for instances map.
checker = func(v DB) bool { return v == nil }
// instances is the management map for instances.
instances = gmap.NewStrAnyMap(true)
instances = gmap.NewKVMapWithChecker[string, DB](checker, true)

// driverMap manages all custom registered driver.
driverMap = map[string]Driver{}
Expand Down Expand Up @@ -985,14 +987,14 @@ func Instance(name ...string) (db DB, err error) {
if len(name) > 0 && name[0] != "" {
group = name[0]
}
v := instances.GetOrSetFuncLock(group, func() any {
v := instances.GetOrSetFuncLock(group, func() DB {
db, err = NewByGroup(group)
return db
})
if v != nil {
return v.(DB), nil
return v, nil
}
return
return nil, err
}

// getConfigNodeByGroup calculates and returns a configuration node of given group. It
Expand Down
6 changes: 4 additions & 2 deletions database/gredis/gredis_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,10 @@ const (
)

var (
// configChecker checks whether the *Config is nil.
configChecker = func(v *Config) bool { return v == nil }
// Configuration groups.
localConfigMap = gmap.NewStrAnyMap(true)
localConfigMap = gmap.NewKVMapWithChecker[string, *Config](configChecker, true)
)

// SetConfig sets the global configuration for specified group.
Expand Down Expand Up @@ -119,7 +121,7 @@ func GetConfig(name ...string) (config *Config, ok bool) {
group = name[0]
}
if v := localConfigMap.Get(group); v != nil {
return v.(*Config), true
return v, true
}
return &Config{}, false
}
Expand Down
11 changes: 4 additions & 7 deletions database/gredis/gredis_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ import (
)

var (
// localInstances for instance management of redis client.
localInstances = gmap.NewStrAnyMap(true)
// checker is the checker function for instances map.
checker = func(v *Redis) bool { return v == nil }
localInstances = gmap.NewKVMapWithChecker[string, *Redis](checker, true)
)

// Instance returns an instance of redis client with specified group.
Expand All @@ -26,7 +27,7 @@ func Instance(name ...string) *Redis {
if len(name) > 0 && name[0] != "" {
group = name[0]
}
v := localInstances.GetOrSetFuncLock(group, func() any {
return localInstances.GetOrSetFuncLock(group, func() *Redis {
if config, ok := GetConfig(group); ok {
r, err := New(config)
if err != nil {
Expand All @@ -37,8 +38,4 @@ func Instance(name ...string) *Redis {
}
return nil
})
if v != nil {
return v.(*Redis)
}
return nil
}
8 changes: 5 additions & 3 deletions i18n/gi18n/gi18n_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ const (
)

var (
// checker is used for checking whether the value is nil.
checker = func(v *Manager) bool { return v == nil }
// instances is the instances map for management
// for multiple i18n instance by name.
instances = gmap.NewStrAnyMap(true)
instances = gmap.NewKVMapWithChecker[string, *Manager](checker, true)
)

// Instance returns an instance of Resource.
Expand All @@ -26,7 +28,7 @@ func Instance(name ...string) *Manager {
if len(name) > 0 && name[0] != "" {
key = name[0]
}
return instances.GetOrSetFuncLock(key, func() any {
return instances.GetOrSetFuncLock(key, func() *Manager {
return New()
}).(*Manager)
})
}
5 changes: 4 additions & 1 deletion net/ghttp/ghttp.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,9 +176,12 @@ var (
// It is used for quick HTTP method searching using map.
methodsMap = make(map[string]struct{})

// checker is used for checking whether the value is nil.
checker = func(v *Server) bool { return v == nil }

// serverMapping stores more than one server instances for current processes.
// The key is the name of the server, and the value is its instance.
serverMapping = gmap.NewStrAnyMap(true)
serverMapping = gmap.NewKVMapWithChecker[string, *Server](checker, true)

// serverRunning marks the running server counts.
// If there is no successful server running or all servers' shutdown, this value is 0.
Expand Down
10 changes: 4 additions & 6 deletions net/ghttp/ghttp_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ func GetServer(name ...any) *Server {
if len(name) > 0 && name[0] != "" {
serverName = gconv.String(name[0])
}
v := serverMapping.GetOrSetFuncLock(serverName, func() any {
return serverMapping.GetOrSetFuncLock(serverName, func() *Server {
s := &Server{
instance: serverName,
plugins: make([]Plugin, 0),
Expand All @@ -118,7 +118,6 @@ func GetServer(name ...any) *Server {
s.Use(internalMiddlewareServerTracing)
return s
})
return v.(*Server)
}

// Start starts listening on configured port.
Expand Down Expand Up @@ -477,10 +476,9 @@ func Wait() {
<-allShutdownChan

// Remove plugins.
serverMapping.Iterator(func(k string, v any) bool {
s := v.(*Server)
if len(s.plugins) > 0 {
for _, p := range s.plugins {
serverMapping.Iterator(func(k string, v *Server) bool {
if len(v.plugins) > 0 {
for _, p := range v.plugins {
intlog.Printf(ctx, `remove plugin: %s`, p.Name())
if err := p.Remove(); err != nil {
intlog.Errorf(ctx, `%+v`, err)
Expand Down
15 changes: 7 additions & 8 deletions net/ghttp/ghttp_server_admin_process.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,9 +190,9 @@ func forkRestartProcess(ctx context.Context, newExeFilePath ...string) error {
// getServerFdMap returns all the servers name to file descriptor mapping as map.
func getServerFdMap() map[string]listenerFdMap {
sfm := make(map[string]listenerFdMap)
serverMapping.RLockFunc(func(m map[string]any) {
serverMapping.RLockFunc(func(m map[string]*Server) {
for k, v := range m {
sfm[k] = v.(*Server).getListenerFdMap()
sfm[k] = v.getListenerFdMap()
}
})
return sfm
Expand Down Expand Up @@ -263,11 +263,10 @@ func shutdownWebServersGracefully(ctx context.Context, signal os.Signal) {
} else {
glog.Printf(ctx, "pid[%d]: server gracefully shutting down by api", gproc.Pid())
}
serverMapping.RLockFunc(func(m map[string]any) {
serverMapping.RLockFunc(func(m map[string]*Server) {
for _, v := range m {
server := v.(*Server)
server.doServiceDeregister()
for _, s := range server.servers {
v.doServiceDeregister()
for _, s := range v.servers {
s.Shutdown(ctx)
}
}
Expand All @@ -276,9 +275,9 @@ func shutdownWebServersGracefully(ctx context.Context, signal os.Signal) {

// forceCloseWebServers forced shuts down all servers.
func forceCloseWebServers(ctx context.Context) {
serverMapping.RLockFunc(func(m map[string]any) {
serverMapping.RLockFunc(func(m map[string]*Server) {
for _, v := range m {
for _, s := range v.(*Server).servers {
for _, s := range v.servers {
s.Close(ctx)
}
}
Expand Down
6 changes: 3 additions & 3 deletions net/ghttp/ghttp_server_router_serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,8 @@ func (s *Server) searchHandlers(method, path, domain string) (parsedItems []*Han
array = strings.Split(path[1:], "/")
}
var (
lastMiddlewareElem *glist.Element
parsedItemList = glist.New()
lastMiddlewareElem *glist.TElement[*HandlerItemParsed]
parsedItemList = glist.NewT[*HandlerItemParsed]()
repeatHandlerCheckMap = make(map[int]struct{}, 16)
)

Expand Down Expand Up @@ -245,7 +245,7 @@ func (s *Server) searchHandlers(method, path, domain string) (parsedItems []*Han
var index = 0
parsedItems = make([]*HandlerItemParsed, parsedItemList.Len())
for e := parsedItemList.Front(); e != nil; e = e.Next() {
parsedItems[index] = e.Value.(*HandlerItemParsed)
parsedItems[index] = e.Value
index++
}
}
Expand Down
7 changes: 4 additions & 3 deletions net/gtcp/gtcp_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,14 @@ const (
)

var (
poolChecker = func(v *gpool.Pool) bool { return v == nil }
// addressPoolMap is a mapping for address to its pool object.
addressPoolMap = gmap.NewStrAnyMap(true)
addressPoolMap = gmap.NewKVMapWithChecker[string, *gpool.Pool](poolChecker, true)
)

// NewPoolConn creates and returns a connection with pool feature.
func NewPoolConn(addr string, timeout ...time.Duration) (*PoolConn, error) {
v := addressPoolMap.GetOrSetFuncLock(addr, func() any {
v := addressPoolMap.GetOrSetFuncLock(addr, func() *gpool.Pool {
var pool *gpool.Pool
pool = gpool.New(defaultPoolExpire, func() (any, error) {
if conn, err := NewConn(addr, timeout...); err == nil {
Expand All @@ -47,7 +48,7 @@ func NewPoolConn(addr string, timeout ...time.Duration) (*PoolConn, error) {
})
return pool
})
value, err := v.(*gpool.Pool).Get()
value, err := v.Get()
if err != nil {
return nil, err
}
Expand Down
11 changes: 8 additions & 3 deletions net/gtcp/gtcp_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,12 @@ type Server struct {
}

// Map for name to server, for singleton purpose.
var serverMapping = gmap.NewStrAnyMap(true)
var (
// checker is used for checking whether the value is nil.
checker = func(v *Server) bool { return v == nil }
// serverMapping is the map for name to server.
serverMapping = gmap.NewKVMapWithChecker[any, *Server](checker, true)
)

// GetServer returns the TCP server with specified `name`,
// or it returns a new normal TCP server named `name` if it does not exist.
Expand All @@ -48,9 +53,9 @@ func GetServer(name ...any) *Server {
if len(name) > 0 && name[0] != "" {
serverName = gconv.String(name[0])
}
return serverMapping.GetOrSetFuncLock(serverName, func() any {
return serverMapping.GetOrSetFuncLock(serverName, func() *Server {
return NewServer("", nil)
}).(*Server)
})
}

// NewServer creates and returns a new normal TCP server.
Expand Down
13 changes: 6 additions & 7 deletions net/gudp/gudp_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,10 @@ type Server struct {
type ServerHandler func(conn *ServerConn)

var (
// checker is used for checking whether the value is nil.
checker = func(v *Server) bool { return v == nil }
// serverMapping is used for instance name to its UDP server mappings.
serverMapping = gmap.NewStrAnyMap(true)
serverMapping = gmap.NewKVMapWithChecker[string, *Server](checker, true)
)

// GetServer creates and returns an udp server instance with given name.
Expand All @@ -57,12 +59,9 @@ func GetServer(name ...any) *Server {
if len(name) > 0 && name[0] != "" {
serverName = gconv.String(name[0])
}
if s := serverMapping.Get(serverName); s != nil {
return s.(*Server)
}
s := NewServer("", nil)
serverMapping.Set(serverName, s)
return s
return serverMapping.GetOrSetFuncLock(serverName, func() *Server {
return NewServer("", nil)
})
}

// NewServer creates and returns an udp server.
Expand Down
20 changes: 9 additions & 11 deletions os/gcache/gcache_adapter_memory.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ import (

// AdapterMemory is an adapter implements using memory.
type AdapterMemory struct {
data *memoryData // data is the underlying cache data which is stored in a hash table.
expireTimes *memoryExpireTimes // expireTimes is the expiring key to its timestamp mapping, which is used for quick indexing and deleting.
expireSets *memoryExpireSets // expireSets is the expiring timestamp to its key set mapping, which is used for quick indexing and deleting.
lru *memoryLru // lru is the LRU manager, which is enabled when attribute cap > 0.
eventList *glist.List // eventList is the asynchronous event list for internal data synchronization.
closed *gtype.Bool // closed controls the cache closed or not.
data *memoryData // data is the underlying cache data which is stored in a hash table.
expireTimes *memoryExpireTimes // expireTimes is the expiring key to its timestamp mapping, which is used for quick indexing and deleting.
expireSets *memoryExpireSets // expireSets is the expiring timestamp to its key set mapping, which is used for quick indexing and deleting.
lru *memoryLru // lru is the LRU manager, which is enabled when attribute cap > 0.
eventList *glist.TList[*adapterMemoryEvent] // eventList is the asynchronous event list for internal data synchronization.
closed *gtype.Bool // closed controls the cache closed or not.
}

var _ Adapter = (*AdapterMemory)(nil)
Expand Down Expand Up @@ -61,7 +61,7 @@ func doNewAdapterMemory() *AdapterMemory {
data: newMemoryData(),
expireTimes: newMemoryExpireTimes(),
expireSets: newMemoryExpireSets(),
eventList: glist.New(true),
eventList: glist.NewT[*adapterMemoryEvent](true),
closed: gtype.NewBool(),
}
// Here may be a "timer leak" if adapter is manually changed from adapter_memory adapter.
Expand Down Expand Up @@ -414,19 +414,17 @@ func (c *AdapterMemory) syncEventAndClearExpired(ctx context.Context) {
return
}
var (
event *adapterMemoryEvent
oldExpireTime int64
newExpireTime int64
)
// ================================
// Data expiration synchronization.
// ================================
for {
v := c.eventList.PopFront()
if v == nil {
event := c.eventList.PopFront()
if event == nil {
break
}
event = v.(*adapterMemoryEvent)
// Fetching the old expire set.
oldExpireTime = c.expireTimes.Get(event.k)
// Calculating the new expiration time set.
Expand Down
20 changes: 11 additions & 9 deletions os/gcache/gcache_adapter_memory_lru.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,23 @@ import (
"github.com/gogf/gf/v2/container/gmap"
)

// checker is used to check if the value is nil.
var checker = func(v *glist.Element) bool { return v == nil }

// memoryLru holds LRU info.
// It uses list.List from stdlib for its underlying doubly linked list.
type memoryLru struct {
mu sync.RWMutex // Mutex to guarantee concurrent safety.
cap int // LRU cap.
data *gmap.Map // Key mapping to the item of the list.
list *glist.List // Key list.
mu sync.RWMutex // Mutex to guarantee concurrent safety.
cap int // LRU cap.
data *gmap.KVMap[any, *glist.Element] // Key mapping to the item of the list.
list *glist.List // Key list.
}

// newMemoryLru creates and returns a new LRU manager.
func newMemoryLru(cap int) *memoryLru {
lru := &memoryLru{
cap: cap,
data: gmap.New(false),
data: gmap.NewKVMapWithChecker[any, *glist.Element](checker, false),
list: glist.New(false),
}
return lru
Expand All @@ -41,7 +44,7 @@ func (l *memoryLru) Remove(keys ...any) {
defer l.mu.Unlock()
for _, key := range keys {
if v := l.data.Remove(key); v != nil {
l.list.Remove(v.(*glist.Element))
l.list.Remove(v)
}
}
}
Expand All @@ -63,9 +66,8 @@ func (l *memoryLru) SaveAndEvict(keys ...any) (evictedKeys []any) {
}

func (l *memoryLru) doSaveAndEvict(key any) (evictedKey any) {
var element *glist.Element
if v := l.data.Get(key); v != nil {
element = v.(*glist.Element)
element := l.data.Get(key)
if element != nil {
if element.Prev() == nil {
// It this element is already on top of list,
// it ignores the element moving.
Expand Down
Loading
Loading