diff --git a/client/cache.go b/client/cache.go index 5859e48..b4f3c5a 100644 --- a/client/cache.go +++ b/client/cache.go @@ -1,6 +1,8 @@ package client import ( + "time" + "github.com/LagrangeDev/LagrangeGo/client/entity" ) @@ -95,22 +97,44 @@ func (c *QQClient) GetCachedMembersInfo(groupUin uint32) map[uint32]*entity.Grou // GetCachedRkeyInfo 获取指定类型的RKey信息(缓存) func (c *QQClient) GetCachedRkeyInfo(rkeyType entity.RKeyType) *entity.RKeyInfo { - if c.cache.RkeyInfoCacheIsEmpty() || c.cache.RkeyInfoCacheIsExpired() { - if err := c.RefreshAllRkeyInfoCache(); err != nil { - return nil + refresh := c.cache.RkeyInfoCacheIsEmpty() + for { + if refresh { + if err := c.RefreshAllRkeyInfoCache(); err != nil { + return nil + } + } + inf := c.cache.GetRKeyInfo(rkeyType) + if inf.ExpireTime <= uint64(time.Now().Unix()) { + refresh = true + continue } + return inf } - return c.cache.GetRKeyInfo(rkeyType) } // GetCachedRkeyInfos 获取所有RKey信息(缓存) func (c *QQClient) GetCachedRkeyInfos() map[entity.RKeyType]*entity.RKeyInfo { - if c.cache.RkeyInfoCacheIsEmpty() || c.cache.RkeyInfoCacheIsExpired() { - if err := c.RefreshAllRkeyInfoCache(); err != nil { - return nil + refresh := c.cache.RkeyInfoCacheIsEmpty() + for { + if refresh { + if err := c.RefreshAllRkeyInfoCache(); err != nil { + return nil + } + refresh = false + } + inf := c.cache.GetAllRkeyInfo() + for _, v := range inf { + if v.ExpireTime <= uint64(time.Now().Unix()) { + refresh = true + break + } + } + if refresh { + continue } + return inf } - return c.cache.GetAllRkeyInfo() } // RefreshFriendCache 刷新好友缓存 diff --git a/client/internal/cache/base.go b/client/internal/cache/base.go index 8147c93..4fc73e1 100644 --- a/client/internal/cache/base.go +++ b/client/internal/cache/base.go @@ -2,7 +2,6 @@ package cache import ( "reflect" - "time" "unsafe" "github.com/LagrangeDev/LagrangeGo/client/entity" @@ -11,9 +10,7 @@ import ( type ( cacheType uint32 - KeyType interface { - ~uint32 - } + keyType interface{ ~uint32 } ) const ( @@ -37,13 +34,12 @@ var cacheTypesMap = map[string]cacheType{ } type Cache struct { - m syncx.Map[uint64, unsafe.Pointer] - refreshed syncx.Map[cacheType, struct{}] - expiredTime syncx.Map[cacheType, int64] + m syncx.Map[uint64, unsafe.Pointer] + refreshed syncx.Map[cacheType, struct{}] } func hasRefreshed[T any](c *Cache) bool { - typ := cacheTypesMap[reflect.ValueOf((*T)(nil)).Type().String()] + typ := cacheTypesMap[typenameof[T]()] if typ == 0 { return false } @@ -51,17 +47,8 @@ func hasRefreshed[T any](c *Cache) bool { return ok } -func hasExpired[T any](c *Cache) bool { - typ := cacheTypesMap[reflect.ValueOf((*T)(nil)).Type().String()] - if typ == 0 { - return false - } - v, ok := c.expiredTime.Load(typ) - return ok && v <= time.Now().Unix() -} - -func refreshAllCacheOf[T any, K KeyType](c *Cache, newcache map[K]*T) { - typstr := reflect.ValueOf((*T)(nil)).Type().String() +func refreshAllCacheOf[T any, K keyType](c *Cache, newcache map[K]*T) { + typstr := typenameof[T]() typ := cacheTypesMap[typstr] if typ == 0 { return @@ -85,12 +72,7 @@ func refreshAllCacheOf[T any, K KeyType](c *Cache, newcache map[K]*T) { } } -func refreshAllExpiredCacheOf[T any, K KeyType](c *Cache, newcache map[K]*T, newextime int64) { - refreshAllCacheOf(c, newcache) - c.expiredTime.Store(cacheTypesMap[reflect.ValueOf((*T)(nil)).Type().String()], newextime) -} - -func setCacheOf[T any, K KeyType](c *Cache, k K, v *T) { +func setCacheOf[T any, K keyType](c *Cache, k K, v *T) { typstr := reflect.ValueOf(v).Type().String() typ := cacheTypesMap[typstr] if typ == 0 { @@ -100,7 +82,7 @@ func setCacheOf[T any, K KeyType](c *Cache, k K, v *T) { c.m.Store(key, unsafe.Pointer(v)) } -func getCacheOf[T any, K KeyType](c *Cache, k K) (v *T, ok bool) { +func getCacheOf[T any, K keyType](c *Cache, k K) (v *T, ok bool) { typstr := reflect.ValueOf(v).Type().String() typ := cacheTypesMap[typstr] if typ == 0 { @@ -114,8 +96,8 @@ func getCacheOf[T any, K KeyType](c *Cache, k K) (v *T, ok bool) { return } -func rangeCacheOf[T any, K KeyType](c *Cache, iter func(k K, v *T) bool) { - typ := cacheTypesMap[reflect.ValueOf((*T)(nil)).Type().String()] +func rangeCacheOf[T any, K keyType](c *Cache, iter func(k K, v *T) bool) { + typ := cacheTypesMap[typenameof[T]()] if typ == 0 { return } diff --git a/client/internal/cache/cache.go b/client/internal/cache/cache.go index c2e9ebf..c7ef417 100644 --- a/client/internal/cache/cache.go +++ b/client/internal/cache/cache.go @@ -1,6 +1,8 @@ package cache -import "github.com/LagrangeDev/LagrangeGo/client/entity" +import ( + "github.com/LagrangeDev/LagrangeGo/client/entity" +) // GetUid 根据uin获取uid func (c *Cache) GetUid(uin uint32, groupUin ...uint32) string { @@ -88,7 +90,7 @@ func (c *Cache) GetGroupMember(uin, groupUin uint32) *entity.GroupMember { func (c *Cache) GetGroupMembers(groupUin uint32) map[uint32]*entity.GroupMember { members := make(map[uint32]*entity.GroupMember, 64) if group, ok := getCacheOf[Cache](c, groupUin); ok { - rangeCacheOf[entity.GroupMember](group, func(k uint32, member *entity.GroupMember) bool { + rangeCacheOf(group, func(k uint32, member *entity.GroupMember) bool { members[member.Uin] = member return true }) @@ -105,7 +107,7 @@ func (c *Cache) GetRKeyInfo(rkeyType entity.RKeyType) *entity.RKeyInfo { // GetAllRkeyInfo 获取所有RKey信息 func (c *Cache) GetAllRkeyInfo() entity.RKeyMap { infos := make(map[entity.RKeyType]*entity.RKeyInfo, 2) - rangeCacheOf[entity.RKeyInfo](c, func(k entity.RKeyType, v *entity.RKeyInfo) bool { + rangeCacheOf(c, func(k entity.RKeyType, v *entity.RKeyInfo) bool { infos[k] = v return true }) @@ -139,7 +141,3 @@ func (c *Cache) GroupInfoCacheIsEmpty() bool { func (c *Cache) RkeyInfoCacheIsEmpty() bool { return !hasRefreshed[entity.RKeyInfo](c) } - -func (c *Cache) RkeyInfoCacheIsExpired() bool { - return hasExpired[entity.RKeyInfo](c) -} diff --git a/client/internal/cache/operation.go b/client/internal/cache/operation.go index 378355e..ecfcd26 100644 --- a/client/internal/cache/operation.go +++ b/client/internal/cache/operation.go @@ -2,10 +2,14 @@ package cache import ( "github.com/LagrangeDev/LagrangeGo/client/entity" - "math" ) -func (c *Cache) RefreshAll(friendCache map[uint32]*entity.Friend, groupCache map[uint32]*entity.Group, groupMemberCache map[uint32]map[uint32]*entity.GroupMember, rkeyCache entity.RKeyMap) { +func (c *Cache) RefreshAll( + friendCache map[uint32]*entity.Friend, + groupCache map[uint32]*entity.Group, + groupMemberCache map[uint32]map[uint32]*entity.GroupMember, + rkeyCache entity.RKeyMap, +) { c.RefreshAllFriend(friendCache) c.RefreshAllGroup(groupCache) c.RefreshAllGroupMembers(groupMemberCache) @@ -64,10 +68,5 @@ func (c *Cache) RefreshAllGroup(groupCache map[uint32]*entity.Group) { // RefreshAllRKeyInfo 刷新所有RKey缓存 func (c *Cache) RefreshAllRKeyInfo(rkeyCache entity.RKeyMap) { - var expTime int64 = math.MaxInt64 - for _, ext := range rkeyCache { - expTime = int64(ext.ExpireTime) - break - } - refreshAllExpiredCacheOf(c, rkeyCache, expTime) + refreshAllCacheOf(c, rkeyCache) }