Bläddra i källkod

:art: Improve `Add to Database` search sorting https://github.com/siyuan-note/siyuan/issues/10952

Daniel 1 år sedan
förälder
incheckning
b3a2c49f15
3 ändrade filer med 122 tillägg och 22 borttagningar
  1. 75 0
      kernel/av/mirror.go
  2. 20 6
      kernel/model/attribute_view.go
  3. 27 16
      kernel/treenode/av.go

+ 75 - 0
kernel/av/mirror.go

@@ -6,6 +6,7 @@ import (
 	"sync"
 
 	"github.com/88250/gulu"
+	"github.com/88250/lute/ast"
 	"github.com/siyuan-note/filelock"
 	"github.com/siyuan-note/logging"
 	"github.com/siyuan-note/siyuan/kernel/util"
@@ -16,6 +17,30 @@ var (
 	AttributeViewBlocksLock = sync.Mutex{}
 )
 
+func GetBlockRels() (ret map[string][]string) {
+	AttributeViewBlocksLock.Lock()
+	defer AttributeViewBlocksLock.Unlock()
+
+	ret = map[string][]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
+	}
+
+	if err = msgpack.Unmarshal(data, &ret); nil != err {
+		logging.LogErrorf("unmarshal attribute view blocks failed: %s", err)
+		return
+	}
+	return
+}
+
 func IsMirror(avID string) bool {
 	AttributeViewBlocksLock.Lock()
 	defer AttributeViewBlocksLock.Unlock()
@@ -86,6 +111,56 @@ func RemoveBlockRel(avID, blockID string) {
 	}
 }
 
+func BatchUpsertBlockRel(nodes []*ast.Node) {
+	AttributeViewBlocksLock.Lock()
+	defer AttributeViewBlocksLock.Unlock()
+
+	avBlocks := map[string][]string{}
+	blocks := filepath.Join(util.DataDir, "storage", "av", "blocks.msgpack")
+	if !filelock.IsExist(blocks) {
+		if err := os.MkdirAll(filepath.Dir(blocks), 0755); nil != err {
+			logging.LogErrorf("create attribute view dir failed: %s", err)
+			return
+		}
+	} else {
+		data, err := filelock.ReadFile(blocks)
+		if nil != err {
+			logging.LogErrorf("read attribute view blocks failed: %s", err)
+			return
+		}
+
+		if err = msgpack.Unmarshal(data, &avBlocks); nil != err {
+			logging.LogErrorf("unmarshal attribute view blocks failed: %s", err)
+			return
+		}
+	}
+
+	for _, n := range nodes {
+		if ast.NodeAttributeView != n.Type {
+			continue
+		}
+
+		if "" == n.AttributeViewID || "" == n.ID {
+			continue
+		}
+
+		blockIDs := avBlocks[n.AttributeViewID]
+		blockIDs = append(blockIDs, n.ID)
+		blockIDs = gulu.Str.RemoveDuplicatedElem(blockIDs)
+		avBlocks[n.AttributeViewID] = blockIDs
+	}
+
+	data, err := msgpack.Marshal(avBlocks)
+	if nil != err {
+		logging.LogErrorf("marshal attribute view blocks failed: %s", err)
+		return
+	}
+	if err = filelock.WriteFile(blocks, data); nil != err {
+		logging.LogErrorf("write attribute view blocks failed: %s", err)
+		return
+	}
+}
+
 func UpsertBlockRel(avID, blockID string) {
 	AttributeViewBlocksLock.Lock()
 	defer AttributeViewBlocksLock.Unlock()

+ 20 - 6
kernel/model/attribute_view.go

@@ -208,7 +208,7 @@ func SearchAttributeView(keyword string) (ret []*SearchAttributeViewResult) {
 		logging.LogErrorf("read directory [%s] failed: %s", avDir, err)
 		return
 	}
-
+	avBlockRels := av.GetBlockRels()
 	for _, entry := range entries {
 		if entry.IsDir() {
 			continue
@@ -219,6 +219,10 @@ func SearchAttributeView(keyword string) (ret []*SearchAttributeViewResult) {
 			continue
 		}
 
+		if nil == avBlockRels[id] {
+			continue
+		}
+
 		name, _ := av.GetAttributeViewNameByPath(filepath.Join(avDir, entry.Name()))
 		info, _ := entry.Info()
 		if "" != keyword {
@@ -237,23 +241,33 @@ func SearchAttributeView(keyword string) (ret []*SearchAttributeViewResult) {
 			}
 			avs = append(avs, a)
 		}
-
 	}
 
 	if "" == keyword {
 		sort.Slice(avs, func(i, j int) bool { return avs[i].AvUpdated > avs[j].AvUpdated })
 	} else {
-		sort.Slice(avs, func(i, j int) bool { return avs[i].Score > avs[j].Score })
+		sort.SliceStable(avs, func(i, j int) bool {
+			if avs[i].Score == avs[j].Score {
+				return avs[i].AvUpdated > avs[j].AvUpdated
+			}
+			return avs[i].Score > avs[j].Score
+		})
 	}
-	if 16 < len(avs) {
-		avs = avs[:16]
+	if 12 <= len(avs) {
+		avs = avs[:12]
 	}
 	var avIDs []string
 	for _, a := range avs {
 		avIDs = append(avIDs, a.AvID)
 	}
 
-	blockIDs := treenode.BatchGetMirrorAttrViewBlockIDs(avIDs)
+	avBlocks := treenode.BatchGetMirrorAttrViewBlocks(avIDs)
+	var blockIDs []string
+	for _, avBlock := range avBlocks {
+		blockIDs = append(blockIDs, avBlock.BlockIDs...)
+	}
+	blockIDs = gulu.Str.RemoveDuplicatedElem(blockIDs)
+
 	trees := map[string]*parse.Tree{}
 	for _, blockID := range blockIDs {
 		bt := treenode.GetBlockTree(blockID)

+ 27 - 16
kernel/treenode/av.go

@@ -26,12 +26,11 @@ import (
 	"github.com/vmihailenco/msgpack/v5"
 )
 
-func BatchGetMirrorAttrViewBlockIDs(avIDs []string) (ret map[string]string) {
+func GetMirrorAttrViewBlockIDs(avID string) (ret []string) {
 	av.AttributeViewBlocksLock.Lock()
 	defer av.AttributeViewBlocksLock.Unlock()
 
-	ret = map[string]string{}
-
+	ret = []string{}
 	blocks := filepath.Join(util.DataDir, "storage", "av", "blocks.msgpack")
 	if !filelock.IsExist(blocks) {
 		return
@@ -49,23 +48,26 @@ func BatchGetMirrorAttrViewBlockIDs(avIDs []string) (ret map[string]string) {
 		return
 	}
 
-	for _, avID := range avIDs {
-		blockIDs := avBlocks[avID]
-		for _, blockID := range blockIDs {
-			if nil != GetBlockTree(blockID) {
-				ret[avID] = blockID
-				break
-			}
+	blockIDs := avBlocks[avID]
+	for _, blockID := range blockIDs {
+		if nil != GetBlockTree(blockID) {
+			ret = append(ret, blockID)
 		}
 	}
 	return
 }
 
-func GetMirrorAttrViewBlockIDs(avID string) (ret []string) {
+type AvBlock struct {
+	AvID     string
+	BlockIDs []string
+}
+
+func BatchGetMirrorAttrViewBlocks(avIDs []string) (ret []*AvBlock) {
 	av.AttributeViewBlocksLock.Lock()
 	defer av.AttributeViewBlocksLock.Unlock()
 
-	ret = []string{}
+	ret = []*AvBlock{}
+
 	blocks := filepath.Join(util.DataDir, "storage", "av", "blocks.msgpack")
 	if !filelock.IsExist(blocks) {
 		return
@@ -83,11 +85,20 @@ func GetMirrorAttrViewBlockIDs(avID string) (ret []string) {
 		return
 	}
 
-	blockIDs := avBlocks[avID]
-	for _, blockID := range blockIDs {
-		if nil != GetBlockTree(blockID) {
-			ret = append(ret, blockID)
+	for _, avID := range avIDs {
+		var blockIDs []string
+		for _, blockID := range avBlocks[avID] {
+			if nil == GetBlockTree(blockID) {
+				continue
+			}
+
+			blockIDs = append(blockIDs, blockID)
+		}
+		avBlock := &AvBlock{
+			AvID:     avID,
+			BlockIDs: blockIDs,
 		}
+		ret = append(ret, avBlock)
 	}
 	return
 }