mirror of
https://github.com/snowykami/neo-blog.git
synced 2025-09-03 15:56:22 +00:00
120 lines
2.3 KiB
Go
120 lines
2.3 KiB
Go
package utils
|
||
|
||
import (
|
||
"sync"
|
||
"time"
|
||
)
|
||
|
||
type kvStoreUtils struct{}
|
||
|
||
var KV kvStoreUtils
|
||
|
||
// KVStore 是一个简单的内存键值存储系统
|
||
type KVStore struct {
|
||
data map[string]storeItem
|
||
mutex sync.RWMutex
|
||
}
|
||
|
||
// storeItem 代表存储的单个数据项
|
||
type storeItem struct {
|
||
value interface{}
|
||
expiration int64 // Unix时间戳,0表示永不过期
|
||
}
|
||
|
||
// 全局单例
|
||
var (
|
||
kvStore *KVStore
|
||
kvStoreOnce sync.Once
|
||
)
|
||
|
||
// GetInstance 获取KVStore单例实例
|
||
func (kv *kvStoreUtils) GetInstance() *KVStore {
|
||
kvStoreOnce.Do(func() {
|
||
kvStore = &KVStore{
|
||
data: make(map[string]storeItem),
|
||
}
|
||
// 启动清理过期项的协程
|
||
go kvStore.startCleanupTimer()
|
||
})
|
||
return kvStore
|
||
}
|
||
|
||
// Set 设置键值对,可选指定过期时间
|
||
func (s *KVStore) Set(key string, value interface{}, ttl time.Duration) {
|
||
s.mutex.Lock()
|
||
defer s.mutex.Unlock()
|
||
|
||
var expiration int64
|
||
if ttl > 0 {
|
||
expiration = time.Now().Add(ttl).Unix()
|
||
}
|
||
|
||
s.data[key] = storeItem{
|
||
value: value,
|
||
expiration: expiration,
|
||
}
|
||
}
|
||
|
||
// Get 获取键对应的值,如果键不存在或已过期则返回(nil, false)
|
||
func (s *KVStore) Get(key string) (interface{}, bool) {
|
||
s.mutex.RLock()
|
||
defer s.mutex.RUnlock()
|
||
|
||
item, exists := s.data[key]
|
||
if !exists {
|
||
return nil, false
|
||
}
|
||
|
||
// 检查是否过期
|
||
if item.expiration > 0 && time.Now().Unix() > item.expiration {
|
||
return nil, false
|
||
}
|
||
|
||
return item.value, true
|
||
}
|
||
|
||
// Delete 删除键值对
|
||
func (s *KVStore) Delete(key string) {
|
||
s.mutex.Lock()
|
||
defer s.mutex.Unlock()
|
||
|
||
delete(s.data, key)
|
||
}
|
||
|
||
// Clear 清空所有键值对
|
||
func (s *KVStore) Clear() {
|
||
s.mutex.Lock()
|
||
defer s.mutex.Unlock()
|
||
|
||
s.data = make(map[string]storeItem)
|
||
}
|
||
|
||
// startCleanupTimer 启动定期清理过期项的计时器
|
||
func (s *KVStore) startCleanupTimer() {
|
||
ticker := time.NewTicker(5 * time.Minute)
|
||
defer ticker.Stop()
|
||
|
||
for range ticker.C {
|
||
s.cleanup()
|
||
}
|
||
}
|
||
|
||
// cleanup 清理过期的数据项
|
||
func (s *KVStore) cleanup() {
|
||
s.mutex.Lock()
|
||
defer s.mutex.Unlock()
|
||
|
||
now := time.Now().Unix()
|
||
for key, item := range s.data {
|
||
if item.expiration > 0 && now > item.expiration {
|
||
delete(s.data, key)
|
||
}
|
||
}
|
||
}
|
||
|
||
// secureRand 生成0到max-1之间的安全随机数
|
||
func secureRand(max int) int {
|
||
// 简单实现,可以根据需要使用crypto/rand替换
|
||
return int(time.Now().UnixNano() % int64(max))
|
||
}
|