diff --git a/kernel/api/filetree.go b/kernel/api/filetree.go index ca1909ec4..23b6a403d 100644 --- a/kernel/api/filetree.go +++ b/kernel/api/filetree.go @@ -32,25 +32,6 @@ import ( "github.com/siyuan-note/siyuan/kernel/util" ) -func reindexTree(c *gin.Context) { - ret := gulu.Ret.NewResult() - defer c.JSON(http.StatusOK, ret) - - arg, ok := util.JsonArg(c, ret) - if !ok { - return - } - - path := arg["path"].(string) - err := model.ReindexTree(path) - if nil != err { - ret.Code = -1 - ret.Msg = err.Error() - ret.Data = map[string]interface{}{"closeTimeout": 5000} - return - } -} - func refreshFiletree(c *gin.Context) { ret := gulu.Ret.NewResult() defer c.JSON(http.StatusOK, ret) diff --git a/kernel/main.go b/kernel/main.go index 14f92c102..aac8a59c7 100644 --- a/kernel/main.go +++ b/kernel/main.go @@ -51,6 +51,7 @@ func main() { go sql.AutoFlushTreeQueue() go treenode.AutoFlushBlockTree() go cache.LoadAssets() + go model.AutoFixIndex() go model.HookDesktopUIProc() model.WatchAssets() model.HandleSignal() diff --git a/kernel/mobile/kernel.go b/kernel/mobile/kernel.go index 411c6a15a..4d23416be 100644 --- a/kernel/mobile/kernel.go +++ b/kernel/mobile/kernel.go @@ -65,6 +65,7 @@ func StartKernel(container, appDir, workspaceBaseDir, timezoneID, localIPs, lang go sql.AutoFlushTreeQueue() go treenode.AutoFlushBlockTree() go cache.LoadAssets() + go model.AutoFixIndex() }() } diff --git a/kernel/model/box.go b/kernel/model/box.go index a3347080d..d9cb56573 100644 --- a/kernel/model/box.go +++ b/kernel/model/box.go @@ -523,30 +523,6 @@ func genTreeID(tree *parse.Tree) { return } -func ReindexTree(path string) (err error) { - if !strings.HasPrefix(path, "/data/") { - return errors.New("path must start with /data/") - } - - part := strings.TrimPrefix(path, "/data/") - idx := strings.Index(part, "/") - if 0 > idx { - return errors.New("parse box failed") - } - box := part[:idx] - - p := strings.TrimPrefix(path, "/data/"+box) - tree, err := LoadTree(box, p) - if nil != err { - return - } - - treenode.ReindexBlockTree(tree) - sql.UpsertTreeQueue(tree) - sql.WaitForWritingDatabase() - return -} - func FullReindex() { util.PushEndlessProgress(Conf.Language(35)) WaitForWritingFiles() diff --git a/kernel/model/transaction.go b/kernel/model/transaction.go index b2104ad1e..4ab011b0f 100644 --- a/kernel/model/transaction.go +++ b/kernel/model/transaction.go @@ -1217,3 +1217,57 @@ func updateRefText(refNode *ast.Node, changedDefNodes map[string]*ast.Node) (cha }) return } + +func AutoFixIndex() { + for { + autoFixIndex() + time.Sleep(30 * time.Second) + } +} + +func autoFixIndex() { + rootUpdated := treenode.GetRootUpdated() + for rootID, updated := range rootUpdated { + root := sql.GetBlock(rootID) + if nil == root { + reindexTree(rootID) + continue + } + + if "" == updated { + reindexTree(rootID) + continue + } + + btUpdated, _ := time.Parse("20060102150405", updated) + dbUpdated, _ := time.Parse("20060102150405", root.Updated) + if dbUpdated.Before(btUpdated.Add(-1 * time.Minute)) { + reindexTree(rootID) + continue + } + + roots := sql.GetBlockRedundant(rootID) + if 1 < len(roots) { + reindexTree(rootID) + continue + } + } + +} + +func reindexTree(rootID string) { + root := treenode.GetBlockTree(rootID) + if nil == root { + logging.LogWarnf("root block not found", rootID) + return + } + + tree, err := LoadTree(root.BoxID, root.Path) + if nil != err { + return + } + + treenode.ReindexBlockTree(tree) + sql.UpsertTreeQueue(tree) + logging.LogInfof("reindex tree [%s]", tree.ID) +} diff --git a/kernel/sql/block_query.go b/kernel/sql/block_query.go index 3dba9bcda..50c811e5f 100644 --- a/kernel/sql/block_query.go +++ b/kernel/sql/block_query.go @@ -581,6 +581,21 @@ func GetBlock(id string) (ret *Block) { return } +func GetBlockRedundant(id string) (ret []*Block) { + rows, err := query("SELECT * FROM blocks WHERE id = ?", id) + if nil != err { + logging.LogErrorf("sql query failed: %s", err) + return + } + defer rows.Close() + for rows.Next() { + if block := scanBlockRows(rows); nil != block { + ret = append(ret, block) + } + } + return +} + func GetAllRootBlocks() (ret []*Block) { stmt := "SELECT * FROM blocks WHERE type = 'd'" rows, err := query(stmt) diff --git a/kernel/treenode/blocktree.go b/kernel/treenode/blocktree.go index de5bc4ef8..6d29430fe 100644 --- a/kernel/treenode/blocktree.go +++ b/kernel/treenode/blocktree.go @@ -42,8 +42,22 @@ type BlockTree struct { RootID string // 根 ID ParentID string // 父 ID BoxID string // 笔记本 ID - Path string // 文档物理路径 - HPath string // 文档逻辑路径 + Path string // 文档数据路径 + HPath string // 文档可读路径 + Updated string // 更新时间 +} + +func GetRootUpdated() (ret map[string]string) { + blockTreesLock.Lock() + defer blockTreesLock.Unlock() + + ret = map[string]string{} + for _, b := range blockTrees { + if b.RootID == b.ID { + ret[b.RootID] = b.Updated + } + } + return } func GetBlockTreeByPath(path string) *BlockTree { @@ -142,7 +156,7 @@ func SetBlockTreePath(tree *parse.Tree) { for _, b := range blockTrees { if b.RootID == tree.ID { - b.BoxID, b.Path, b.HPath = tree.Box, tree.Path, tree.HPath + b.BoxID, b.Path, b.HPath, b.Updated = tree.Box, tree.Path, tree.HPath, tree.Root.IALAttr("updated") } } blockTreesChanged = true @@ -229,7 +243,7 @@ func ReindexBlockTree(tree *parse.Tree) { if "" == n.ID { return ast.WalkContinue } - blockTrees[n.ID] = &BlockTree{ID: n.ID, ParentID: parentID, RootID: tree.ID, BoxID: tree.Box, Path: tree.Path, HPath: tree.HPath} + blockTrees[n.ID] = &BlockTree{ID: n.ID, ParentID: parentID, RootID: tree.ID, BoxID: tree.Box, Path: tree.Path, HPath: tree.HPath, Updated: tree.Root.IALAttr("updated")} return ast.WalkContinue }) blockTreesChanged = true @@ -250,7 +264,7 @@ func IndexBlockTree(tree *parse.Tree) { if "" == n.ID { return ast.WalkContinue } - blockTrees[n.ID] = &BlockTree{ID: n.ID, ParentID: parentID, RootID: tree.ID, BoxID: tree.Box, Path: tree.Path, HPath: tree.HPath} + blockTrees[n.ID] = &BlockTree{ID: n.ID, ParentID: parentID, RootID: tree.ID, BoxID: tree.Box, Path: tree.Path, HPath: tree.HPath, Updated: tree.Root.IALAttr("updated")} return ast.WalkContinue })