diff --git a/kernel/model/index_fix.go b/kernel/model/index_fix.go index 4547aa4a4..4aa2ac08b 100644 --- a/kernel/model/index_fix.go +++ b/kernel/model/index_fix.go @@ -106,12 +106,10 @@ func autoFixIndex() { size := len(paths) - // 清理块树中重复冗余的数据 - redundantPaths := treenode.GetRedundantPaths(box.ID, paths) - for _, p := range redundantPaths { - treenode.RemoveBlockTreesByPath(box.ID, p) - } + // 清理块树中的冗余数据 + treenode.ClearRedundantBlockTrees(box.ID, paths) + // 重新索引缺失的块树 missingPaths := treenode.GetNotExistPaths(box.ID, paths) for i, p := range missingPaths { id := path.Base(p) diff --git a/kernel/sql/queue.go b/kernel/sql/queue.go index 6026007d4..b535bb3bd 100644 --- a/kernel/sql/queue.go +++ b/kernel/sql/queue.go @@ -181,6 +181,10 @@ func execOp(op *dbQueueOperation, tx *sql.Tx, context map[string]interface{}) (e } func BatchRemoveAssetsQueue(hashes []string) { + if 1 > len(hashes) { + return + } + dbQueueLock.Lock() defer dbQueueLock.Unlock() @@ -319,6 +323,10 @@ func RemoveTreeQueue(box, rootID string) { } func BatchRemoveTreeQueue(rootIDs []string) { + if 1 > len(rootIDs) { + return + } + dbQueueLock.Lock() defer dbQueueLock.Unlock() diff --git a/kernel/treenode/blocktree.go b/kernel/treenode/blocktree.go index 566c6de35..8aa62649e 100644 --- a/kernel/treenode/blocktree.go +++ b/kernel/treenode/blocktree.go @@ -55,22 +55,6 @@ type BlockTree struct { Type string // 类型 } -func GetRootUpdated() (ret map[string]string) { - ret = map[string]string{} - blockTrees.Range(func(key, value interface{}) bool { - slice := value.(*btSlice) - slice.m.Lock() - for _, b := range slice.data { - if b.RootID == b.ID { - ret[b.RootID] = b.Updated - } - } - slice.m.Unlock() - return true - }) - return -} - func GetBlockTreeByPath(path string) (ret *BlockTree) { blockTrees.Range(func(key, value interface{}) bool { slice := value.(*btSlice) @@ -113,62 +97,6 @@ func CountBlocks() (ret int) { return } -func GetRedundantPaths(boxID string, paths []string) (ret []string) { - pathsMap := map[string]bool{} - for _, path := range paths { - pathsMap[path] = true - } - - btPathsMap := map[string]bool{} - blockTrees.Range(func(key, value interface{}) bool { - slice := value.(*btSlice) - slice.m.Lock() - for _, b := range slice.data { - if b.BoxID == boxID { - btPathsMap[b.Path] = true - } - } - slice.m.Unlock() - return true - }) - - for p, _ := range btPathsMap { - if !pathsMap[p] { - ret = append(ret, p) - } - } - ret = gulu.Str.RemoveDuplicatedElem(ret) - return -} - -func GetNotExistPaths(boxID string, paths []string) (ret []string) { - pathsMap := map[string]bool{} - for _, path := range paths { - pathsMap[path] = true - } - - btPathsMap := map[string]bool{} - blockTrees.Range(func(key, value interface{}) bool { - slice := value.(*btSlice) - slice.m.Lock() - for _, b := range slice.data { - if b.BoxID == boxID { - btPathsMap[b.Path] = true - } - } - slice.m.Unlock() - return true - }) - - for p, _ := range pathsMap { - if !btPathsMap[p] { - ret = append(ret, p) - } - } - ret = gulu.Str.RemoveDuplicatedElem(ret) - return -} - func GetBlockTreeRootByPath(boxID, path string) (ret *BlockTree) { blockTrees.Range(func(key, value interface{}) bool { slice := value.(*btSlice) @@ -269,21 +197,6 @@ func RemoveBlockTreesByRootID(rootID string) { } } -func RemoveBlockTreesByPath(boxID, path string) { - blockTrees.Range(func(key, value interface{}) bool { - slice := value.(*btSlice) - slice.m.Lock() - for _, b := range slice.data { - if b.Path == path && b.BoxID == boxID { - delete(slice.data, b.ID) - slice.changed = time.Now() - } - } - slice.m.Unlock() - return true - }) -} - func RemoveBlockTreesByPathPrefix(pathPrefix string) { var ids []string blockTrees.Range(func(key, value interface{}) bool { diff --git a/kernel/treenode/blocktree_fix.go b/kernel/treenode/blocktree_fix.go new file mode 100644 index 000000000..fd0fdebdf --- /dev/null +++ b/kernel/treenode/blocktree_fix.go @@ -0,0 +1,116 @@ +// SiYuan - Build Your Eternal Digital Garden +// Copyright (c) 2020-present, b3log.org +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package treenode + +import ( + "github.com/88250/gulu" + "time" +) + +func ClearRedundantBlockTrees(boxID string, paths []string) { + redundantPaths := getRedundantPaths(boxID, paths) + for _, p := range redundantPaths { + removeBlockTreesByPath(boxID, p) + } +} + +func getRedundantPaths(boxID string, paths []string) (ret []string) { + pathsMap := map[string]bool{} + for _, path := range paths { + pathsMap[path] = true + } + + btPathsMap := map[string]bool{} + blockTrees.Range(func(key, value interface{}) bool { + slice := value.(*btSlice) + slice.m.Lock() + for _, b := range slice.data { + if b.BoxID == boxID { + btPathsMap[b.Path] = true + } + } + slice.m.Unlock() + return true + }) + + for p, _ := range btPathsMap { + if !pathsMap[p] { + ret = append(ret, p) + } + } + ret = gulu.Str.RemoveDuplicatedElem(ret) + return +} + +func removeBlockTreesByPath(boxID, path string) { + blockTrees.Range(func(key, value interface{}) bool { + slice := value.(*btSlice) + slice.m.Lock() + for _, b := range slice.data { + if b.Path == path && b.BoxID == boxID { + delete(slice.data, b.ID) + slice.changed = time.Now() + } + } + slice.m.Unlock() + return true + }) +} + +func GetNotExistPaths(boxID string, paths []string) (ret []string) { + pathsMap := map[string]bool{} + for _, path := range paths { + pathsMap[path] = true + } + + btPathsMap := map[string]bool{} + blockTrees.Range(func(key, value interface{}) bool { + slice := value.(*btSlice) + slice.m.Lock() + for _, b := range slice.data { + if b.BoxID == boxID { + btPathsMap[b.Path] = true + } + } + slice.m.Unlock() + return true + }) + + for p, _ := range pathsMap { + if !btPathsMap[p] { + ret = append(ret, p) + } + } + ret = gulu.Str.RemoveDuplicatedElem(ret) + return +} + +func GetRootUpdated() (ret map[string]string) { + ret = map[string]string{} + blockTrees.Range(func(key, value interface{}) bool { + slice := value.(*btSlice) + slice.m.Lock() + for _, b := range slice.data { + if b.RootID == b.ID { + ret[b.RootID] = b.Updated + } + } + slice.m.Unlock() + return true + }) + return +}