Files
EdgeNode/internal/cache/cache.go

105 lines
2.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package cache
import (
"time"
)
// TTL缓存
// 最大的缓存时间为30 * 86400
// Piece数据结构
// Piece1 | Piece2 | Piece3 | ...
// [ Item1, Item2, ... | ...
// KeyMap列表数据结构
// { timestamp1 => [key1, key2, ...] }, ...
type Cache struct {
pieces []*Piece
countPieces uint64
gcPieceIndex int
}
func NewCache(opt ...OptionInterface) *Cache {
countPieces := 128
for _, option := range opt {
if option == nil {
continue
}
switch o := option.(type) {
case *PiecesOption:
if o.Count > 0 {
countPieces = o.Count
}
}
}
cache := &Cache{
countPieces: uint64(countPieces),
}
for i := 0; i < countPieces; i++ {
cache.pieces = append(cache.pieces, NewPiece())
}
// start timer
go func() {
ticker := time.NewTicker(1 * time.Second)
for range ticker.C {
cache.GC()
}
}()
return cache
}
func (this *Cache) Add(key string, value interface{}, expiredAt int64) {
currentTimestamp := time.Now().Unix()
if expiredAt <= currentTimestamp {
return
}
maxExpiredAt := currentTimestamp + 30*86400
if expiredAt > maxExpiredAt {
expiredAt = maxExpiredAt
}
uint64Key := HashKey([]byte(key))
pieceIndex := uint64Key % this.countPieces
this.pieces[pieceIndex].Add(uint64Key, &Item{
value: value,
expiredAt: expiredAt,
})
}
func (this *Cache) Read(key string) (value *Item) {
uint64Key := HashKey([]byte(key))
return this.pieces[uint64Key%this.countPieces].Read(uint64Key)
}
func (this *Cache) readIntKey(key uint64) (value *Item) {
return this.pieces[key%this.countPieces].Read(key)
}
func (this *Cache) Delete(key string) {
uint64Key := HashKey([]byte(key))
this.pieces[uint64Key%this.countPieces].Delete(uint64Key)
}
func (this *Cache) deleteIntKey(key uint64) {
this.pieces[key%this.countPieces].Delete(key)
}
func (this *Cache) Count() (count int) {
for _, piece := range this.pieces {
count += piece.Count()
}
return
}
func (this *Cache) GC() {
this.pieces[this.gcPieceIndex].GC()
newIndex := this.gcPieceIndex + 1
if newIndex >= int(this.countPieces) {
newIndex = 0
}
this.gcPieceIndex = newIndex
}