Browse Source

:recycle: Clean code

Daniel 1 year ago
parent
commit
f3574038e2

+ 2 - 1
kernel/api/av.go

@@ -23,6 +23,7 @@ import (
 	"github.com/gin-gonic/gin"
 	"github.com/siyuan-note/siyuan/kernel/av"
 	"github.com/siyuan-note/siyuan/kernel/model"
+	"github.com/siyuan-note/siyuan/kernel/treenode"
 	"github.com/siyuan-note/siyuan/kernel/util"
 )
 
@@ -36,7 +37,7 @@ func getMirrorDatabaseBlocks(c *gin.Context) {
 	}
 
 	avID := arg["avID"].(string)
-	ret.Data = av.GetMirrorBlockIDs(avID)
+	ret.Data = treenode.GetMirrorAttrViewBlockIDs(avID)
 }
 
 func setDatabaseBlockView(c *gin.Context) {

+ 1 - 1
kernel/api/block.go

@@ -447,7 +447,7 @@ func getBlockInfo(c *gin.Context) {
 
 	id := arg["id"].(string)
 
-	tree, err := model.LoadTreeByID(id)
+	tree, err := model.LoadTreeByBlockID(id)
 	if errors.Is(err, model.ErrIndexing) {
 		ret.Code = 3
 		ret.Msg = model.Conf.Language(56)

+ 1 - 1
kernel/api/filetree.go

@@ -518,7 +518,7 @@ func duplicateDoc(c *gin.Context) {
 	}
 
 	id := arg["id"].(string)
-	tree, err := model.LoadTreeByID(id)
+	tree, err := model.LoadTreeByBlockID(id)
 	if nil != err {
 		ret.Code = -1
 		ret.Msg = err.Error()

+ 7 - 32
kernel/av/mirror.go

@@ -13,37 +13,12 @@ import (
 )
 
 var (
-	attributeViewBlocksLock = sync.Mutex{}
+	AttributeViewBlocksLock = sync.Mutex{}
 )
 
-func GetMirrorBlockIDs(avID string) []string {
-	attributeViewBlocksLock.Lock()
-	defer attributeViewBlocksLock.Unlock()
-
-	blocks := filepath.Join(util.DataDir, "storage", "av", "blocks.msgpack")
-	if !filelock.IsExist(blocks) {
-		return nil
-	}
-
-	data, err := filelock.ReadFile(blocks)
-	if nil != err {
-		logging.LogErrorf("read attribute view blocks failed: %s", err)
-		return nil
-	}
-
-	avBlocks := map[string][]string{}
-	if err = msgpack.Unmarshal(data, &avBlocks); nil != err {
-		logging.LogErrorf("unmarshal attribute view blocks failed: %s", err)
-		return nil
-	}
-
-	blockIDs := avBlocks[avID]
-	return blockIDs
-}
-
 func IsMirror(avID string) bool {
-	attributeViewBlocksLock.Lock()
-	defer attributeViewBlocksLock.Unlock()
+	AttributeViewBlocksLock.Lock()
+	defer AttributeViewBlocksLock.Unlock()
 
 	blocks := filepath.Join(util.DataDir, "storage", "av", "blocks.msgpack")
 	if !filelock.IsExist(blocks) {
@@ -67,8 +42,8 @@ func IsMirror(avID string) bool {
 }
 
 func RemoveBlockRel(avID, blockID string) {
-	attributeViewBlocksLock.Lock()
-	defer attributeViewBlocksLock.Unlock()
+	AttributeViewBlocksLock.Lock()
+	defer AttributeViewBlocksLock.Unlock()
 
 	blocks := filepath.Join(util.DataDir, "storage", "av", "blocks.msgpack")
 	if !filelock.IsExist(blocks) {
@@ -112,8 +87,8 @@ func RemoveBlockRel(avID, blockID string) {
 }
 
 func UpsertBlockRel(avID, blockID string) {
-	attributeViewBlocksLock.Lock()
-	defer attributeViewBlocksLock.Unlock()
+	AttributeViewBlocksLock.Lock()
+	defer AttributeViewBlocksLock.Unlock()
 
 	avBlocks := map[string][]string{}
 	blocks := filepath.Join(util.DataDir, "storage", "av", "blocks.msgpack")

+ 1 - 1
kernel/model/ai.go

@@ -132,7 +132,7 @@ func getBlocksContent(ids []string) string {
 
 		var tree *parse.Tree
 		if tree = trees[bt.RootID]; nil == tree {
-			tree, _ = loadTreeByBlockID(bt.RootID)
+			tree, _ = LoadTreeByBlockID(bt.RootID)
 			if nil == tree {
 				continue
 			}

+ 5 - 5
kernel/model/assets.go

@@ -52,7 +52,7 @@ import (
 )
 
 func DocImageAssets(rootID string) (ret []string, err error) {
-	tree, err := loadTreeByBlockID(rootID)
+	tree, err := LoadTreeByBlockID(rootID)
 	if nil != err {
 		return
 	}
@@ -75,7 +75,7 @@ func DocImageAssets(rootID string) (ret []string, err error) {
 }
 
 func NetImg2LocalAssets(rootID, originalURL string) (err error) {
-	tree, err := loadTreeByBlockID(rootID)
+	tree, err := LoadTreeByBlockID(rootID)
 	if nil != err {
 		return
 	}
@@ -227,7 +227,7 @@ func NetImg2LocalAssets(rootID, originalURL string) (err error) {
 }
 
 func NetAssets2LocalAssets(rootID string) (err error) {
-	tree, err := loadTreeByBlockID(rootID)
+	tree, err := LoadTreeByBlockID(rootID)
 	if nil != err {
 		return
 	}
@@ -515,7 +515,7 @@ func UploadAssets2Cloud(rootID string) (count int, err error) {
 		return
 	}
 
-	tree, err := loadTreeByBlockID(rootID)
+	tree, err := LoadTreeByBlockID(rootID)
 	if nil != err {
 		return
 	}
@@ -1071,7 +1071,7 @@ func assetsLinkDestsInQueryEmbedNodes(tree *parse.Tree) (ret []string) {
 		stmt = strings.ReplaceAll(stmt, editor.IALValEscNewLine, "\n")
 		sqlBlocks := sql.SelectBlocksRawStmt(stmt, 1, Conf.Search.Limit)
 		for _, sqlBlock := range sqlBlocks {
-			subtree, _ := loadTreeByBlockID(sqlBlock.ID)
+			subtree, _ := LoadTreeByBlockID(sqlBlock.ID)
 			if nil == subtree {
 				continue
 			}

+ 10 - 10
kernel/model/attribute_view.go

@@ -205,7 +205,7 @@ func SearchAttributeView(keyword string, page int, pageSize int) (ret []*SearchA
 	for _, block := range blocks {
 		tree := trees[block.RootID]
 		if nil == tree {
-			tree, _ = loadTreeByBlockID(block.ID)
+			tree, _ = LoadTreeByBlockID(block.ID)
 			if nil != tree {
 				trees[block.RootID] = tree
 			}
@@ -438,7 +438,7 @@ func GetBlockAttributeViewKeys(blockID string) (ret []*BlockAttributeViewKeys) {
 			})
 		}
 
-		blockIDs := av.GetMirrorBlockIDs(avID)
+		blockIDs := treenode.GetMirrorAttrViewBlockIDs(avID)
 		if 1 > len(blockIDs) {
 			// 老数据兼容处理
 			avBts := treenode.GetBlockTreesByType("av")
@@ -446,7 +446,7 @@ func GetBlockAttributeViewKeys(blockID string) (ret []*BlockAttributeViewKeys) {
 				if nil == avBt {
 					continue
 				}
-				tree, _ := loadTreeByBlockID(avBt.ID)
+				tree, _ := LoadTreeByBlockID(avBt.ID)
 				if nil == tree {
 					continue
 				}
@@ -459,7 +459,7 @@ func GetBlockAttributeViewKeys(blockID string) (ret []*BlockAttributeViewKeys) {
 				}
 			}
 			if 1 > len(blockIDs) {
-				tree, _ := loadTreeByBlockID(blockID)
+				tree, _ := LoadTreeByBlockID(blockID)
 				if nil != tree {
 					node := treenode.GetNodeInTree(tree, blockID)
 					if nil != node {
@@ -1481,7 +1481,7 @@ func (tx *Transaction) doRemoveAttrViewView(operation *Operation) (ret *TxErr) {
 }
 
 func getMirrorBlocksNodes(avID string) (trees []*parse.Tree, nodes []*ast.Node) {
-	mirrorBlocks := av.GetMirrorBlockIDs(avID)
+	mirrorBlocks := treenode.GetMirrorAttrViewBlockIDs(avID)
 	mirrorBlockTree := map[string]*parse.Tree{}
 	treeMap := map[string]*parse.Tree{}
 	for _, mirrorBlock := range mirrorBlocks {
@@ -1493,7 +1493,7 @@ func getMirrorBlocksNodes(avID string) (trees []*parse.Tree, nodes []*ast.Node)
 
 		tree := mirrorBlockTree[mirrorBlock]
 		if nil == tree {
-			tree, _ = loadTreeByBlockID(mirrorBlock)
+			tree, _ = LoadTreeByBlockID(mirrorBlock)
 			if nil == tree {
 				logging.LogErrorf("load tree by block ID [%s] failed", mirrorBlock)
 				continue
@@ -1764,7 +1764,7 @@ func getAttrViewBoundNodes(attrView *av.AttributeView) (ret []*ast.Node) {
 		var tree *parse.Tree
 		tree = treeMap[blockKeyValue.BlockID]
 		if nil == tree {
-			tree, _ = loadTreeByBlockID(blockKeyValue.BlockID)
+			tree, _ = LoadTreeByBlockID(blockKeyValue.BlockID)
 		}
 		if nil == tree {
 			continue
@@ -1941,7 +1941,7 @@ func AddAttributeViewBlock(tx *Transaction, srcIDs []string, avID, blockID, prev
 			if nil != tx {
 				tree, loadErr = tx.loadTree(id)
 			} else {
-				tree, loadErr = loadTreeByBlockID(id)
+				tree, loadErr = LoadTreeByBlockID(id)
 			}
 			if nil != loadErr {
 				logging.LogErrorf("load tree [%s] failed: %s", id, err)
@@ -2156,7 +2156,7 @@ func removeAttributeViewBlock(srcIDs []string, avID string, tx *Transaction) (er
 				if bt := treenode.GetBlockTree(values.BlockID); nil != bt {
 					tree := trees[bt.RootID]
 					if nil == tree {
-						tree, _ = loadTreeByBlockID(values.BlockID)
+						tree, _ = LoadTreeByBlockID(values.BlockID)
 					}
 
 					if nil != tree {
@@ -3062,7 +3062,7 @@ func getNodeByBlockID(tx *Transaction, blockID string) (node *ast.Node, tree *pa
 	if nil != tx {
 		tree, err = tx.loadTree(blockID)
 	} else {
-		tree, err = loadTreeByBlockID(blockID)
+		tree, err = LoadTreeByBlockID(blockID)
 	}
 	if nil != err {
 		return

+ 3 - 3
kernel/model/backlink.go

@@ -52,7 +52,7 @@ func refreshRefsByDefID(defID string) {
 		}
 
 		var loadErr error
-		tree, loadErr = loadTreeByBlockID(ref.RootID)
+		tree, loadErr = LoadTreeByBlockID(ref.RootID)
 		if nil != loadErr {
 			logging.LogErrorf("refresh tree refs failed: %s", loadErr)
 			continue
@@ -100,7 +100,7 @@ func GetBackmentionDoc(defID, refTreeID, keyword string) (ret []*Backlink) {
 		refTree := treeCache[mention.RootID]
 		if nil == refTree {
 			var loadErr error
-			refTree, loadErr = loadTreeByBlockID(mention.ID)
+			refTree, loadErr = LoadTreeByBlockID(mention.ID)
 			if nil != loadErr {
 				logging.LogWarnf("load ref tree [%s] failed: %s", mention.ID, loadErr)
 				continue
@@ -133,7 +133,7 @@ func GetBacklinkDoc(defID, refTreeID, keyword string) (ret []*Backlink) {
 	refs = removeDuplicatedRefs(refs) // 同一个块中引用多个相同块时反链去重 https://github.com/siyuan-note/siyuan/issues/3317
 
 	linkRefs, _, _ := buildLinkRefs(rootID, refs, keyword)
-	refTree, err := loadTreeByBlockID(refTreeID)
+	refTree, err := LoadTreeByBlockID(refTreeID)
 	if nil != err {
 		logging.LogWarnf("load ref tree [%s] failed: %s", refTreeID, err)
 		return

+ 16 - 16
kernel/model/block.go

@@ -115,7 +115,7 @@ type Path struct {
 }
 
 func GetParentNextChildID(id string) string {
-	tree, err := loadTreeByBlockID(id)
+	tree, err := LoadTreeByBlockID(id)
 	if nil != err {
 		return ""
 	}
@@ -172,7 +172,7 @@ func RecentUpdatedBlocks() (ret []*Block) {
 }
 
 func TransferBlockRef(fromID, toID string, refIDs []string) (err error) {
-	toTree, _ := loadTreeByBlockID(toID)
+	toTree, _ := LoadTreeByBlockID(toID)
 	if nil == toTree {
 		err = ErrBlockNotFound
 		return
@@ -190,7 +190,7 @@ func TransferBlockRef(fromID, toID string, refIDs []string) (err error) {
 		refIDs, _ = sql.QueryRefIDsByDefID(fromID, false)
 	}
 	for _, refID := range refIDs {
-		tree, _ := loadTreeByBlockID(refID)
+		tree, _ := LoadTreeByBlockID(refID)
 		if nil == tree {
 			continue
 		}
@@ -215,7 +215,7 @@ func TransferBlockRef(fromID, toID string, refIDs []string) (err error) {
 }
 
 func SwapBlockRef(refID, defID string, includeChildren bool) (err error) {
-	refTree, err := loadTreeByBlockID(refID)
+	refTree, err := LoadTreeByBlockID(refID)
 	if nil != err {
 		return
 	}
@@ -226,7 +226,7 @@ func SwapBlockRef(refID, defID string, includeChildren bool) (err error) {
 	if ast.NodeListItem == refNode.Parent.Type {
 		refNode = refNode.Parent
 	}
-	defTree, err := loadTreeByBlockID(defID)
+	defTree, err := LoadTreeByBlockID(defID)
 	if nil != err {
 		return
 	}
@@ -331,7 +331,7 @@ func SwapBlockRef(refID, defID string, includeChildren bool) (err error) {
 }
 
 func GetHeadingDeleteTransaction(id string) (transaction *Transaction, err error) {
-	tree, err := loadTreeByBlockID(id)
+	tree, err := LoadTreeByBlockID(id)
 	if nil != err {
 		return
 	}
@@ -374,7 +374,7 @@ func GetHeadingDeleteTransaction(id string) (transaction *Transaction, err error
 }
 
 func GetHeadingChildrenIDs(id string) (ret []string) {
-	tree, err := loadTreeByBlockID(id)
+	tree, err := LoadTreeByBlockID(id)
 	if nil != err {
 		return
 	}
@@ -392,7 +392,7 @@ func GetHeadingChildrenIDs(id string) (ret []string) {
 }
 
 func GetHeadingChildrenDOM(id string) (ret string) {
-	tree, err := loadTreeByBlockID(id)
+	tree, err := LoadTreeByBlockID(id)
 	if nil != err {
 		return
 	}
@@ -410,7 +410,7 @@ func GetHeadingChildrenDOM(id string) (ret string) {
 }
 
 func GetHeadingLevelTransaction(id string, level int) (transaction *Transaction, err error) {
-	tree, err := loadTreeByBlockID(id)
+	tree, err := LoadTreeByBlockID(id)
 	if nil != err {
 		return
 	}
@@ -469,7 +469,7 @@ func GetBlockDOM(id string) (ret string) {
 		return
 	}
 
-	tree, err := loadTreeByBlockID(id)
+	tree, err := LoadTreeByBlockID(id)
 	if nil != err {
 		return
 	}
@@ -484,7 +484,7 @@ func GetBlockKramdown(id string) (ret string) {
 		return
 	}
 
-	tree, err := loadTreeByBlockID(id)
+	tree, err := LoadTreeByBlockID(id)
 	if nil != err {
 		return
 	}
@@ -511,7 +511,7 @@ func GetChildBlocks(id string) (ret []*ChildBlock) {
 		return
 	}
 
-	tree, err := loadTreeByBlockID(id)
+	tree, err := LoadTreeByBlockID(id)
 	if nil != err {
 		return
 	}
@@ -557,7 +557,7 @@ func GetTailChildBlocks(id string, n int) (ret []*ChildBlock) {
 		return
 	}
 
-	tree, err := loadTreeByBlockID(id)
+	tree, err := LoadTreeByBlockID(id)
 	if nil != err {
 		return
 	}
@@ -616,10 +616,10 @@ func getBlock(id string, tree *parse.Tree) (ret *Block, err error) {
 	}
 
 	if nil == tree {
-		tree, err = loadTreeByBlockID(id)
+		tree, err = LoadTreeByBlockID(id)
 		if nil != err {
 			time.Sleep(1 * time.Second)
-			tree, err = loadTreeByBlockID(id)
+			tree, err = LoadTreeByBlockID(id)
 			if nil != err {
 				return
 			}
@@ -643,7 +643,7 @@ func getBlock(id string, tree *parse.Tree) (ret *Block, err error) {
 func getEmbeddedBlock(trees map[string]*parse.Tree, sqlBlock *sql.Block, headingMode int, breadcrumb bool) (block *Block, blockPaths []*BlockPath) {
 	tree, _ := trees[sqlBlock.RootID]
 	if nil == tree {
-		tree, _ = loadTreeByBlockID(sqlBlock.RootID)
+		tree, _ = LoadTreeByBlockID(sqlBlock.RootID)
 	}
 	if nil == tree {
 		return

+ 6 - 6
kernel/model/blockial.go

@@ -53,7 +53,7 @@ func SetBlockReminder(id string, timed string) (err error) {
 	}
 
 	attrs := GetBlockAttrs(id) // 获取属性是会等待树写入
-	tree, err := loadTreeByBlockID(id)
+	tree, err := LoadTreeByBlockID(id)
 	if nil != err {
 		return
 	}
@@ -110,7 +110,7 @@ func BatchSetBlockAttrs(blockAttrs []map[string]interface{}) (err error) {
 		}
 
 		if nil == trees[bt.RootID] {
-			tree, e := loadTreeByBlockID(id)
+			tree, e := LoadTreeByBlockID(id)
 			if nil != e {
 				return e
 			}
@@ -160,7 +160,7 @@ func SetBlockAttrs(id string, nameValues map[string]string) (err error) {
 
 	WaitForWritingFiles()
 
-	tree, err := loadTreeByBlockID(id)
+	tree, err := LoadTreeByBlockID(id)
 	if nil != err {
 		return err
 	}
@@ -248,7 +248,7 @@ func pushBroadcastAttrTransactions(oldAttrs map[string]string, node *ast.Node) {
 }
 
 func ResetBlockAttrs(id string, nameValues map[string]string) (err error) {
-	tree, err := loadTreeByBlockID(id)
+	tree, err := LoadTreeByBlockID(id)
 	if nil != err {
 		return err
 	}
@@ -296,7 +296,7 @@ func GetBlockAttrs(id string) (ret map[string]string) {
 
 	WaitForWritingFiles()
 
-	tree, err := loadTreeByBlockID(id)
+	tree, err := LoadTreeByBlockID(id)
 	if nil != err {
 		return
 	}
@@ -321,7 +321,7 @@ func GetBlockAttrsWithoutWaitWriting(id string) (ret map[string]string) {
 		return
 	}
 
-	tree, err := loadTreeByBlockID(id)
+	tree, err := LoadTreeByBlockID(id)
 	if nil != err {
 		return
 	}

+ 4 - 4
kernel/model/blockinfo.go

@@ -54,7 +54,7 @@ type AttrView struct {
 func GetDocInfo(blockID string) (ret *BlockInfo) {
 	WaitForWritingFiles()
 
-	tree, err := loadTreeByBlockID(blockID)
+	tree, err := LoadTreeByBlockID(blockID)
 	if nil != err {
 		logging.LogErrorf("load tree by root id [%s] failed: %s", blockID, err)
 		return
@@ -129,7 +129,7 @@ func GetBlockRefText(id string) string {
 		return ErrBlockNotFound.Error()
 	}
 
-	tree, err := loadTreeByBlockID(id)
+	tree, err := LoadTreeByBlockID(id)
 	if nil != err {
 		return ErrTreeNotFound.Error()
 	}
@@ -243,7 +243,7 @@ func GetBlockDefIDsByRefText(refText string, excludeIDs []string) (ret []string)
 }
 
 func GetBlockIndex(id string) (ret int) {
-	tree, _ := loadTreeByBlockID(id)
+	tree, _ := LoadTreeByBlockID(id)
 	if nil == tree {
 		return
 	}
@@ -284,7 +284,7 @@ type BlockPath struct {
 
 func BuildBlockBreadcrumb(id string, excludeTypes []string) (ret []*BlockPath, err error) {
 	ret = []*BlockPath{}
-	tree, err := loadTreeByBlockID(id)
+	tree, err := LoadTreeByBlockID(id)
 	if nil == tree {
 		err = nil
 		return

+ 3 - 3
kernel/model/bookmark.go

@@ -45,7 +45,7 @@ func RemoveBookmark(bookmark string) (err error) {
 
 	for treeID, blocks := range treeBlocks {
 		util.PushEndlessProgress("[" + treeID + "]")
-		tree, e := loadTreeByBlockID(treeID)
+		tree, e := LoadTreeByBlockID(treeID)
 		if nil != e {
 			util.PushClearProgress()
 			return e
@@ -103,7 +103,7 @@ func RenameBookmark(oldBookmark, newBookmark string) (err error) {
 
 	for treeID, blocks := range treeBlocks {
 		util.PushEndlessProgress("[" + treeID + "]")
-		tree, e := loadTreeByBlockID(treeID)
+		tree, e := LoadTreeByBlockID(treeID)
 		if nil != e {
 			util.ClearPushProgress(100)
 			return e
@@ -173,7 +173,7 @@ func BuildBookmark() (ret *Bookmarks) {
 			block.Content = block.Name
 		} else {
 			// Improve bookmark panel rendering https://github.com/siyuan-note/siyuan/issues/9361
-			tree, err := loadTreeByBlockID(block.ID)
+			tree, err := LoadTreeByBlockID(block.ID)
 			if nil != err {
 				logging.LogErrorf("parse block [%s] failed: %s", block.ID, err)
 			} else {

+ 12 - 12
kernel/model/export.go

@@ -191,7 +191,7 @@ func ExportAv2CSV(avID, blockID string) (zipPath string, err error) {
 }
 
 func Export2Liandi(id string) (err error) {
-	tree, err := loadTreeByBlockID(id)
+	tree, err := LoadTreeByBlockID(id)
 	if nil != err {
 		logging.LogErrorf("load tree by block id [%s] failed: %s", id, err)
 		return
@@ -293,7 +293,7 @@ func Export2Liandi(id string) (err error) {
 
 	if !foundArticle {
 		articleId = result.Data.(string)
-		tree, _ = loadTreeByBlockID(id) // 这里必须重新加载,因为前面导出时已经修改了树结构
+		tree, _ = LoadTreeByBlockID(id) // 这里必须重新加载,因为前面导出时已经修改了树结构
 		tree.Root.SetIALAttr(liandiArticleIdAttrName, articleId)
 		if err = writeJSONQueue(tree); nil != err {
 			return
@@ -518,7 +518,7 @@ func ExportResources(resourcePaths []string, mainName string) (exportFilePath st
 }
 
 func Preview(id string) (retStdHTML string, retOutline []*Path) {
-	tree, _ := loadTreeByBlockID(id)
+	tree, _ := LoadTreeByBlockID(id)
 	tree = exportTree(tree, false, false, false,
 		Conf.Export.BlockRefMode, Conf.Export.BlockEmbedMode, Conf.Export.FileAnnotationRefMode,
 		Conf.Export.TagOpenMarker, Conf.Export.TagCloseMarker,
@@ -931,7 +931,7 @@ func processIFrame(tree *parse.Tree) {
 }
 
 func ProcessPDF(id, p string, merge, removeAssets, watermark bool) (err error) {
-	tree, _ := loadTreeByBlockID(id)
+	tree, _ := LoadTreeByBlockID(id)
 	if nil == tree {
 		return
 	}
@@ -1319,7 +1319,7 @@ func processPDFLinkEmbedAssets(pdfCtx *pdfcpu.Context, assetDests []string, remo
 }
 
 func ExportStdMarkdown(id string) string {
-	tree, err := loadTreeByBlockID(id)
+	tree, err := LoadTreeByBlockID(id)
 	if nil != err {
 		logging.LogErrorf("load tree by block id [%s] failed: %s", id, err)
 		return ""
@@ -1490,7 +1490,7 @@ func exportSYZip(boxID, rootDirPath, baseFolderName string, docPaths []string) (
 		}
 
 		id := docIAL["id"]
-		tree, err := loadTreeByBlockID(id)
+		tree, err := LoadTreeByBlockID(id)
 		if nil != err {
 			continue
 		}
@@ -1783,7 +1783,7 @@ func ExportMarkdownContent(id string) (hPath, exportedMd string) {
 }
 
 func exportMarkdownContent(id string, exportRefMode int, defBlockIDs []string) (hPath, exportedMd string) {
-	tree, err := loadTreeByBlockID(id)
+	tree, err := LoadTreeByBlockID(id)
 	if nil != err {
 		logging.LogErrorf("load tree by block id [%s] failed: %s", id, err)
 		return
@@ -2071,7 +2071,7 @@ func exportTree(tree *parse.Tree, wysiwyg, expandKaTexMacros, keepFold bool,
 		// 处理引用节点
 
 		defID, linkText := getExportBlockRefLinkText(n, blockRefTextLeft, blockRefTextRight)
-		defTree, _ := loadTreeByBlockID(defID)
+		defTree, _ := LoadTreeByBlockID(defID)
 		if nil == defTree {
 			return ast.WalkContinue
 		}
@@ -2337,7 +2337,7 @@ func resolveFootnotesDefs(refFootnotes *[]*refAsFootnotes, rootID string, blockR
 	footnotesDefBlock = &ast.Node{Type: ast.NodeFootnotesDefBlock}
 	var rendered []string
 	for _, foot := range *refFootnotes {
-		t, err := loadTreeByBlockID(foot.defID)
+		t, err := LoadTreeByBlockID(foot.defID)
 		if nil != err {
 			continue
 		}
@@ -2464,7 +2464,7 @@ func collectFootnotesDefs(id string, refFootnotes *[]*refAsFootnotes, treeCache
 	t := (*treeCache)[b.RootID]
 	if nil == t {
 		var err error
-		if t, err = loadTreeByBlockID(b.ID); nil != err {
+		if t, err = LoadTreeByBlockID(b.ID); nil != err {
 			return
 		}
 		(*treeCache)[t.ID] = t
@@ -2550,7 +2550,7 @@ func exportRefTrees0(tree *parse.Tree, retTrees *map[string]*parse.Tree) {
 			if nil == defBlock {
 				return ast.WalkSkipChildren
 			}
-			defTree, err := loadTreeByBlockID(defBlock.RootID)
+			defTree, err := LoadTreeByBlockID(defBlock.RootID)
 			if nil != err {
 				return ast.WalkSkipChildren
 			}
@@ -2642,7 +2642,7 @@ func exportPandocConvertZip(exportNotebook bool, boxID, baseFolderName string, d
 				continue
 			}
 			id := docIAL["id"]
-			tree, err := loadTreeByBlockID(id)
+			tree, err := LoadTreeByBlockID(id)
 			if nil != err {
 				continue
 			}

+ 8 - 8
kernel/model/file.go

@@ -491,7 +491,7 @@ func BlocksWordCount(ids []string) (ret *util.BlockStatResult) {
 func StatTree(id string) (ret *util.BlockStatResult) {
 	WaitForWritingFiles()
 
-	tree, _ := loadTreeByBlockID(id)
+	tree, _ := LoadTreeByBlockID(id)
 	if nil == tree {
 		return
 	}
@@ -515,7 +515,7 @@ func GetDoc(startID, endID, id string, index int, query string, queryTypes map[s
 	WaitForWritingFiles() // 写入数据时阻塞,避免获取到的数据不一致
 
 	inputIndex := index
-	tree, err := loadTreeByBlockID(id)
+	tree, err := LoadTreeByBlockID(id)
 	if nil != err {
 		if ErrBlockNotFound == err {
 			if 0 == mode {
@@ -1075,7 +1075,7 @@ func CreateDailyNote(boxID string) (p string, existed bool, err error) {
 		existed = true
 		p = existRoot.Path
 
-		tree, loadErr := loadTreeByBlockID(existRoot.RootID)
+		tree, loadErr := LoadTreeByBlockID(existRoot.RootID)
 		if nil != loadErr {
 			logging.LogWarnf("load tree by block id [%s] failed: %v", existRoot.RootID, loadErr)
 			return
@@ -1110,7 +1110,7 @@ func CreateDailyNote(boxID string) (p string, existed bool, err error) {
 	}
 	if "" != dom {
 		var tree *parse.Tree
-		tree, err = loadTreeByBlockID(id)
+		tree, err = LoadTreeByBlockID(id)
 		if nil == err {
 			tree.Root.FirstChild.Unlink()
 
@@ -1133,7 +1133,7 @@ func CreateDailyNote(boxID string) (p string, existed bool, err error) {
 
 	WaitForWritingFiles()
 
-	tree, err := loadTreeByBlockID(id)
+	tree, err := LoadTreeByBlockID(id)
 	if nil != err {
 		logging.LogErrorf("load tree by block id [%s] failed: %v", id, err)
 		return
@@ -1184,7 +1184,7 @@ func GetHPathsByPaths(paths []string) (hPaths []string, err error) {
 }
 
 func GetHPathByID(id string) (hPath string, err error) {
-	tree, err := loadTreeByBlockID(id)
+	tree, err := LoadTreeByBlockID(id)
 	if nil != err {
 		return
 	}
@@ -1193,7 +1193,7 @@ func GetHPathByID(id string) (hPath string, err error) {
 }
 
 func GetFullHPathByID(id string) (hPath string, err error) {
-	tree, err := loadTreeByBlockID(id)
+	tree, err := LoadTreeByBlockID(id)
 	if nil != err {
 		return
 	}
@@ -1585,7 +1585,7 @@ func createDoc(boxID, p, title, dom string) (tree *parse.Tree, err error) {
 	folder := path.Dir(p)
 	if "/" != folder {
 		parentID := path.Base(folder)
-		parentTree, loadErr := loadTreeByBlockID(parentID)
+		parentTree, loadErr := LoadTreeByBlockID(parentID)
 		if nil != loadErr {
 			logging.LogErrorf("get parent tree [%s] failed", parentID)
 			err = ErrBlockNotFound

+ 1 - 1
kernel/model/format.go

@@ -30,7 +30,7 @@ import (
 )
 
 func AutoSpace(rootID string) (err error) {
-	tree, err := loadTreeByBlockID(rootID)
+	tree, err := LoadTreeByBlockID(rootID)
 	if nil != err {
 		return
 	}

+ 1 - 1
kernel/model/graph.go

@@ -63,7 +63,7 @@ func BuildTreeGraph(id, query string) (boxID string, nodes []*GraphNode, links [
 	nodes = []*GraphNode{}
 	links = []*GraphLink{}
 
-	tree, err := loadTreeByBlockID(id)
+	tree, err := LoadTreeByBlockID(id)
 	if nil != err {
 		return
 	}

+ 3 - 3
kernel/model/heading.go

@@ -117,7 +117,7 @@ func (tx *Transaction) doUnfoldHeading(operation *Operation) (ret *TxErr) {
 }
 
 func Doc2Heading(srcID, targetID string, after bool) (srcTreeBox, srcTreePath string, err error) {
-	srcTree, _ := loadTreeByBlockID(srcID)
+	srcTree, _ := LoadTreeByBlockID(srcID)
 	if nil == srcTree {
 		err = ErrBlockNotFound
 		return
@@ -135,7 +135,7 @@ func Doc2Heading(srcID, targetID string, after bool) (srcTreeBox, srcTreePath st
 		}
 	}
 
-	targetTree, _ := loadTreeByBlockID(targetID)
+	targetTree, _ := LoadTreeByBlockID(targetID)
 	if nil == targetTree {
 		err = ErrBlockNotFound
 		return
@@ -264,7 +264,7 @@ func Doc2Heading(srcID, targetID string, after bool) (srcTreeBox, srcTreePath st
 }
 
 func Heading2Doc(srcHeadingID, targetBoxID, targetPath string) (srcRootBlockID, newTargetPath string, err error) {
-	srcTree, _ := loadTreeByBlockID(srcHeadingID)
+	srcTree, _ := LoadTreeByBlockID(srcHeadingID)
 	if nil == srcTree {
 		err = ErrBlockNotFound
 		return

+ 1 - 1
kernel/model/index.go

@@ -253,7 +253,7 @@ func IndexRefs() {
 		bootProgressPart := int32(10.0 / float64(size))
 
 		for _, defBlockID := range defBlockIDs {
-			defTree, loadErr := LoadTreeByID(defBlockID)
+			defTree, loadErr := LoadTreeByBlockID(defBlockID)
 			if nil != loadErr {
 				continue
 			}

+ 1 - 1
kernel/model/listitem.go

@@ -27,7 +27,7 @@ import (
 )
 
 func ListItem2Doc(srcListItemID, targetBoxID, targetPath string) (srcRootBlockID, newTargetPath string, err error) {
-	srcTree, _ := loadTreeByBlockID(srcListItemID)
+	srcTree, _ := LoadTreeByBlockID(srcListItemID)
 	if nil == srcTree {
 		err = ErrBlockNotFound
 		return

+ 1 - 1
kernel/model/outline.go

@@ -31,7 +31,7 @@ func Outline(rootID string) (ret []*Path, err error) {
 	WaitForWritingFiles()
 
 	ret = []*Path{}
-	tree, _ := loadTreeByBlockID(rootID)
+	tree, _ := LoadTreeByBlockID(rootID)
 	if nil == tree {
 		return
 	}

+ 2 - 2
kernel/model/path.go

@@ -207,7 +207,7 @@ func toSubTree(blocks []*Block, keyword string) (ret []*Path) {
 		}
 		for _, c := range root.Children {
 			if "NodeListItem" == c.Type {
-				tree, _ := loadTreeByBlockID(c.RootID)
+				tree, _ := LoadTreeByBlockID(c.RootID)
 				li := treenode.GetNodeInTree(tree, c.ID)
 				if nil == li || nil == li.FirstChild {
 					// 反链面板拖拽到文档以后可能会出现这种情况 https://github.com/siyuan-note/siyuan/issues/5363
@@ -309,7 +309,7 @@ func toSubTree(blocks []*Block, keyword string) (ret []*Path) {
 					treeNode.Children = append(treeNode.Children, subRoot)
 				}
 			} else if "NodeHeading" == c.Type {
-				tree, _ := loadTreeByBlockID(c.RootID)
+				tree, _ := LoadTreeByBlockID(c.RootID)
 				h := treenode.GetNodeInTree(tree, c.ID)
 				if nil == h {
 					continue

+ 1 - 1
kernel/model/render.go

@@ -188,7 +188,7 @@ func renderBlockMarkdownR0(id string, rendered *[]string) (ret []*ast.Node) {
 
 	var err error
 	var t *parse.Tree
-	if t, err = loadTreeByBlockID(b.ID); nil != err {
+	if t, err = LoadTreeByBlockID(b.ID); nil != err {
 		return
 	}
 	node := treenode.GetNodeInTree(t, b.ID)

+ 6 - 6
kernel/model/search.go

@@ -266,7 +266,7 @@ func buildEmbedBlock(embedBlockID string, excludeIDs []string, headingMode int,
 	count := 0
 	for _, sb := range sqlBlocks {
 		if nil == trees[sb.RootID] {
-			tree, _ := loadTreeByBlockID(sb.RootID)
+			tree, _ := LoadTreeByBlockID(sb.RootID)
 			if nil == tree {
 				continue
 			}
@@ -324,7 +324,7 @@ func SearchRefBlock(id, rootID, keyword string, beforeLen int, isSquareBrackets
 		for _, ref := range refs {
 			tree := cachedTrees[ref.DefBlockRootID]
 			if nil == tree {
-				tree, _ = loadTreeByBlockID(ref.DefBlockRootID)
+				tree, _ = LoadTreeByBlockID(ref.DefBlockRootID)
 			}
 			if nil == tree {
 				continue
@@ -360,7 +360,7 @@ func SearchRefBlock(id, rootID, keyword string, beforeLen int, isSquareBrackets
 	for _, b := range ret {
 		tree := cachedTrees[b.RootID]
 		if nil == tree {
-			tree, _ = loadTreeByBlockID(b.RootID)
+			tree, _ = LoadTreeByBlockID(b.RootID)
 		}
 		if nil == tree {
 			continue
@@ -373,7 +373,7 @@ func SearchRefBlock(id, rootID, keyword string, beforeLen int, isSquareBrackets
 			// `((` 引用候选中排除当前块的父块 https://github.com/siyuan-note/siyuan/issues/4538
 			tree := cachedTrees[b.RootID]
 			if nil == tree {
-				tree, _ = loadTreeByBlockID(b.RootID)
+				tree, _ = LoadTreeByBlockID(b.RootID)
 				cachedTrees[b.RootID] = tree
 			}
 			if nil != tree {
@@ -466,7 +466,7 @@ func FindReplace(keyword, replacement string, replaceTypes map[string]bool, ids
 			continue
 		}
 
-		tree, _ = loadTreeByBlockID(id)
+		tree, _ = LoadTreeByBlockID(id)
 		if nil == tree {
 			continue
 		}
@@ -820,7 +820,7 @@ func FullTextSearchBlock(query string, boxes, paths []string, types map[string]b
 			if _, ok := rootMap[b.RootID]; !ok {
 				rootMap[b.RootID] = true
 				rootIDs = append(rootIDs, b.RootID)
-				tree, _ := loadTreeByBlockID(b.RootID)
+				tree, _ := LoadTreeByBlockID(b.RootID)
 				if nil == tree {
 					continue
 				}

+ 2 - 2
kernel/model/tag.go

@@ -52,7 +52,7 @@ func RemoveTag(label string) (err error) {
 
 	for treeID, blocks := range treeBlocks {
 		util.PushEndlessProgress("[" + treeID + "]")
-		tree, e := loadTreeByBlockID(treeID)
+		tree, e := LoadTreeByBlockID(treeID)
 		if nil != e {
 			util.ClearPushProgress(100)
 			return e
@@ -137,7 +137,7 @@ func RenameTag(oldLabel, newLabel string) (err error) {
 
 	for treeID, blocks := range treeBlocks {
 		util.PushEndlessProgress("[" + treeID + "]")
-		tree, e := loadTreeByBlockID(treeID)
+		tree, e := LoadTreeByBlockID(treeID)
 		if nil != e {
 			util.ClearPushProgress(100)
 			return e

+ 1 - 1
kernel/model/template.go

@@ -188,7 +188,7 @@ func RenderTemplate(p, id string, preview bool) (string, error) {
 }
 
 func renderTemplate(p, id string, preview bool) (string, error) {
-	tree, err := loadTreeByBlockID(id)
+	tree, err := LoadTreeByBlockID(id)
 	if nil != err {
 		return "", err
 	}

+ 1 - 1
kernel/model/transaction.go

@@ -1376,7 +1376,7 @@ func refreshDynamicRefTexts(updatedDefNodes map[string]*ast.Node, updatedTrees m
 		refTree, ok := updatedTrees[refTreeID]
 		if !ok {
 			var err error
-			refTree, err = loadTreeByBlockID(refTreeID)
+			refTree, err = LoadTreeByBlockID(refTreeID)
 			if nil != err {
 				continue
 			}

+ 2 - 6
kernel/model/tree.go

@@ -18,6 +18,7 @@ package model
 
 import (
 	"errors"
+	"github.com/siyuan-note/siyuan/kernel/task"
 	"io/fs"
 	"path"
 	"path/filepath"
@@ -30,7 +31,6 @@ import (
 	"github.com/siyuan-note/filelock"
 	"github.com/siyuan-note/logging"
 	"github.com/siyuan-note/siyuan/kernel/filesys"
-	"github.com/siyuan-note/siyuan/kernel/task"
 	"github.com/siyuan-note/siyuan/kernel/treenode"
 	"github.com/siyuan-note/siyuan/kernel/util"
 )
@@ -150,11 +150,7 @@ var (
 	ErrIndexing      = errors.New("indexing")
 )
 
-func LoadTreeByID(id string) (ret *parse.Tree, err error) {
-	return loadTreeByBlockID(id)
-}
-
-func loadTreeByBlockID(id string) (ret *parse.Tree, err error) {
+func LoadTreeByBlockID(id string) (ret *parse.Tree, err error) {
 	if "" == id {
 		return nil, ErrTreeNotFound
 	}

+ 58 - 0
kernel/treenode/av.go

@@ -0,0 +1,58 @@
+// SiYuan - Refactor your thinking
+// Copyright (c) 2020-present, b3log.org
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+package treenode
+
+import (
+	"path/filepath"
+
+	"github.com/siyuan-note/filelock"
+	"github.com/siyuan-note/logging"
+	"github.com/siyuan-note/siyuan/kernel/av"
+	"github.com/siyuan-note/siyuan/kernel/util"
+	"github.com/vmihailenco/msgpack/v5"
+)
+
+func GetMirrorAttrViewBlockIDs(avID string) (ret []string) {
+	av.AttributeViewBlocksLock.Lock()
+	defer av.AttributeViewBlocksLock.Unlock()
+
+	ret = []string{}
+	blocks := filepath.Join(util.DataDir, "storage", "av", "blocks.msgpack")
+	if !filelock.IsExist(blocks) {
+		return
+	}
+
+	data, err := filelock.ReadFile(blocks)
+	if nil != err {
+		logging.LogErrorf("read attribute view blocks failed: %s", err)
+		return
+	}
+
+	avBlocks := map[string][]string{}
+	if err = msgpack.Unmarshal(data, &avBlocks); nil != err {
+		logging.LogErrorf("unmarshal attribute view blocks failed: %s", err)
+		return
+	}
+
+	blockIDs := avBlocks[avID]
+	for _, blockID := range blockIDs {
+		if nil != GetBlockTree(blockID) {
+			ret = append(ret, blockID)
+		}
+	}
+	return
+}