代码拉取完成,页面将自动刷新
package main
import (
"fmt"
"runtime"
"strconv"
"strings"
"sync"
"time"
)
// Signed is a constraint that permits any signed integer type.
// If future releases of Go add new predeclared signed integer types,
// this constraint will be modified to include them.
type Signed interface {
~int | ~int8 | ~int16 | ~int32 | ~int64
}
// Unsigned is a constraint that permits any unsigned integer type.
// If future releases of Go add new predeclared unsigned integer types,
// this constraint will be modified to include them.
type Unsigned interface {
~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
}
// Integer is a constraint that permits any integer type.
// If future releases of Go add new predeclared integer types,
// this constraint will be modified to include them.
type Integer interface {
Signed | Unsigned
}
// Float is a constraint that permits any floating-point type.
// If future releases of Go add new predeclared floating-point types,
// this constraint will be modified to include them.
type Float interface {
~float32 | ~float64
}
// Complex is a constraint that permits any complex numeric type.
// If future releases of Go add new predeclared complex numeric types,
// this constraint will be modified to include them.
type Complex interface {
~complex64 | ~complex128
}
// Ordered is a constraint that permits any ordered type: any type
// that supports the operators < <= >= >.
// If future releases of Go add new ordered types,
// this constraint will be modified to include them.
type Ordered interface {
Integer | Float | ~string
}
// GenericCache 泛型缓存
type GenericCache[K Ordered, V any] struct { // 使用 Ordered
cache map[K]V
cacheCleanTime map[K]int64
updateTime int64
mu sync.RWMutex
}
// checkGoVersion 检查当前 Go 版本是否支持泛型
func checkGoVersionCanUseGenerics() error {
v := runtime.Version()
parts := strings.Split(v, ".")
major, err := strconv.Atoi(parts[1])
if err != nil {
return fmt.Errorf("failed to parse Go version: %v", err)
}
minor, err := strconv.Atoi(parts[2])
if err != nil {
return fmt.Errorf("failed to parse Go version: %v", err)
}
if major < 1 || (major == 1 && minor < 18) {
return fmt.Errorf("your Go version (%s) does not support generics. Please upgrade to Go 1.18 or later.", v)
}
return nil
}
// NewGenericCache 创建一个新的泛型缓存
func NewGenericCache[K Ordered, V any]() (*GenericCache[K, V], error) {
if err := checkGoVersionCanUseGenerics(); err != nil {
return nil, err
}
return &GenericCache[K, V]{
cache: make(map[K]V), cacheCleanTime: make(map[K]int64),
}, nil
}
// Set 设置缓存项
func (c *GenericCache[K, V]) Set(key K, value V, cleanTime int64) {
c.mu.Lock()
defer c.mu.Unlock()
now := time.Now()
timestampMs := now.UnixMilli()
if cleanTime > 0 {
c.cacheCleanTime[key] = timestampMs + cleanTime
} else {
c.cacheCleanTime[key] = -1
}
c.updateTime = timestampMs
c.cache[key] = value
}
// Get 获取缓存项
func (c *GenericCache[K, V]) Get(key K) (V, bool) {
c.mu.RLock()
var zeroValue V
defer c.mu.RUnlock()
if c.cacheCleanTime[key] > 0 && time.Now().UnixMilli() > c.cacheCleanTime[key] {
return zeroValue, false
}
value, ok := c.cache[key]
return value, ok
}
// ShowAllKey 获取所有缓存key
func (c *GenericCache[K, V]) ShowAllKey(isShowExpired bool) []K {
nowUnixMilli := time.Now().UnixMilli()
keys := make([]K, 0)
c.mu.RLock()
defer c.mu.RUnlock()
for key := range c.cache {
if !isShowExpired && c.cacheCleanTime[key] > 0 && nowUnixMilli > c.cacheCleanTime[key] {
continue
}
keys = append(keys, key)
}
return keys
}
// Del 删除某个Key
func (c *GenericCache[K, V]) Del(key K) {
c.mu.Lock()
defer c.mu.Unlock()
delete(c.cacheCleanTime, key)
delete(c.cache, key)
}
// cleanupExpired 清理过期缓存
func (c *GenericCache[K, V]) CleanupExpired() {
nowUnixMilli := time.Now().UnixMilli()
keys := make([]K, 0)
c.mu.RLock()
for key, cleanTime := range c.cacheCleanTime {
if cleanTime > 0 && nowUnixMilli > cleanTime {
keys = append(keys, key)
}
}
c.mu.RUnlock()
for _, cleanKey := range keys {
cleanNowUnixMilli := time.Now().UnixMilli()
c.mu.Lock()
thiscleanKeycacheCleanTime := c.cacheCleanTime[cleanKey]
if thiscleanKeycacheCleanTime > 0 && cleanNowUnixMilli > thiscleanKeycacheCleanTime {
delete(c.cacheCleanTime, cleanKey)
delete(c.cache, cleanKey)
}
c.mu.Unlock()
}
}
func (c *GenericCache[K, V]) UnSafeRlock() {
c.mu.RLock()
}
func (c *GenericCache[K, V]) UnSafeRUnlock() {
c.mu.RUnlock()
}
func (c *GenericCache[K, V]) UnSafeLock() {
c.mu.Lock()
}
func (c *GenericCache[K, V]) UnSafeUnLock() {
c.mu.Unlock()
}
func (c *GenericCache[K, V]) UnSafeGet(key K) (V, bool) {
value, ok := c.cache[key]
return value, ok
}
func (c *GenericCache[K, V]) UnSafeSet(key K, value V, cleanTime int64) {
now := time.Now()
timestampMs := now.UnixMilli()
if cleanTime > 0 {
c.cacheCleanTime[key] = timestampMs + cleanTime
} else {
c.cacheCleanTime[key] = -1
}
c.updateTime = timestampMs
c.cache[key] = value
}
/*
func main() {
// 获取 Unix 时间戳(毫秒)
now := time.Now()
timestampMs := now.UnixMilli()
fmt.Println("Unix 时间戳(毫秒):", timestampMs)
stringCache, err := NewGenericCache[string, string]()
if err != nil {
fmt.Println(err)
return
}
intCache, err := NewGenericCache[int, time.Time]()
if err != nil {
fmt.Println(err)
return
}
stringCache.Set("name", "John Doe", 100)
intCache.Set(1, time.Now(), -1)
stringCache.Set("name2", "John Doe2", 888000)
stringCache.Set("name3", "John Doe2", -1)
fmt.Println(stringCache.ShowAllKey(false))
stringCache.Del("name2")
fmt.Println(stringCache.ShowAllKey(false))
name, found := stringCache.Get("name")
if found {
fmt.Println("Name:", name)
}
timestamp, found := intCache.Get(1)
if found {
fmt.Println("Timestamp:", timestamp)
}
time.Sleep(time.Millisecond * 150)
fmt.Println(stringCache.ShowAllKey(false))
fmt.Println(stringCache.ShowAllKey(true))
stringCache.CleanupExpired()
fmt.Println(stringCache.ShowAllKey(true))
fmt.Println(stringCache.UnSafeGet("name3"))
stringCache.UnSafeLock()
stringCache.UnSafeSet("name5", "John Doe5", 888000)
fmt.Println(stringCache.UnSafeGet("name5"))
stringCache.UnSafeUnLock()
}
*/
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。