A privacy-first, self-hosted, fully open source personal knowledge management software, written in typescript and golang. (PERSONAL FORK)
at lambda-fork/main 119 lines 2.8 kB view raw
1// SiYuan - Refactor your thinking 2// Copyright (c) 2020-present, b3log.org 3// 4// This program is free software: you can redistribute it and/or modify 5// it under the terms of the GNU Affero General Public License as published by 6// the Free Software Foundation, either version 3 of the License, or 7// (at your option) any later version. 8// 9// This program is distributed in the hope that it will be useful, 10// but WITHOUT ANY WARRANTY; without even the implied warranty of 11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12// GNU Affero General Public License for more details. 13// 14// You should have received a copy of the GNU Affero General Public License 15// along with this program. If not, see <https://www.gnu.org/licenses/>. 16 17package sql 18 19import ( 20 "strings" 21 "time" 22 23 "github.com/88250/lute/ast" 24 "github.com/88250/lute/parse" 25 "github.com/dgraph-io/ristretto" 26 "github.com/jinzhu/copier" 27 gcache "github.com/patrickmn/go-cache" 28 "github.com/siyuan-note/logging" 29 "github.com/siyuan-note/siyuan/kernel/search" 30) 31 32var cacheDisabled = true 33 34func enableCache() { 35 cacheDisabled = false 36} 37 38func disableCache() { 39 cacheDisabled = true 40} 41 42var blockCache, _ = ristretto.NewCache(&ristretto.Config{ 43 NumCounters: 102400, 44 MaxCost: 10240, 45 BufferItems: 64, 46}) 47 48func ClearCache() { 49 blockCache.Clear() 50} 51 52func putBlockCache(block *Block) { 53 if cacheDisabled { 54 return 55 } 56 57 cloned := &Block{} 58 if err := copier.Copy(cloned, block); err != nil { 59 logging.LogErrorf("clone block failed: %v", err) 60 return 61 } 62 cloned.Content = strings.ReplaceAll(cloned.Content, search.SearchMarkLeft, "") 63 cloned.Content = strings.ReplaceAll(cloned.Content, search.SearchMarkRight, "") 64 blockCache.Set(cloned.ID, cloned, 1) 65} 66 67func getBlockCache(id string) (ret *Block) { 68 if cacheDisabled { 69 return 70 } 71 72 b, _ := blockCache.Get(id) 73 if nil != b { 74 ret = b.(*Block) 75 } 76 return 77} 78 79func removeBlockCache(id string) { 80 blockCache.Del(id) 81 removeRefCacheByDefID(id) 82} 83 84var defIDRefsCache = gcache.New(30*time.Minute, 5*time.Minute) // [defBlockID]map[refBlockID]*Ref 85 86func GetRefsCacheByDefID(defID string) (ret []*Ref) { 87 for defBlockID, refs := range defIDRefsCache.Items() { 88 if defBlockID == defID { 89 for _, ref := range refs.Object.(map[string]*Ref) { 90 ret = append(ret, ref) 91 } 92 } 93 } 94 if 1 > len(ret) { 95 ret = QueryRefsByDefID(defID, false) 96 for _, ref := range ret { 97 putRefCache(ref) 98 } 99 } 100 return 101} 102 103func CacheRef(tree *parse.Tree, refNode *ast.Node) { 104 ref := buildRef(tree, refNode) 105 putRefCache(ref) 106} 107 108func putRefCache(ref *Ref) { 109 defBlockRefs, ok := defIDRefsCache.Get(ref.DefBlockID) 110 if !ok { 111 defBlockRefs = map[string]*Ref{} 112 } 113 defBlockRefs.(map[string]*Ref)[ref.BlockID] = ref 114 defIDRefsCache.SetDefault(ref.DefBlockID, defBlockRefs) 115} 116 117func removeRefCacheByDefID(defID string) { 118 defIDRefsCache.Delete(defID) 119}