⚡ 改进打开虚拟引用后加载文档的性能 https://github.com/siyuan-note/siyuan/issues/7378
This commit is contained in:
parent
ef029d4dea
commit
0eabe9bf5f
1 changed files with 18 additions and 81 deletions
|
@ -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 {
|
||||
|
|
Loading…
Add table
Reference in a new issue