diff --git a/kernel/model/box.go b/kernel/model/box.go index b6824168f..1a069cb00 100644 --- a/kernel/model/box.go +++ b/kernel/model/box.go @@ -480,6 +480,7 @@ func RefreshFileTree() { util.PushErrMsg(fmt.Sprintf(Conf.Language(85), err), 5000) return } + treenode.InitBlockTree(true) util.PushEndlessProgress(Conf.Language(35)) openedBoxes := Conf.GetOpenedBoxes() diff --git a/kernel/model/conf.go b/kernel/model/conf.go index 809eee939..31e15186e 100644 --- a/kernel/model/conf.go +++ b/kernel/model/conf.go @@ -502,7 +502,7 @@ func InitBoxes() { } }() - treenode.InitBlockTree() + treenode.InitBlockTree(false) initialized = true } } else { // 大于 1 的话说明在同步阶段已经加载过了 diff --git a/kernel/model/repository.go b/kernel/model/repository.go index eed53fea9..c1227210b 100644 --- a/kernel/model/repository.go +++ b/kernel/model/repository.go @@ -497,7 +497,7 @@ func syncRepo(boot, exit, byHand bool) (err error) { } start := time.Now() - indexBeforeSync, err := indexRepoBeforeCloudSync(repo) + err = indexRepoBeforeCloudSync(repo) if nil != err { syncDownloadErrCount++ planSyncAfter(fixSyncInterval) @@ -592,21 +592,24 @@ func syncRepo(boot, exit, byHand bool) (err error) { // 有数据变更,需要重建索引 var upserts, removes []string + var upsertTrees int for _, file := range mergeResult.Upserts { upserts = append(upserts, file.Path) + if strings.HasSuffix(file.Path, ".sy") { + upsertTrees++ + } } for _, file := range mergeResult.Removes { removes = append(removes, file.Path) } if boot && gulu.File.IsExist(util.BlockTreePath) { - treenode.InitBlockTree() + treenode.InitBlockTree(false) } cache.ClearDocsIAL() // 同步后文档树文档图标没有更新 https://github.com/siyuan-note/siyuan/issues/4939 - fullReindex := 0.2 < float64(len(upserts))/float64(len(indexBeforeSync.Files)) - if fullReindex { // 如果更新的文件比较多则全量重建索引 + if needFullReindex(upsertTrees) { // 改进同步后全量重建索引判断 https://github.com/siyuan-note/siyuan/issues/5764 RefreshFileTree() return } @@ -626,10 +629,14 @@ func syncRepo(boot, exit, byHand bool) (err error) { return } -func indexRepoBeforeCloudSync(repo *dejavu.Repo) (index *entity.Index, err error) { +func needFullReindex(upsertTrees int) bool { + return 0.2 < float64(upsertTrees)/float64(treenode.CountTrees()) +} + +func indexRepoBeforeCloudSync(repo *dejavu.Repo) (err error) { start := time.Now() latest, _ := repo.Latest() - index, err = repo.Index("[Sync] Cloud sync", map[string]interface{}{ + index, err := repo.Index("[Sync] Cloud sync", map[string]interface{}{ dejavu.CtxPushMsg: dejavu.CtxPushMsgToStatusBar, }) if nil != err { diff --git a/kernel/treenode/blocktree.go b/kernel/treenode/blocktree.go index 3cf551a40..455484c6f 100644 --- a/kernel/treenode/blocktree.go +++ b/kernel/treenode/blocktree.go @@ -47,6 +47,15 @@ type BlockTree struct { HPath string // 文档逻辑路径 } +func CountTrees() (ret int) { + roots := map[string]bool{} + for _, b := range blockTrees { + roots[b.RootID] = true + } + ret = len(roots) + return +} + func GetBlockTrees() map[string]*BlockTree { return blockTrees } @@ -218,11 +227,24 @@ func AutoFlushBlockTree() { } } -func InitBlockTree() { +func InitBlockTree(force bool) { start := time.Now() if nil == blocktreeFileLock { blocktreeFileLock = flock.New(util.BlockTreePath) + } else { + if force { + err := blocktreeFileLock.Unlock() + if nil != err { + logging.LogErrorf("unlock blocktree file failed: %s", err) + } + err = os.RemoveAll(util.BlockTreePath) + if nil != err { + logging.LogErrorf("remove blocktree file failed: %s", err) + } + blocktreeFileLock = flock.New(util.BlockTreePath) + return + } } var err error @@ -247,6 +269,7 @@ func InitBlockTree() { blockTreesLock.Lock() if err = msgpack.Unmarshal(data, &blockTrees); nil != err { logging.LogErrorf("unmarshal block tree failed: %s", err) + blocktreeFileLock.Unlock() if err = os.RemoveAll(util.BlockTreePath); nil != err { logging.LogErrorf("removed corrupted block tree failed: %s", err) }