浏览代码

Merge remote-tracking branch 'origin/dev' into dev

Vanessa 2 年之前
父节点
当前提交
af12e702ad

+ 0 - 1
kernel/api/setting.go

@@ -221,7 +221,6 @@ func setSearch(c *gin.Context) {
 	if s.CaseSensitive != oldCaseSensitive {
 	if s.CaseSensitive != oldCaseSensitive {
 		model.FullReindex()
 		model.FullReindex()
 	}
 	}
-	sql.ClearVirtualRefKeywords()
 	ret.Data = s
 	ret.Data = s
 }
 }
 
 

+ 1 - 0
kernel/job/cron.go

@@ -39,6 +39,7 @@ func StartCron() {
 	go every(util.SQLFlushInterval, sql.FlushTxJob)
 	go every(util.SQLFlushInterval, sql.FlushTxJob)
 	go every(10*time.Minute, model.FixIndexJob)
 	go every(10*time.Minute, model.FixIndexJob)
 	go every(10*time.Minute, model.IndexEmbedBlockJob)
 	go every(10*time.Minute, model.IndexEmbedBlockJob)
+	go every(10*time.Minute, model.CacheVirtualBlockRefJob)
 	go every(12*time.Second, model.OCRAssetsJob)
 	go every(12*time.Second, model.OCRAssetsJob)
 	go every(12*time.Second, model.FlushAssetsTextsJob)
 	go every(12*time.Second, model.FlushAssetsTextsJob)
 	go every(30*time.Second, model.HookDesktopUIProcJob)
 	go every(30*time.Second, model.HookDesktopUIProcJob)

+ 2 - 2
kernel/model/backlink.go

@@ -167,7 +167,7 @@ func buildBacklink(refID string, refTree *parse.Tree, keywords []string, luteEng
 					return ast.WalkContinue
 					return ast.WalkContinue
 				}
 				}
 
 
-				markReplaceSpan(n, &unlinks, keywords, searchMarkDataType, luteEngine)
+				markReplaceSpan(n, &unlinks, keywords, search.MarkDataType, luteEngine)
 				return ast.WalkContinue
 				return ast.WalkContinue
 			})
 			})
 
 
@@ -690,7 +690,7 @@ func searchBackmention(mentionKeywords []string, keyword string, excludeBacklink
 			continue
 			continue
 		}
 		}
 
 
-		newText := markReplaceSpanWithSplit(text, mentionKeywords, getMarkSpanStart(searchMarkDataType), getMarkSpanEnd())
+		newText := markReplaceSpanWithSplit(text, mentionKeywords, search.GetMarkSpanStart(search.MarkDataType), search.GetMarkSpanEnd())
 		if text != newText {
 		if text != newText {
 			tmp = append(tmp, b)
 			tmp = append(tmp, b)
 		}
 		}

+ 2 - 15
kernel/model/file.go

@@ -440,19 +440,6 @@ func StatTree(id string) (ret *util.BlockStatResult) {
 	}
 	}
 }
 }
 
 
-const (
-	searchMarkDataType      = "search-mark"
-	virtualBlockRefDataType = "virtual-block-ref"
-)
-
-func getMarkSpanStart(dataType string) string {
-	return fmt.Sprintf("<span data-type=\"%s\">", dataType)
-}
-
-func getMarkSpanEnd() string {
-	return "</span>"
-}
-
 func GetDoc(startID, endID, id string, index int, keyword string, mode int, size int, isBacklink bool) (blockCount, childBlockCount int, dom, parentID, parent2ID, rootID, typ string, eof bool, boxID, docPath string, isBacklinkExpand bool, err error) {
 func GetDoc(startID, endID, id string, index int, keyword string, mode int, size int, isBacklink bool) (blockCount, childBlockCount int, dom, parentID, parent2ID, rootID, typ string, eof bool, boxID, docPath string, isBacklinkExpand bool, err error) {
 	//os.MkdirAll("pprof", 0755)
 	//os.MkdirAll("pprof", 0755)
 	//cpuProfile, _ := os.Create("pprof/GetDoc")
 	//cpuProfile, _ := os.Create("pprof/GetDoc")
@@ -618,7 +605,7 @@ func GetDoc(startID, endID, id string, index int, keyword string, mode int, size
 	}
 	}
 
 
 	refCount := sql.QueryRootChildrenRefCount(rootID)
 	refCount := sql.QueryRootChildrenRefCount(rootID)
-	virtualBlockRefKeywords := getVirtualRefKeywords(tree.Root.IALAttr("title"))
+	virtualBlockRefKeywords := getBlockVirtualRefKeywords(tree.Root)
 
 
 	subTree := &parse.Tree{ID: rootID, Root: &ast.Node{Type: ast.NodeDocument}, Marks: tree.Marks}
 	subTree := &parse.Tree{ID: rootID, Root: &ast.Node{Type: ast.NodeDocument}, Marks: tree.Marks}
 	keyword = strings.Join(strings.Split(keyword, " "), search.TermSep)
 	keyword = strings.Join(strings.Split(keyword, " "), search.TermSep)
@@ -659,7 +646,7 @@ func GetDoc(startID, endID, id string, index int, keyword string, mode int, size
 					}
 					}
 				}
 				}
 				if hitBlock {
 				if hitBlock {
-					if markReplaceSpan(n, &unlinks, keywords, searchMarkDataType, luteEngine) {
+					if markReplaceSpan(n, &unlinks, keywords, search.MarkDataType, luteEngine) {
 						return ast.WalkContinue
 						return ast.WalkContinue
 					}
 					}
 				}
 				}

+ 1 - 1
kernel/model/history.go

@@ -180,7 +180,7 @@ func GetDocHistoryContent(historyPath, keyword string) (id, rootID, content stri
 			n.RemoveIALAttr("fold")
 			n.RemoveIALAttr("fold")
 
 
 			if 0 < len(keywords) {
 			if 0 < len(keywords) {
-				if markReplaceSpan(n, &unlinks, keywords, searchMarkDataType, luteEngine) {
+				if markReplaceSpan(n, &unlinks, keywords, search.MarkDataType, luteEngine) {
 					return ast.WalkContinue
 					return ast.WalkContinue
 				}
 				}
 			}
 			}

+ 6 - 6
kernel/model/search.go

@@ -915,9 +915,9 @@ func stringQuery(query string) string {
 func markReplaceSpan(n *ast.Node, unlinks *[]*ast.Node, keywords []string, markSpanDataType string, luteEngine *lute.Lute) bool {
 func markReplaceSpan(n *ast.Node, unlinks *[]*ast.Node, keywords []string, markSpanDataType string, luteEngine *lute.Lute) bool {
 	text := n.Content()
 	text := n.Content()
 	if ast.NodeText == n.Type {
 	if ast.NodeText == n.Type {
-		text = search.EncloseHighlighting(text, keywords, getMarkSpanStart(markSpanDataType), getMarkSpanEnd(), Conf.Search.CaseSensitive)
+		text = search.EncloseHighlighting(text, keywords, search.GetMarkSpanStart(markSpanDataType), search.GetMarkSpanEnd(), Conf.Search.CaseSensitive)
 		n.Tokens = gulu.Str.ToBytes(text)
 		n.Tokens = gulu.Str.ToBytes(text)
-		if bytes.Contains(n.Tokens, []byte(searchMarkDataType)) {
+		if bytes.Contains(n.Tokens, []byte(search.MarkDataType)) {
 			linkTree := parse.Inline("", n.Tokens, luteEngine.ParseOptions)
 			linkTree := parse.Inline("", n.Tokens, luteEngine.ParseOptions)
 			var children []*ast.Node
 			var children []*ast.Node
 			for c := linkTree.Root.FirstChild.FirstChild; nil != c; c = c.Next {
 			for c := linkTree.Root.FirstChild.FirstChild; nil != c; c = c.Next {
@@ -935,10 +935,10 @@ func markReplaceSpan(n *ast.Node, unlinks *[]*ast.Node, keywords []string, markS
 			return false
 			return false
 		}
 		}
 
 
-		startTag := getMarkSpanStart(markSpanDataType)
-		text = search.EncloseHighlighting(text, keywords, startTag, getMarkSpanEnd(), Conf.Search.CaseSensitive)
-		if strings.Contains(text, searchMarkDataType) {
-			dataType := getMarkSpanStart(n.TextMarkType + " " + searchMarkDataType)
+		startTag := search.GetMarkSpanStart(markSpanDataType)
+		text = search.EncloseHighlighting(text, keywords, startTag, search.GetMarkSpanEnd(), Conf.Search.CaseSensitive)
+		if strings.Contains(text, search.MarkDataType) {
+			dataType := search.GetMarkSpanStart(n.TextMarkType + " " + search.MarkDataType)
 			text = strings.ReplaceAll(text, startTag, dataType)
 			text = strings.ReplaceAll(text, startTag, dataType)
 			tokens := gulu.Str.ToBytes(text)
 			tokens := gulu.Str.ToBytes(text)
 			linkTree := parse.Inline("", tokens, luteEngine.ParseOptions)
 			linkTree := parse.Inline("", tokens, luteEngine.ParseOptions)

+ 90 - 4
kernel/model/virutalref.go

@@ -17,6 +17,7 @@
 package model
 package model
 
 
 import (
 import (
+	"bytes"
 	"regexp"
 	"regexp"
 	"sort"
 	"sort"
 	"strings"
 	"strings"
@@ -25,12 +26,83 @@ import (
 	"github.com/88250/lute"
 	"github.com/88250/lute"
 	"github.com/88250/lute/ast"
 	"github.com/88250/lute/ast"
 	"github.com/88250/lute/parse"
 	"github.com/88250/lute/parse"
+	"github.com/dgraph-io/ristretto"
+	"github.com/siyuan-note/siyuan/kernel/search"
 	"github.com/siyuan-note/siyuan/kernel/sql"
 	"github.com/siyuan-note/siyuan/kernel/sql"
 	"github.com/siyuan-note/siyuan/kernel/treenode"
 	"github.com/siyuan-note/siyuan/kernel/treenode"
 )
 )
 
 
+// virtualBlockRefCache 用于保存块关联的虚拟引用关键字。
+// 改进打开虚拟引用后加载文档的性能 https://github.com/siyuan-note/siyuan/issues/7378
+var virtualBlockRefCache, _ = ristretto.NewCache(&ristretto.Config{
+	NumCounters: 102400,
+	MaxCost:     10240,
+	BufferItems: 64,
+})
+
+func getBlockVirtualRefKeywords(root *ast.Node) (ret []string) {
+	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()
+		ret = putBlockVirtualRefKeywords(content, root.ID, root.IALAttr("title"))
+		return
+	}
+	ret = val.([]string)
+	return
+}
+
+func putBlockVirtualRefKeywords(blockContent, blockID, docTitle string) (ret []string) {
+	keywords := getVirtualRefKeywords(docTitle)
+	if 1 > len(keywords) {
+		return
+	}
+
+	contentTmp := blockContent
+	if !Conf.Search.CaseSensitive {
+		contentTmp = strings.ToLower(blockContent)
+	}
+	for _, keyword := range keywords {
+		keywordTmp := keyword
+		if !Conf.Search.CaseSensitive {
+			keywordTmp = strings.ToLower(keyword)
+		}
+
+		if strings.Contains(contentTmp, keywordTmp) {
+			ret = append(ret, keyword)
+		}
+	}
+
+	if 1 > len(ret) {
+		return
+	}
+
+	ret = gulu.Str.RemoveDuplicatedElem(ret)
+	virtualBlockRefCache.Set(blockID, ret, 1)
+	return
+}
+
+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)
+}
+
 func processVirtualRef(n *ast.Node, unlinks *[]*ast.Node, virtualBlockRefKeywords []string, refCount map[string]int, luteEngine *lute.Lute) bool {
 func processVirtualRef(n *ast.Node, unlinks *[]*ast.Node, virtualBlockRefKeywords []string, refCount map[string]int, luteEngine *lute.Lute) bool {
-	if !Conf.Editor.VirtualBlockRef || 1 > len(virtualBlockRefKeywords) {
+	if !Conf.Editor.VirtualBlockRef {
 		return false
 		return false
 	}
 	}
 
 
@@ -43,8 +115,18 @@ func processVirtualRef(n *ast.Node, unlinks *[]*ast.Node, virtualBlockRefKeyword
 		return false
 		return false
 	}
 	}
 
 
+	if 1 > len(virtualBlockRefKeywords) {
+		return false
+	}
+
 	content := string(n.Tokens)
 	content := string(n.Tokens)
-	newContent := markReplaceSpanWithSplit(content, virtualBlockRefKeywords, getMarkSpanStart(virtualBlockRefDataType), getMarkSpanEnd())
+	tmp := gulu.Str.RemoveInvisible(content)
+	tmp = strings.TrimSpace(tmp)
+	if "" == tmp {
+		return false
+	}
+
+	newContent := markReplaceSpanWithSplit(content, virtualBlockRefKeywords, search.GetMarkSpanStart(search.VirtualBlockRefDataType), search.GetMarkSpanEnd())
 	if content != newContent {
 	if content != newContent {
 		// 虚拟引用排除命中自身块命名和别名的情况 https://github.com/siyuan-note/siyuan/issues/3185
 		// 虚拟引用排除命中自身块命名和别名的情况 https://github.com/siyuan-note/siyuan/issues/3185
 		var blockKeys []string
 		var blockKeys []string
@@ -55,7 +137,7 @@ func processVirtualRef(n *ast.Node, unlinks *[]*ast.Node, virtualBlockRefKeyword
 			blockKeys = append(blockKeys, alias)
 			blockKeys = append(blockKeys, alias)
 		}
 		}
 		if 0 < len(blockKeys) {
 		if 0 < len(blockKeys) {
-			keys := gulu.Str.SubstringsBetween(newContent, getMarkSpanStart(virtualBlockRefDataType), getMarkSpanEnd())
+			keys := gulu.Str.SubstringsBetween(newContent, search.GetMarkSpanStart(search.VirtualBlockRefDataType), search.GetMarkSpanEnd())
 			for _, k := range keys {
 			for _, k := range keys {
 				if gulu.Str.Contains(k, blockKeys) {
 				if gulu.Str.Contains(k, blockKeys) {
 					return true
 					return true
@@ -83,7 +165,10 @@ func getVirtualRefKeywords(docName string) (ret []string) {
 		return
 		return
 	}
 	}
 
 
-	ret = sql.QueryVirtualRefKeywords(Conf.Search.VirtualRefName, Conf.Search.VirtualRefAlias, Conf.Search.VirtualRefAnchor, Conf.Search.VirtualRefDoc)
+	if val, ok := virtualBlockRefCache.Get("virtual_ref"); ok {
+		ret = val.([]string)
+	}
+
 	if "" != strings.TrimSpace(Conf.Editor.VirtualBlockRefInclude) {
 	if "" != strings.TrimSpace(Conf.Editor.VirtualBlockRefInclude) {
 		include := strings.ReplaceAll(Conf.Editor.VirtualBlockRefInclude, "\\,", "__comma@sep__")
 		include := strings.ReplaceAll(Conf.Editor.VirtualBlockRefInclude, "\\,", "__comma@sep__")
 		includes := strings.Split(include, ",")
 		includes := strings.Split(include, ",")
@@ -129,6 +214,7 @@ func getVirtualRefKeywords(docName string) (ret []string) {
 	ret = gulu.Str.ExcludeElem(ret, []string{docName})
 	ret = gulu.Str.ExcludeElem(ret, []string{docName})
 	ret = prepareMarkKeywords(ret)
 	ret = prepareMarkKeywords(ret)
 
 
+	// 在 设置 - 搜索 中分别增加虚拟引用和反链提及 `关键字数量限制` https://github.com/siyuan-note/siyuan/issues/6603
 	if Conf.Search.VirtualRefKeywordsLimit < len(ret) {
 	if Conf.Search.VirtualRefKeywordsLimit < len(ret) {
 		ret = ret[:Conf.Search.VirtualRefKeywordsLimit]
 		ret = ret[:Conf.Search.VirtualRefKeywordsLimit]
 	}
 	}

+ 14 - 0
kernel/search/mark.go

@@ -17,6 +17,7 @@
 package search
 package search
 
 
 import (
 import (
+	"fmt"
 	"regexp"
 	"regexp"
 	"strings"
 	"strings"
 	"unicode/utf8"
 	"unicode/utf8"
@@ -99,3 +100,16 @@ func EncloseHighlighting(text string, keywords []string, openMark, closeMark str
 	}
 	}
 	return
 	return
 }
 }
+
+const (
+	MarkDataType            = "search-mark"
+	VirtualBlockRefDataType = "virtual-block-ref"
+)
+
+func GetMarkSpanStart(dataType string) string {
+	return fmt.Sprintf("<span data-type=\"%s\">", dataType)
+}
+
+func GetMarkSpanEnd() string {
+	return "</span>"
+}

+ 0 - 6
kernel/sql/block_ref_query.go

@@ -29,11 +29,6 @@ import (
 )
 )
 
 
 func QueryVirtualRefKeywords(name, alias, anchor, doc bool) (ret []string) {
 func QueryVirtualRefKeywords(name, alias, anchor, doc bool) (ret []string) {
-	ret, ok := getVirtualRefKeywordsCache()
-	if ok {
-		return ret
-	}
-
 	if name {
 	if name {
 		ret = append(ret, queryNames()...)
 		ret = append(ret, queryNames()...)
 	}
 	}
@@ -50,7 +45,6 @@ func QueryVirtualRefKeywords(name, alias, anchor, doc bool) (ret []string) {
 	sort.SliceStable(ret, func(i, j int) bool {
 	sort.SliceStable(ret, func(i, j int) bool {
 		return len(ret[i]) >= len(ret[j])
 		return len(ret[i]) >= len(ret[j])
 	})
 	})
-	setVirtualRefKeywords(ret)
 	return
 	return
 }
 }
 
 

+ 16 - 46
kernel/sql/cache.go

@@ -28,28 +28,29 @@ import (
 	"github.com/siyuan-note/logging"
 	"github.com/siyuan-note/logging"
 )
 )
 
 
-var memCache, _ = ristretto.NewCache(&ristretto.Config{
-	NumCounters: 10240,
-	MaxCost:     1024,
-	BufferItems: 64,
-})
-var disabled = true
+var cacheDisabled = true
 
 
 func enableCache() {
 func enableCache() {
-	disabled = false
+	cacheDisabled = false
 }
 }
 
 
 func disableCache() {
 func disableCache() {
-	disabled = true
+	cacheDisabled = true
 }
 }
 
 
-func ClearBlockCache() {
-	memCache.Clear()
+var blockCache, _ = ristretto.NewCache(&ristretto.Config{
+	NumCounters: 10240,
+	MaxCost:     1024,
+	BufferItems: 64,
+})
+
+func ClearCache() {
+	blockCache.Clear()
 	debug.FreeOSMemory()
 	debug.FreeOSMemory()
 }
 }
 
 
 func putBlockCache(block *Block) {
 func putBlockCache(block *Block) {
-	if disabled {
+	if cacheDisabled {
 		return
 		return
 	}
 	}
 
 
@@ -58,15 +59,15 @@ func putBlockCache(block *Block) {
 		logging.LogErrorf("clone block failed: %v", err)
 		logging.LogErrorf("clone block failed: %v", err)
 		return
 		return
 	}
 	}
-	memCache.Set(cloned.ID, cloned, 1)
+	blockCache.Set(cloned.ID, cloned, 1)
 }
 }
 
 
 func getBlockCache(id string) (ret *Block) {
 func getBlockCache(id string) (ret *Block) {
-	if disabled {
+	if cacheDisabled {
 		return
 		return
 	}
 	}
 
 
-	b, _ := memCache.Get(id)
+	b, _ := blockCache.Get(id)
 	if nil != b {
 	if nil != b {
 		ret = b.(*Block)
 		ret = b.(*Block)
 	}
 	}
@@ -74,41 +75,10 @@ func getBlockCache(id string) (ret *Block) {
 }
 }
 
 
 func removeBlockCache(id string) {
 func removeBlockCache(id string) {
-	memCache.Del(id)
+	blockCache.Del(id)
 	removeRefCacheByDefID(id)
 	removeRefCacheByDefID(id)
 }
 }
 
 
-var virtualRefKeywordsCacheTime = time.Now()
-
-func getVirtualRefKeywordsCache() ([]string, bool) {
-	if disabled {
-		return nil, false
-	}
-
-	// 虚拟引用关键字缓存调整为 10 分钟 https://github.com/siyuan-note/siyuan/issues/6602
-	if 10 < time.Now().Sub(virtualRefKeywordsCacheTime).Minutes() {
-		ClearVirtualRefKeywords()
-		return nil, false
-	}
-
-	if val, ok := memCache.Get("virtual_ref"); ok {
-		return val.([]string), true
-	}
-	return nil, false
-}
-
-func setVirtualRefKeywords(keywords []string) {
-	if disabled {
-		return
-	}
-
-	memCache.Set("virtual_ref", keywords, 1)
-}
-
-func ClearVirtualRefKeywords() {
-	memCache.Del("virtual_ref")
-}
-
 var defIDRefsCache = gcache.New(30*time.Minute, 5*time.Minute) // [defBlockID]map[refBlockID]*Ref
 var defIDRefsCache = gcache.New(30*time.Minute, 5*time.Minute) // [defBlockID]map[refBlockID]*Ref
 
 
 func GetRefsCacheByDefID(defID string) (ret []*Ref) {
 func GetRefsCacheByDefID(defID string) (ret []*Ref) {

+ 6 - 6
kernel/sql/database.go

@@ -67,7 +67,7 @@ func InitDatabase(forceRebuild bool) (err error) {
 	initDatabaseLock.Lock()
 	initDatabaseLock.Lock()
 	defer initDatabaseLock.Unlock()
 	defer initDatabaseLock.Unlock()
 
 
-	ClearBlockCache()
+	ClearCache()
 	disableCache()
 	disableCache()
 	defer enableCache()
 	defer enableCache()
 
 
@@ -888,7 +888,7 @@ func deleteBlocksByBoxTx(tx *sql.Tx, box string) (err error) {
 	if err = execStmtTx(tx, stmt, box); nil != err {
 	if err = execStmtTx(tx, stmt, box); nil != err {
 		return
 		return
 	}
 	}
-	ClearBlockCache()
+	ClearCache()
 	return
 	return
 }
 }
 
 
@@ -1012,7 +1012,7 @@ func deleteByRootID(tx *sql.Tx, rootID string, context map[string]interface{}) (
 	if err = execStmtTx(tx, stmt, rootID); nil != err {
 	if err = execStmtTx(tx, stmt, rootID); nil != err {
 		return
 		return
 	}
 	}
-	ClearBlockCache()
+	ClearCache()
 	eventbus.Publish(eventbus.EvtSQLDeleteBlocks, context, rootID)
 	eventbus.Publish(eventbus.EvtSQLDeleteBlocks, context, rootID)
 	return
 	return
 }
 }
@@ -1048,7 +1048,7 @@ func batchDeleteByRootIDs(tx *sql.Tx, rootIDs []string, context map[string]inter
 	if err = execStmtTx(tx, stmt); nil != err {
 	if err = execStmtTx(tx, stmt); nil != err {
 		return
 		return
 	}
 	}
-	ClearBlockCache()
+	ClearCache()
 	eventbus.Publish(eventbus.EvtSQLDeleteBlocks, context, fmt.Sprintf("%d", len(rootIDs)))
 	eventbus.Publish(eventbus.EvtSQLDeleteBlocks, context, fmt.Sprintf("%d", len(rootIDs)))
 	return
 	return
 }
 }
@@ -1082,7 +1082,7 @@ func batchDeleteByPathPrefix(tx *sql.Tx, boxID, pathPrefix string) (err error) {
 	if err = execStmtTx(tx, stmt, boxID, pathPrefix+"%"); nil != err {
 	if err = execStmtTx(tx, stmt, boxID, pathPrefix+"%"); nil != err {
 		return
 		return
 	}
 	}
-	ClearBlockCache()
+	ClearCache()
 	return
 	return
 }
 }
 
 
@@ -1099,7 +1099,7 @@ func batchUpdateHPath(tx *sql.Tx, boxID, rootID, oldHPath, newHPath string) (err
 	if err = execStmtTx(tx, stmt, newHPath, boxID, rootID, oldHPath); nil != err {
 	if err = execStmtTx(tx, stmt, newHPath, boxID, rootID, oldHPath); nil != err {
 		return
 		return
 	}
 	}
-	ClearBlockCache()
+	ClearCache()
 	return
 	return
 }
 }