瀏覽代碼

:zap: 改进查询嵌入块加载性能 https://github.com/siyuan-note/siyuan/issues/6160

Liang Ding 2 年之前
父節點
當前提交
2faedbe7c6
共有 3 個文件被更改,包括 43 次插入13 次删除
  1. 8 4
      kernel/model/block.go
  2. 4 4
      kernel/model/export.go
  3. 31 5
      kernel/model/search.go

+ 8 - 4
kernel/model/block.go

@@ -381,12 +381,15 @@ func getBlock(id string) (ret *Block, err error) {
 	return
 	return
 }
 }
 
 
-func getBlockRendered(id string, headingMode int) (ret *Block) {
-	tree, _ := loadTreeByBlockID(id)
+func getBlockRendered(trees map[string]*parse.Tree, sqlBlock *sql.Block, headingMode int) (block *Block, blockPaths []*BlockPath) {
+	tree, _ := trees[sqlBlock.RootID]
+	if nil == tree {
+		tree, _ = loadTreeByBlockID(sqlBlock.RootID)
+	}
 	if nil == tree {
 	if nil == tree {
 		return
 		return
 	}
 	}
-	def := treenode.GetNodeInTree(tree, id)
+	def := treenode.GetNodeInTree(tree, sqlBlock.ID)
 	if nil == def {
 	if nil == def {
 		return
 		return
 	}
 	}
@@ -430,6 +433,7 @@ func getBlockRendered(id string, headingMode int) (ret *Block) {
 	luteEngine := NewLute()
 	luteEngine := NewLute()
 	luteEngine.RenderOptions.ProtyleContenteditable = false // 不可编辑
 	luteEngine.RenderOptions.ProtyleContenteditable = false // 不可编辑
 	dom := renderBlockDOMByNodes(nodes, luteEngine)
 	dom := renderBlockDOMByNodes(nodes, luteEngine)
-	ret = &Block{Box: def.Box, Path: def.Path, HPath: b.HPath, ID: def.ID, Type: def.Type.String(), Content: dom}
+	block = &Block{Box: def.Box, Path: def.Path, HPath: b.HPath, ID: def.ID, Type: def.Type.String(), Content: dom}
+	blockPaths = buildBlockBreadcrumb(def)
 	return
 	return
 }
 }

+ 4 - 4
kernel/model/export.go

@@ -1038,14 +1038,14 @@ func exportTree(tree *parse.Tree, wysiwyg, expandKaTexMacros, keepFold bool) (re
 		var defMd string
 		var defMd string
 		stmt := n.ChildByType(ast.NodeBlockQueryEmbedScript).TokensStr()
 		stmt := n.ChildByType(ast.NodeBlockQueryEmbedScript).TokensStr()
 		stmt = html.UnescapeString(stmt)
 		stmt = html.UnescapeString(stmt)
-		blocks := searchEmbedBlock(stmt, nil, 0)
-		if 1 > len(blocks) {
+		embedBlocks := searchEmbedBlock(stmt, nil, 0)
+		if 1 > len(embedBlocks) {
 			return ast.WalkContinue
 			return ast.WalkContinue
 		}
 		}
 
 
 		defMdBuf := bytes.Buffer{}
 		defMdBuf := bytes.Buffer{}
-		for _, def := range blocks {
-			defMdBuf.WriteString(renderBlockMarkdownR(def.ID))
+		for _, def := range embedBlocks {
+			defMdBuf.WriteString(renderBlockMarkdownR(def.Block.ID))
 			defMdBuf.WriteString("\n\n")
 			defMdBuf.WriteString("\n\n")
 		}
 		}
 		defMd = defMdBuf.String()
 		defMd = defMdBuf.String()

+ 31 - 5
kernel/model/search.go

@@ -38,12 +38,17 @@ import (
 	"github.com/xrash/smetrics"
 	"github.com/xrash/smetrics"
 )
 )
 
 
-func SearchEmbedBlock(stmt string, excludeIDs []string, headingMode int) (ret []*Block) {
+type EmbedBlock struct {
+	Block     *Block       `json:"block"`
+	BlockPath []*BlockPath `json:"blockPath"`
+}
+
+func SearchEmbedBlock(stmt string, excludeIDs []string, headingMode int) (ret []*EmbedBlock) {
 	WaitForWritingFiles()
 	WaitForWritingFiles()
 	return searchEmbedBlock(stmt, excludeIDs, headingMode)
 	return searchEmbedBlock(stmt, excludeIDs, headingMode)
 }
 }
 
 
-func searchEmbedBlock(stmt string, excludeIDs []string, headingMode int) (ret []*Block) {
+func searchEmbedBlock(stmt string, excludeIDs []string, headingMode int) (ret []*EmbedBlock) {
 	sqlBlocks := sql.SelectBlocksRawStmtNoParse(stmt, Conf.Search.Limit)
 	sqlBlocks := sql.SelectBlocksRawStmtNoParse(stmt, Conf.Search.Limit)
 	var tmp []*sql.Block
 	var tmp []*sql.Block
 	for _, b := range sqlBlocks {
 	for _, b := range sqlBlocks {
@@ -52,16 +57,37 @@ func searchEmbedBlock(stmt string, excludeIDs []string, headingMode int) (ret []
 		}
 		}
 	}
 	}
 	sqlBlocks = tmp
 	sqlBlocks = tmp
+
+	// 缓存最多 128 棵语法树
+	trees := map[string]*parse.Tree{}
+	count := 0
+	for _, sb := range sqlBlocks {
+		if nil == trees[sb.RootID] {
+			tree, _ := loadTreeByBlockID(sb.RootID)
+			if nil == tree {
+				continue
+			}
+			trees[sb.RootID] = tree
+			count++
+		}
+		if 127 < count {
+			break
+		}
+	}
+
 	for _, sb := range sqlBlocks {
 	for _, sb := range sqlBlocks {
-		block := getBlockRendered(sb.ID, headingMode)
+		block, blockPaths := getBlockRendered(trees, sb, headingMode)
 		if nil == block {
 		if nil == block {
 			continue
 			continue
 		}
 		}
-		ret = append(ret, block)
+		ret = append(ret, &EmbedBlock{
+			Block:     block,
+			BlockPath: blockPaths,
+		})
 	}
 	}
 
 
 	if 1 > len(ret) {
 	if 1 > len(ret) {
-		ret = []*Block{}
+		ret = []*EmbedBlock{}
 	}
 	}
 	return
 	return
 }
 }