Reduce the memory usage when exporting documents containing numerous references https://github.com/siyuan-note/siyuan/issues/16982

Signed-off-by: Daniel <845765@qq.com>
This commit is contained in:
Daniel 2026-02-07 11:49:58 +08:00
parent 7d1c310f89
commit b4a761d071
No known key found for this signature in database
GPG key ID: 86211BA83DF03017

View file

@ -2241,10 +2241,10 @@ func ExportMarkdownContent(id string, refMode, embedMode int, addYfm, fillCSSVar
return
}
func exportMarkdownContent(id, ext string, exportRefMode int, defBlockIDs []string, singleFile bool, treeCache map[string]*parse.Tree) (tree *parse.Tree, exportedMd string, isEmpty bool) {
tree, err := loadTreeWithCache(id, treeCache)
func exportMarkdownContent(rootID, ext string, exportRefMode int, defBlockIDs []string, singleFile bool, treeCache map[string]*parse.Tree) (tree *parse.Tree, exportedMd string, isEmpty bool) {
tree, err := loadTreeWithCache(rootID, treeCache)
if err != nil {
logging.LogErrorf("load tree by block id [%s] failed: %s", id, err)
logging.LogErrorf("load tree by block id [%s] failed: %s", rootID, err)
return
}
@ -2263,7 +2263,7 @@ func exportMarkdownContent(id, ext string, exportRefMode int, defBlockIDs []stri
}
}
exportedMd = exportMarkdownContent0(id, tree, "", false, false, false,
exportedMd = exportMarkdownContent0(rootID, tree, "", false, false, false,
ext, exportRefMode, Conf.Export.BlockEmbedMode, Conf.Export.FileAnnotationRefMode,
Conf.Export.TagOpenMarker, Conf.Export.TagCloseMarker,
Conf.Export.BlockRefTextLeft, Conf.Export.BlockRefTextRight,
@ -3066,8 +3066,21 @@ func resolveFootnotesDefs(refFootnotes *[]*refAsFootnotes, currentTree *parse.Tr
footnotesDefBlock = &ast.Node{Type: ast.NodeFootnotesDefBlock}
var rendered []string
var defIDs []string
for _, foot := range *refFootnotes {
t, err := loadTreeWithCache(foot.defID, treeCache)
defIDs = append(defIDs, foot.defID)
}
defIDs = gulu.Str.RemoveDuplicatedElem(defIDs)
bts := treenode.GetBlockTrees(defIDs)
for _, foot := range *refFootnotes {
bt := bts[foot.defID]
if nil == bt {
logging.LogWarnf("not found block tree for footnote def [%s] refNum [%s]", foot.defID, foot.refNum)
continue
}
t, err := loadTreeWithCache(bt.RootID, treeCache)
if nil != err {
logging.LogWarnf("load tree for footnote def [%s] refNum [%s] failed: %s", foot.defID, foot.refNum, err)
continue
@ -3417,8 +3430,8 @@ func exportPandocConvertZip(baseFolderName string, docPaths, defBlockIDs []strin
assetsOldNew, assetsNewOld := map[string]string{}, map[string]string{}
luteEngine := util.NewLute()
for i, p := range docPaths {
id := util.GetTreeID(p)
tree, md, isEmpty := exportMarkdownContent(id, ext, exportRefMode, defBlockIDs, false, treeCache)
rootID := util.GetTreeID(p)
tree, md, isEmpty := exportMarkdownContent(rootID, ext, exportRefMode, defBlockIDs, false, treeCache)
if nil == tree {
continue
}
@ -3437,7 +3450,7 @@ func exportPandocConvertZip(baseFolderName string, docPaths, defBlockIDs []strin
hash := fmt.Sprintf("%x", sha1.Sum([]byte(md)))
if gulu.File.IsExist(writePath) && hash != wrotePathHash[writePath] {
// 重名文档加 ID
p = hPath + "-" + id + ext
p = hPath + "-" + rootID + ext
writePath = filepath.Join(exportFolder, p)
}
writeFolder := filepath.Dir(writePath)
@ -3743,13 +3756,15 @@ func exportRefTrees(tree *parse.Tree, defBlockIDs *[]string, retTrees, treeCache
*defBlockIDs = gulu.Str.RemoveDuplicatedElem(*defBlockIDs)
}
func loadTreeWithCache(id string, treeCache map[string]*parse.Tree) (tree *parse.Tree, err error) {
if tree = treeCache[id]; nil != tree {
// loadTreeWithCache 加载树时优先从缓存获取,避免重复加载同一棵树
// 注意传入的 rootID 必须是树的根节点 ID不能是树中任意节点的 ID否则会导致缓存失效和重复加载树
func loadTreeWithCache(rootID string, treeCache map[string]*parse.Tree) (tree *parse.Tree, err error) {
if tree = treeCache[rootID]; nil != tree {
return
}
tree, err = LoadTreeByBlockID(id)
tree, err = LoadTreeByBlockID(rootID)
if nil == err && nil != tree {
treeCache[id] = tree
treeCache[rootID] = tree
}
return
}