mirror of
https://github.com/TeaOSLab/EdgeNode.git
synced 2025-11-03 23:20:25 +08:00
[缓存]实现按照目录刷新缓存
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
package caches
|
||||
|
||||
import "sync"
|
||||
import (
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// 缓存列表管理
|
||||
type List struct {
|
||||
@@ -43,6 +46,20 @@ func (this *List) Exist(hash string) bool {
|
||||
return !item.IsExpired()
|
||||
}
|
||||
|
||||
// 根据前缀进行查找
|
||||
func (this *List) FindKeysWithPrefix(prefix string) (keys []string) {
|
||||
this.locker.RLock()
|
||||
defer this.locker.RUnlock()
|
||||
|
||||
// TODO 需要优化性能,支持千万级数据低于1s的处理速度
|
||||
for _, item := range this.m {
|
||||
if strings.HasPrefix(item.Key, prefix) {
|
||||
keys = append(keys, item.Key)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (this *List) Remove(hash string) {
|
||||
this.locker.Lock()
|
||||
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
package caches
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/cespare/xxhash"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
@@ -94,3 +97,23 @@ func TestList_Stat(t *testing.T) {
|
||||
})
|
||||
t.Log(result)
|
||||
}
|
||||
|
||||
func TestList_FindKeysWithPrefix(t *testing.T) {
|
||||
list := NewList()
|
||||
before := time.Now()
|
||||
for i := 0; i < 1_000_000; i++ {
|
||||
key := "http://www.teaos.cn/hello" + strconv.Itoa(i/100000) + "/" + strconv.Itoa(i) + ".html"
|
||||
list.Add(fmt.Sprintf("%d", xxhash.Sum64String(key)), &Item{
|
||||
Key: key,
|
||||
ExpiredAt: 0,
|
||||
ValueSize: 0,
|
||||
Size: 0,
|
||||
})
|
||||
}
|
||||
t.Log(time.Since(before).Seconds()*1000, "ms")
|
||||
|
||||
before = time.Now()
|
||||
keys := list.FindKeysWithPrefix("http://www.teaos.cn/hello/5000")
|
||||
t.Log(len(keys))
|
||||
t.Log(time.Since(before).Seconds()*1000, "ms")
|
||||
}
|
||||
|
||||
@@ -468,10 +468,20 @@ func (this *FileStorage) CleanAll() error {
|
||||
}
|
||||
|
||||
// 清理过期的缓存
|
||||
func (this *FileStorage) Purge(keys []string) error {
|
||||
func (this *FileStorage) Purge(keys []string, urlType string) error {
|
||||
this.locker.Lock()
|
||||
defer this.locker.Unlock()
|
||||
|
||||
// 目录
|
||||
if urlType == "dir" {
|
||||
resultKeys := []string{}
|
||||
for _, key := range keys {
|
||||
resultKeys = append(resultKeys, this.list.FindKeysWithPrefix(key)...)
|
||||
}
|
||||
keys = resultKeys
|
||||
}
|
||||
|
||||
// 文件
|
||||
for _, key := range keys {
|
||||
hash, path := this.keyPath(key)
|
||||
if !this.list.Exist(hash) {
|
||||
|
||||
@@ -235,7 +235,7 @@ func TestFileStorage_Purge(t *testing.T) {
|
||||
t.Log(time.Since(before).Seconds()*1000, "ms")
|
||||
}()
|
||||
|
||||
err = storage.Purge([]string{"a", "b1", "c"})
|
||||
err = storage.Purge([]string{"a", "b1", "c"}, "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ type StorageInterface interface {
|
||||
CleanAll() error
|
||||
|
||||
// 批量删除缓存
|
||||
Purge(keys []string) error
|
||||
Purge(keys []string, urlType string) error
|
||||
|
||||
// 停止缓存策略
|
||||
Stop()
|
||||
|
||||
@@ -134,7 +134,16 @@ func (this *MemoryStorage) CleanAll() error {
|
||||
}
|
||||
|
||||
// 批量删除缓存
|
||||
func (this *MemoryStorage) Purge(keys []string) error {
|
||||
func (this *MemoryStorage) Purge(keys []string, urlType string) error {
|
||||
// 目录
|
||||
if urlType == "dir" {
|
||||
resultKeys := []string{}
|
||||
for _, key := range keys {
|
||||
resultKeys = append(resultKeys, this.list.FindKeysWithPrefix(key)...)
|
||||
}
|
||||
keys = resultKeys
|
||||
}
|
||||
|
||||
for _, key := range keys {
|
||||
err := this.Delete(key)
|
||||
if err != nil {
|
||||
|
||||
@@ -185,7 +185,7 @@ func TestMemoryStorage_Purge(t *testing.T) {
|
||||
ExpiredAt: expiredAt,
|
||||
})
|
||||
}
|
||||
err := storage.Purge([]string{"abc", "abc1"})
|
||||
err := storage.Purge([]string{"abc", "abc1"}, "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -306,7 +306,7 @@ func (this *APIStream) handlePurgeCache(message *pb.NodeStreamMessage) error {
|
||||
}()
|
||||
}
|
||||
|
||||
err = storage.Purge(msg.Keys)
|
||||
err = storage.Purge(msg.Keys, msg.Type)
|
||||
if err != nil {
|
||||
this.replyFail(message.RequestId, "purge keys failed: "+err.Error())
|
||||
return err
|
||||
|
||||
Reference in New Issue
Block a user