|
@@ -21,10 +21,6 @@ import (
|
|
"encoding/json"
|
|
"encoding/json"
|
|
"errors"
|
|
"errors"
|
|
"fmt"
|
|
"fmt"
|
|
- "os"
|
|
|
|
- "path/filepath"
|
|
|
|
- "strings"
|
|
|
|
-
|
|
|
|
"github.com/88250/lute"
|
|
"github.com/88250/lute"
|
|
"github.com/88250/lute/parse"
|
|
"github.com/88250/lute/parse"
|
|
"github.com/88250/lute/render"
|
|
"github.com/88250/lute/render"
|
|
@@ -34,23 +30,39 @@ import (
|
|
"github.com/siyuan-note/siyuan/kernel/cache"
|
|
"github.com/siyuan-note/siyuan/kernel/cache"
|
|
"github.com/siyuan-note/siyuan/kernel/treenode"
|
|
"github.com/siyuan-note/siyuan/kernel/treenode"
|
|
"github.com/siyuan-note/siyuan/kernel/util"
|
|
"github.com/siyuan-note/siyuan/kernel/util"
|
|
|
|
+ "os"
|
|
|
|
+ "path/filepath"
|
|
|
|
+ "strings"
|
|
|
|
+ "sync"
|
|
)
|
|
)
|
|
|
|
|
|
func LoadTrees(ids []string) (ret map[string]*parse.Tree) {
|
|
func LoadTrees(ids []string) (ret map[string]*parse.Tree) {
|
|
- ret, tmpCache := map[string]*parse.Tree{}, map[string]*parse.Tree{}
|
|
|
|
|
|
+ ret = map[string]*parse.Tree{}
|
|
bts := treenode.GetBlockTrees(ids)
|
|
bts := treenode.GetBlockTrees(ids)
|
|
luteEngine := util.NewLute()
|
|
luteEngine := util.NewLute()
|
|
- for id, bt := range bts {
|
|
|
|
- tree := tmpCache[bt.RootID]
|
|
|
|
- if nil == tree {
|
|
|
|
- tree, _ = LoadTree(bt.BoxID, bt.Path, luteEngine)
|
|
|
|
- if nil == tree {
|
|
|
|
- logging.LogWarnf("load tree [%s] failed: %s", id, bt.Path)
|
|
|
|
- continue
|
|
|
|
- }
|
|
|
|
- tmpCache[bt.RootID] = tree
|
|
|
|
|
|
+ var boxIDs []string
|
|
|
|
+ var paths []string
|
|
|
|
+ seen := make(map[string]bool)
|
|
|
|
+ for _, bt := range bts {
|
|
|
|
+ key := bt.BoxID + bt.Path
|
|
|
|
+ if !seen[key] {
|
|
|
|
+ seen[key] = true
|
|
|
|
+ boxIDs = append(boxIDs, bt.BoxID)
|
|
|
|
+ paths = append(paths, bt.Path)
|
|
}
|
|
}
|
|
- ret[id] = tree
|
|
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ trees, errs := BatchLoadTrees(boxIDs, paths, luteEngine)
|
|
|
|
+
|
|
|
|
+ for i := range trees {
|
|
|
|
+ tree := trees[i]
|
|
|
|
+ err := errs[i]
|
|
|
|
+ if err != nil || tree == nil {
|
|
|
|
+ logging.LogErrorf("load tree failed: %s", err)
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ret[tree.ID] = tree
|
|
}
|
|
}
|
|
return
|
|
return
|
|
}
|
|
}
|
|
@@ -67,6 +79,31 @@ func LoadTree(boxID, p string, luteEngine *lute.Lute) (ret *parse.Tree, err erro
|
|
return
|
|
return
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+func BatchLoadTrees(boxIDs, paths []string, luteEngine *lute.Lute) ([]*parse.Tree, []error) {
|
|
|
|
+ var wg sync.WaitGroup
|
|
|
|
+ results := make([]*parse.Tree, len(paths))
|
|
|
|
+ errors := make([]error, len(paths))
|
|
|
|
+
|
|
|
|
+ for i := range paths {
|
|
|
|
+ wg.Add(1)
|
|
|
|
+ go func(i int) {
|
|
|
|
+ defer wg.Done()
|
|
|
|
+
|
|
|
|
+ boxID := boxIDs[i]
|
|
|
|
+ path := paths[i]
|
|
|
|
+
|
|
|
|
+ tree, err := LoadTree(boxID, path, luteEngine)
|
|
|
|
+
|
|
|
|
+ results[i] = tree
|
|
|
|
+ errors[i] = err
|
|
|
|
+ }(i)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ wg.Wait()
|
|
|
|
+
|
|
|
|
+ return results, errors
|
|
|
|
+}
|
|
|
|
+
|
|
func LoadTreeByData(data []byte, boxID, p string, luteEngine *lute.Lute) (ret *parse.Tree, err error) {
|
|
func LoadTreeByData(data []byte, boxID, p string, luteEngine *lute.Lute) (ret *parse.Tree, err error) {
|
|
ret = parseJSON2Tree(boxID, p, data, luteEngine)
|
|
ret = parseJSON2Tree(boxID, p, data, luteEngine)
|
|
if nil == ret {
|
|
if nil == ret {
|