From 0c0cc55820f2c0a9ca12387cdae022340545ce6a Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Thu, 31 Oct 2024 22:56:48 +0800 Subject: [PATCH] :zap: Improve load tree performance --- kernel/filesys/tree.go | 50 ++++++++++++++++++++++++++++-------------- kernel/model/file.go | 25 ++------------------- 2 files changed, 35 insertions(+), 40 deletions(-) diff --git a/kernel/filesys/tree.go b/kernel/filesys/tree.go index 24aa96953..ccc3d7371 100644 --- a/kernel/filesys/tree.go +++ b/kernel/filesys/tree.go @@ -150,29 +150,22 @@ func LoadTreeByData(data []byte, boxID, p string, luteEngine *lute.Lute) (ret *p parentAbsPath += ".sy" parentPath := parentAbsPath parentAbsPath = filepath.Join(util.DataDir, boxID, parentAbsPath) - parentData, readErr := filelock.ReadFile(parentAbsPath) - if nil != readErr { - if os.IsNotExist(readErr) { - // 子文档缺失父文档时自动补全 https://github.com/siyuan-note/siyuan/issues/7376 - parentTree := treenode.NewTree(boxID, parentPath, hPathBuilder.String()+"Untitled", "Untitled") - if _, writeErr := WriteTree(parentTree); nil != writeErr { - logging.LogErrorf("rebuild parent tree [%s] failed: %s", parentAbsPath, writeErr) - } else { - logging.LogInfof("rebuilt parent tree [%s]", parentAbsPath) - treenode.UpsertBlockTree(parentTree) - } + + parentDocIAL := DocIAL(parentAbsPath) + if 1 > len(parentDocIAL) { + // 子文档缺失父文档时自动补全 https://github.com/siyuan-note/siyuan/issues/7376 + parentTree := treenode.NewTree(boxID, parentPath, hPathBuilder.String()+"Untitled", "Untitled") + if _, writeErr := WriteTree(parentTree); nil != writeErr { + logging.LogErrorf("rebuild parent tree [%s] failed: %s", parentAbsPath, writeErr) } else { - logging.LogWarnf("read parent tree data [%s] failed: %s", parentAbsPath, readErr) + logging.LogInfof("rebuilt parent tree [%s]", parentAbsPath) + treenode.UpsertBlockTree(parentTree) } hPathBuilder.WriteString("Untitled/") continue } - ial := ReadDocIAL(parentData) - if 1 > len(ial) { - logging.LogWarnf("tree [%s] is corrupted", filepath.Join(boxID, p)) - } - title := ial["title"] + title := parentDocIAL["title"] if "" == title { title = "Untitled" } @@ -185,6 +178,29 @@ func LoadTreeByData(data []byte, boxID, p string, luteEngine *lute.Lute) (ret *p return } +func DocIAL(absPath string) (ret map[string]string) { + filelock.Lock(absPath) + file, err := os.Open(absPath) + if err != nil { + logging.LogErrorf("open file [%s] failed: %s", absPath, err) + filelock.Unlock(absPath) + return nil + } + + iter := jsoniter.Parse(jsoniter.ConfigCompatibleWithStandardLibrary, file, 512) + for field := iter.ReadObject(); field != ""; field = iter.ReadObject() { + if field == "Properties" { + iter.ReadVal(&ret) + break + } else { + iter.Skip() + } + } + file.Close() + filelock.Unlock(absPath) + return +} + func WriteTree(tree *parse.Tree) (size uint64, err error) { data, filePath, err := prepareWriteTree(tree) if err != nil { diff --git a/kernel/model/file.go b/kernel/model/file.go index d0be5ba06..b65909b71 100644 --- a/kernel/model/file.go +++ b/kernel/model/file.go @@ -37,7 +37,6 @@ import ( "github.com/88250/lute/html" "github.com/88250/lute/parse" util2 "github.com/88250/lute/util" - jsoniter "github.com/json-iterator/go" "github.com/siyuan-note/filelock" "github.com/siyuan-note/logging" "github.com/siyuan-note/riff" @@ -116,29 +115,9 @@ func (box *Box) docIAL(p string) (ret map[string]string) { } filePath := filepath.Join(util.DataDir, box.ID, p) - - filelock.Lock(filePath) - file, err := os.Open(filePath) - if err != nil { - logging.LogErrorf("open file [%s] failed: %s", p, err) - filelock.Unlock(filePath) - return nil - } - - iter := jsoniter.Parse(jsoniter.ConfigCompatibleWithStandardLibrary, file, 512) - for field := iter.ReadObject(); field != ""; field = iter.ReadObject() { - if field == "Properties" { - iter.ReadVal(&ret) - break - } else { - iter.Skip() - } - } - file.Close() - filelock.Unlock(filePath) - + ret = filesys.DocIAL(filePath) if 1 > len(ret) { - logging.LogWarnf("properties not found in file [%s]", p) + logging.LogWarnf("properties not found in file [%s]", filePath) box.moveCorruptedData(filePath) return nil }