mirror of
https://github.com/siyuan-note/siyuan.git
synced 2026-02-08 00:04:21 +01:00
⚡ Caching tree data to improve performance and reduce disk read and write operations https://github.com/siyuan-note/siyuan/issues/16961
Signed-off-by: Daniel <845765@qq.com>
This commit is contained in:
parent
8383a4b3fa
commit
89a595f9c6
3 changed files with 67 additions and 2 deletions
54
kernel/cache/tree.go
vendored
Normal file
54
kernel/cache/tree.go
vendored
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
// SiYuan - Refactor your thinking
|
||||
// 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
package cache
|
||||
|
||||
import (
|
||||
"github.com/dgraph-io/ristretto"
|
||||
)
|
||||
|
||||
type treeCacheEntry struct {
|
||||
raw []byte
|
||||
}
|
||||
|
||||
var (
|
||||
treeCache, _ = ristretto.NewCache(&ristretto.Config{
|
||||
NumCounters: 8,
|
||||
MaxCost: 1024 * 1024 * 200,
|
||||
BufferItems: 64,
|
||||
})
|
||||
)
|
||||
|
||||
func GetTreeData(rootID string) (raw []byte, ok bool) {
|
||||
v, _ := treeCache.Get(rootID)
|
||||
if nil == v {
|
||||
return nil, false
|
||||
}
|
||||
e := v.(*treeCacheEntry)
|
||||
return e.raw, true
|
||||
}
|
||||
|
||||
func SetTreeData(rootID string, raw []byte) {
|
||||
if raw == nil {
|
||||
return
|
||||
}
|
||||
entry := &treeCacheEntry{raw: raw}
|
||||
treeCache.Set(rootID, entry, int64(len(raw)))
|
||||
}
|
||||
|
||||
func RemoveTreeData(rootID string) {
|
||||
treeCache.Del(rootID)
|
||||
}
|
||||
|
|
@ -115,14 +115,23 @@ func batchLoadTrees(boxIDs, paths []string, luteEngine *lute.Lute) (ret []*parse
|
|||
}
|
||||
|
||||
func LoadTree(boxID, p string, luteEngine *lute.Lute) (ret *parse.Tree, err error) {
|
||||
rootID := util.GetTreeID(p)
|
||||
if raw, ok := cache.GetTreeData(rootID); ok {
|
||||
ret, err = LoadTreeByData(raw, boxID, p, luteEngine)
|
||||
return
|
||||
}
|
||||
|
||||
filePath := filepath.Join(util.DataDir, boxID, p)
|
||||
data, err := filelock.ReadFile(filePath)
|
||||
if err != nil {
|
||||
if nil != err {
|
||||
logging.LogErrorf("load tree [%s] failed: %s", p, err)
|
||||
return
|
||||
}
|
||||
|
||||
ret, err = LoadTreeByData(data, boxID, p, luteEngine)
|
||||
if nil != err {
|
||||
cache.SetTreeData(rootID, data)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -146,7 +155,7 @@ func LoadTreeByData(data []byte, boxID, p string, luteEngine *lute.Lute) (ret *p
|
|||
// 构造 HPath
|
||||
hPathBuilder := bytes.Buffer{}
|
||||
hPathBuilder.WriteString("/")
|
||||
for i, _ := range parts {
|
||||
for i := range parts {
|
||||
var parentAbsPath string
|
||||
if 0 < i {
|
||||
parentAbsPath = strings.Join(parts[:i+1], "/")
|
||||
|
|
@ -232,6 +241,7 @@ func WriteTree(tree *parse.Tree) (size uint64, err error) {
|
|||
util.PushErrMsg(msg, 7000)
|
||||
}
|
||||
|
||||
cache.SetTreeData(tree.ID, data)
|
||||
afterWriteTree(tree)
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1647,6 +1647,7 @@ func removeDoc0(tree *parse.Tree, childrenDir string) {
|
|||
treenode.RemoveBlockTreesByPathPrefix(childrenDir)
|
||||
sql.RemoveTreePathQueue(tree.Box, childrenDir)
|
||||
cache.RemoveDocIAL(tree.Path)
|
||||
cache.RemoveTreeData(tree.ID)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue