改进打开虚拟引用后加载文档的性能 https://github.com/siyuan-note/siyuan/issues/7378

This commit is contained in:
Liang Ding 2023-02-16 13:41:34 +08:00
parent ef029d4dea
commit 0eabe9bf5f
No known key found for this signature in database
GPG key ID: 136F30F901A2231D

View file

@ -18,25 +18,18 @@ package model
import (
"bytes"
"regexp"
"sort"
"strings"
"github.com/88250/gulu"
"github.com/88250/lute"
"github.com/88250/lute/ast"
"github.com/88250/lute/parse"
"github.com/dgraph-io/ristretto"
"github.com/panjf2000/ants/v2"
"github.com/siyuan-note/logging"
"github.com/siyuan-note/siyuan/kernel/filesys"
"github.com/siyuan-note/siyuan/kernel/search"
"github.com/siyuan-note/siyuan/kernel/sql"
"github.com/siyuan-note/siyuan/kernel/treenode"
"github.com/siyuan-note/siyuan/kernel/util"
"os"
"path/filepath"
"regexp"
"runtime"
"sort"
"strings"
"sync"
)
// virtualBlockRefCache 用于保存块关联的虚拟引用关键字。
@ -48,8 +41,20 @@ var virtualBlockRefCache, _ = ristretto.NewCache(&ristretto.Config{
})
func getBlockVirtualRefKeywords(root *ast.Node) (ret []string) {
val, _ := virtualBlockRefCache.Get(root.ID)
if nil == val {
val, ok := virtualBlockRefCache.Get(root.ID)
if !ok {
buf := bytes.Buffer{}
ast.Walk(root, func(n *ast.Node, entering bool) ast.WalkStatus {
if !entering || !n.IsBlock() {
return ast.WalkContinue
}
content := treenode.NodeStaticContent(n, nil)
buf.WriteString(content)
return ast.WalkContinue
})
content := buf.String()
putBlockVirtualRefKeywords(content, root.ID, root.IALAttr("title"))
return
}
ret = val.([]string)
@ -88,80 +93,12 @@ func putBlockVirtualRefKeywords(blockContent, blockID, docTitle string) {
func CacheVirtualBlockRefJob() {
virtualBlockRefCache.Del("virtual_ref")
if !Conf.Editor.VirtualBlockRef {
return
}
keywords := sql.QueryVirtualRefKeywords(Conf.Search.VirtualRefName, Conf.Search.VirtualRefAlias, Conf.Search.VirtualRefAnchor, Conf.Search.VirtualRefDoc)
virtualBlockRefCache.Set("virtual_ref", keywords, 1)
boxes := Conf.GetOpenedBoxes()
luteEngine := lute.New()
for _, box := range boxes {
boxPath := filepath.Join(util.DataDir, box.ID)
var paths []string
filepath.Walk(boxPath, func(path string, info os.FileInfo, err error) error {
if boxPath == path {
// 跳过根路径(笔记本文件夹)
return nil
}
if info.IsDir() {
if strings.HasPrefix(info.Name(), ".") {
return filepath.SkipDir
}
return nil
}
if filepath.Ext(path) != ".sy" || strings.Contains(filepath.ToSlash(path), "/assets/") {
return nil
}
p := path[len(boxPath):]
p = filepath.ToSlash(p)
paths = append(paths, p)
return nil
})
poolSize := runtime.NumCPU()
if 8 < poolSize {
poolSize = 8
}
i := 0
waitGroup := &sync.WaitGroup{}
pool, _ := ants.NewPoolWithFunc(poolSize, func(arg interface{}) {
defer waitGroup.Done()
p := arg.(string)
tree, loadErr := filesys.LoadTree(box.ID, p, luteEngine)
if nil != loadErr {
return
}
treeTitle := tree.Root.IALAttr("title")
buf := bytes.Buffer{}
ast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus {
if !entering || !n.IsBlock() {
return ast.WalkContinue
}
content := treenode.NodeStaticContent(n, nil)
buf.WriteString(content)
return ast.WalkContinue
})
content := buf.String()
putBlockVirtualRefKeywords(content, tree.ID, treeTitle)
i++
logging.LogInfof("cached virtual block ref for tree [%s, %d/%d]", tree.ID, i, len(paths))
})
for _, p := range paths {
waitGroup.Add(1)
pool.Invoke(p)
}
waitGroup.Wait()
pool.Release()
}
}
func processVirtualRef(n *ast.Node, unlinks *[]*ast.Node, virtualBlockRefKeywords []string, refCount map[string]int, luteEngine *lute.Lute) bool {