Optimize asset cache lookups and add accessors (#16894)

* optimize asset cache lookups and add accessors.

* adopt cache.FilterAssets to optimize asset processing.
This commit is contained in:
Jane Haring 2026-02-07 10:00:49 +08:00 committed by GitHub
parent 3f3db3c34f
commit 82647de886
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 75 additions and 25 deletions

38
kernel/cache/asset.go vendored
View file

@ -104,17 +104,53 @@ var (
assetsLock = sync.Mutex{}
)
// GetAssets 返回所有资源的副本
func GetAssets() (ret map[string]*Asset) {
assetsLock.Lock()
defer assetsLock.Unlock()
ret = map[string]*Asset{}
// 指定长度避免分配新内存时扩容和迁移
ret = make(map[string]*Asset, len(assetsCache))
for k, v := range assetsCache {
ret[k] = v
}
return
}
// IterateAssets 遍历所有资源,适合只读场景
func IterateAssets(fn func(path string, asset *Asset) bool) {
assetsLock.Lock()
defer assetsLock.Unlock()
for path, asset := range assetsCache {
if !fn(path, asset) {
break
}
}
}
// FilterAssets 根据过滤函数返回符合条件的资源
func FilterAssets(filter func(path string, asset *Asset) bool) (ret map[string]*Asset) {
assetsLock.Lock()
defer assetsLock.Unlock()
ret = make(map[string]*Asset)
for path, asset := range assetsCache {
if filter(path, asset) {
ret[path] = asset
}
}
return
}
// GetAssetByPath 根据路径获取资源
func GetAssetByPath(path string) *Asset {
assetsLock.Lock()
defer assetsLock.Unlock()
return assetsCache[path]
}
func RemoveAsset(path string) {
assetsLock.Lock()
defer assetsLock.Unlock()

View file

@ -448,7 +448,9 @@ func SearchAssetsByName(keyword string, exts []string) (ret []*cache.Asset) {
}
pathHitCount := map[string]int{}
filterByExt := 0 < len(exts)
for _, asset := range cache.GetAssets() {
matchedAssets := cache.FilterAssets(func(path string, asset *cache.Asset) bool {
// 扩展名过滤
if filterByExt {
ext := filepath.Ext(asset.HName)
includeExt := false
@ -459,10 +461,11 @@ func SearchAssetsByName(keyword string, exts []string) (ret []*cache.Asset) {
}
}
if !includeExt {
continue
return false
}
}
// 关键字匹配
lowerHName := strings.ToLower(asset.HName)
lowerPath := strings.ToLower(asset.Path)
var hitNameCount, hitPathCount int
@ -485,13 +488,21 @@ func SearchAssetsByName(keyword string, exts []string) (ret []*cache.Asset) {
}
}
// 只返回有匹配的资源
if 1 > hitNameCount+hitPathCount {
continue
return false
}
pathHitCount[asset.Path] += hitNameCount + hitPathCount
// 记录命中次数用于排序
pathHitCount[asset.Path] = hitNameCount + hitPathCount
return true
})
// 添加高亮
for _, asset := range matchedAssets {
hitCount := pathHitCount[asset.Path]
hName := asset.HName
if 0 < hitNameCount {
if hitCount > 0 {
_, hName = search.MarkText(asset.HName, strings.Join(keywords, search.TermSep), 64, Conf.Search.CaseSensitive)
}
ret = append(ret, &cache.Asset{

View file

@ -770,15 +770,21 @@ func (box *Box) recentModifiedDocs() (ret []string) {
var assetsLatestHistoryTime = time.Now().Unix()
func recentModifiedAssets() (ret []string) {
assets := cache.GetAssets()
for _, asset := range assets {
if asset.Updated > assetsLatestHistoryTime {
absPath := filepath.Join(util.DataDir, asset.Path)
if filelock.IsHidden(absPath) {
continue
}
ret = append(ret, absPath)
// 只获取最近修改的资源
recentAssets := cache.FilterAssets(func(path string, asset *cache.Asset) bool {
if asset.Updated <= assetsLatestHistoryTime {
return false
}
absPath := filepath.Join(util.DataDir, asset.Path)
if filelock.IsHidden(absPath) {
return false
}
return true
})
for _, asset := range recentAssets {
absPath := filepath.Join(util.DataDir, asset.Path)
ret = append(ret, absPath)
}
assetsLatestHistoryTime = time.Now().Unix()
return

View file

@ -55,21 +55,18 @@ func autoOCRAssets() {
}
func getUnOCRAssetsAbsPaths() (ret []string) {
var assetsPaths []string
assets := cache.GetAssets()
for _, asset := range assets {
if !util.IsTesseractExtractable(asset.Path) {
continue
}
assetsPaths = append(assetsPaths, asset.Path)
}
// 只获取需要 OCR 的资源
ocrAssets := cache.FilterAssets(func(path string, asset *cache.Asset) bool {
return util.IsTesseractExtractable(asset.Path)
})
assetsPath := util.GetDataAssetsAbsPath()
for _, assetPath := range assetsPaths {
if util.ExistsAssetText(assetPath) {
for _, asset := range ocrAssets {
// 跳过已经存在 OCR 文本的资源
if util.ExistsAssetText(asset.Path) {
continue
}
absPath := filepath.Join(assetsPath, strings.TrimPrefix(assetPath, "assets"))
absPath := filepath.Join(assetsPath, strings.TrimPrefix(asset.Path, "assets"))
ret = append(ret, absPath)
}
return