Improve data indexing to reduce disk read operations https://github.com/siyuan-note/siyuan/issues/16958

Signed-off-by: Daniel <845765@qq.com>
This commit is contained in:
Daniel 2026-02-06 18:25:48 +08:00
parent dc00060062
commit 87282404bb
No known key found for this signature in database
GPG key ID: 86211BA83DF03017
4 changed files with 65 additions and 45 deletions

33
kernel/cache/asset.go vendored
View file

@ -34,25 +34,45 @@ type AssetHash struct {
}
var (
assetHashCache = map[string]*AssetHash{}
assetHashLock = sync.Mutex{}
assetHashCache = map[string]*AssetHash{}
assetPathHashCache = map[string]*AssetHash{}
assetHashLock = sync.Mutex{}
)
func RemoveAssetHash(hash string) {
assetHashLock.Lock()
defer assetHashLock.Unlock()
delete(assetHashCache, hash)
asset := assetHashCache[hash]
if nil != asset {
delete(assetHashCache, hash)
delete(assetPathHashCache, asset.Path)
}
}
func SetAssetHash(hash, path string) {
assetHashLock.Lock()
defer assetHashLock.Unlock()
assetHashCache[hash] = &AssetHash{
Hash: hash,
Path: path,
assetHashCache[hash] = &AssetHash{Hash: hash, Path: path}
assetPathHashCache[path] = &AssetHash{Hash: hash, Path: path}
}
func GetAssetHashByPath(path string) *AssetHash {
assetHashLock.Lock()
defer assetHashLock.Unlock()
asset, exists := assetPathHashCache[path]
if exists {
if filelock.IsExist(filepath.Join(util.DataDir, asset.Path)) {
return asset
}
delete(assetHashCache, asset.Hash)
delete(assetPathHashCache, path)
return nil
}
return nil
}
func GetAssetHash(hash string) *AssetHash {
@ -66,6 +86,7 @@ func GetAssetHash(hash string) *AssetHash {
}
delete(assetHashCache, hash)
delete(assetPathHashCache, a.Path)
return nil
}
}

View file

@ -93,6 +93,13 @@ func HandleAssetsRemoveEvent(assetAbsPath string) {
removeIndexAssetContent(assetAbsPath)
removeAssetThumbnail(assetAbsPath)
hash, err := util.GetEtag(assetAbsPath)
if nil != err {
logging.LogErrorf("calc asset [%s] hash failed: %s", assetAbsPath, err)
} else {
cache.RemoveAssetHash(hash)
}
}
func HandleAssetsChangeEvent(assetAbsPath string) {
@ -106,6 +113,15 @@ func HandleAssetsChangeEvent(assetAbsPath string) {
indexAssetContent(assetAbsPath)
removeAssetThumbnail(assetAbsPath)
hash, err := util.GetEtag(assetAbsPath)
if nil != err {
logging.LogErrorf("calc asset [%s] hash failed: %s", assetAbsPath, err)
} else {
p := strings.TrimPrefix(assetAbsPath, util.DataDir)
p = filepath.ToSlash(p)
cache.SetAssetHash(hash, p)
}
}
func removeAssetThumbnail(assetAbsPath string) {

View file

@ -21,9 +21,11 @@ import (
"path/filepath"
"strings"
"github.com/88250/gulu"
"github.com/88250/lute/ast"
"github.com/siyuan-note/filelock"
"github.com/siyuan-note/logging"
"github.com/siyuan-note/siyuan/kernel/cache"
"github.com/siyuan-note/siyuan/kernel/treenode"
"github.com/siyuan-note/siyuan/kernel/util"
)
@ -69,16 +71,7 @@ func docTitleImgAsset(root *ast.Node, boxLocalPath, docDirLocalPath string) *Ass
return nil
}
var hash string
var err error
if lp := assetLocalPath(p, boxLocalPath, docDirLocalPath); "" != lp {
hash, err = util.GetEtag(lp)
if err != nil {
logging.LogErrorf("calc asset [%s] hash failed: %s", lp, err)
return nil
}
}
hash := assetHashByLocalPath(p, boxLocalPath, docDirLocalPath)
name, _ := util.LastID(p)
asset := &Asset{
ID: ast.NewNodeID(),
@ -126,6 +119,22 @@ func scanAssetRows(rows *sql.Rows) (ret *Asset) {
return
}
func assetHashByLocalPath(linkDest, boxLocalPath, docDirLocalPath string) (ret string) {
if lp := assetLocalPath(linkDest, boxLocalPath, docDirLocalPath); "" != lp {
if !gulu.File.IsDir(lp) {
if assetHash := cache.GetAssetHashByPath(linkDest); nil != assetHash {
ret = assetHash.Hash
} else {
ret, _ = util.GetEtag(lp)
if "" != ret {
cache.SetAssetHash(ret, linkDest)
}
}
}
}
return
}
func assetLocalPath(linkDest, boxLocalPath, docDirLocalPath string) (ret string) {
ret = filepath.Join(docDirLocalPath, linkDest)
if filelock.IsExist(ret) {

View file

@ -649,16 +649,7 @@ func buildSpanFromNode(n *ast.Node, tree *parse.Tree, rootID, boxID, p string) (
title = gulu.Str.FromBytes(titleNode.Tokens)
}
var hash string
var hashErr error
if lp := assetLocalPath(dest, boxLocalPath, docDirLocalPath); "" != lp {
if !gulu.File.IsDir(lp) {
hash, hashErr = util.GetEtag(lp)
if nil != hashErr {
logging.LogErrorf("calc asset [%s] hash failed: %s", lp, hashErr)
}
}
}
hash := assetHashByLocalPath(dest, boxLocalPath, docDirLocalPath)
name, _ := util.LastID(dest)
asset := &Asset{
ID: ast.NewNodeID(),
@ -700,16 +691,7 @@ func buildSpanFromNode(n *ast.Node, tree *parse.Tree, rootID, boxID, p string) (
title = gulu.Str.FromBytes(titleNode.Tokens)
}
var hash string
var hashErr error
if lp := assetLocalPath(dest, boxLocalPath, docDirLocalPath); "" != lp {
if !gulu.File.IsDir(lp) {
hash, hashErr = util.GetEtag(lp)
if nil != hashErr {
logging.LogErrorf("calc asset [%s] hash failed: %s", lp, hashErr)
}
}
}
hash := assetHashByLocalPath(dest, boxLocalPath, docDirLocalPath)
name, _ := util.LastID(dest)
asset := &Asset{
ID: ast.NewNodeID(),
@ -790,15 +772,7 @@ func buildSpanFromNode(n *ast.Node, tree *parse.Tree, rootID, boxID, p string) (
}
dest := string(src)
var hash string
var hashErr error
if lp := assetLocalPath(dest, boxLocalPath, docDirLocalPath); "" != lp {
hash, hashErr = util.GetEtag(lp)
if nil != hashErr {
logging.LogErrorf("calc asset [%s] hash failed: %s", lp, hashErr)
}
}
hash := assetHashByLocalPath(dest, boxLocalPath, docDirLocalPath)
parentBlock := treenode.ParentBlock(n)
if ast.NodeInlineHTML != n.Type {
parentBlock = n