github.com/turingchain2020/turingchain@v1.1.21/system/store/mavl/db/memmavl.go (about) 1 // Copyright Turing Corp. 2018 All Rights Reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package mavl 6 7 import ( 8 "fmt" 9 "sync" 10 "time" 11 12 "github.com/turingchain2020/turingchain/common" 13 dbm "github.com/turingchain2020/turingchain/common/db" 14 farm "github.com/dgryski/go-farm" 15 lru "github.com/hashicorp/golang-lru" 16 ) 17 18 // MemTreeOpera memtree操作接口 19 type MemTreeOpera interface { 20 Add(key, value interface{}) 21 Get(key interface{}) (value interface{}, ok bool) 22 Delete(key interface{}) 23 Contains(key interface{}) bool 24 Len() int 25 } 26 27 // TreeMap map形式memtree 28 type TreeMap struct { 29 mpCache map[interface{}]interface{} 30 lock sync.RWMutex 31 } 32 33 // NewTreeMap new mem tree 34 func NewTreeMap(size int) *TreeMap { 35 mp := &TreeMap{} 36 mp.mpCache = make(map[interface{}]interface{}, size) 37 return mp 38 } 39 40 // Add 添加元素 41 func (tm *TreeMap) Add(key, value interface{}) { 42 tm.lock.Lock() 43 defer tm.lock.Unlock() 44 if _, ok := tm.mpCache[key]; ok { 45 delete(tm.mpCache, key) 46 return 47 } 48 tm.mpCache[key] = value 49 } 50 51 // Get 获取元素 52 func (tm *TreeMap) Get(key interface{}) (value interface{}, ok bool) { 53 tm.lock.Lock() 54 defer tm.lock.Unlock() 55 if value, ok := tm.mpCache[key]; ok { 56 return value, ok 57 } 58 return nil, false 59 } 60 61 // Delete 删除元素 62 func (tm *TreeMap) Delete(key interface{}) { 63 tm.lock.Lock() 64 defer tm.lock.Unlock() 65 if _, ok := tm.mpCache[key]; ok { 66 delete(tm.mpCache, key) 67 } 68 } 69 70 // Contains 查看是否包含元素 71 func (tm *TreeMap) Contains(key interface{}) bool { 72 tm.lock.Lock() 73 defer tm.lock.Unlock() 74 if _, ok := tm.mpCache[key]; ok { 75 return true 76 } 77 return false 78 } 79 80 // Len 元素长度 81 func (tm *TreeMap) Len() int { 82 tm.lock.Lock() 83 defer tm.lock.Unlock() 84 return len(tm.mpCache) 85 } 86 87 // TreeARC lru的mem tree 88 type TreeARC struct { 89 arcCache *lru.ARCCache 90 } 91 92 // NewTreeARC new lru mem tree 93 func NewTreeARC(size int) *TreeARC { 94 ma := &TreeARC{} 95 var err error 96 ma.arcCache, err = lru.NewARC(size) 97 if err != nil { 98 panic("New tree lru fail") 99 } 100 return ma 101 } 102 103 // Add 添加元素 104 func (ta *TreeARC) Add(key, value interface{}) { 105 if ta.arcCache.Contains(key) { 106 ta.arcCache.Remove(key) 107 return 108 } 109 ta.arcCache.Add(key, value) 110 } 111 112 // Get 获取元素 113 func (ta *TreeARC) Get(key interface{}) (value interface{}, ok bool) { 114 return ta.arcCache.Get(key) 115 } 116 117 // Delete 删除元素 118 func (ta *TreeARC) Delete(key interface{}) { 119 ta.arcCache.Remove(key) 120 } 121 122 // Contains 查看是否包含元素 123 func (ta *TreeARC) Contains(key interface{}) bool { 124 return ta.arcCache.Contains(key) 125 } 126 127 // Len 元素长度 128 func (ta *TreeARC) Len() int { 129 return ta.arcCache.Len() 130 } 131 132 // LoadTree2MemDb 从数据库中载入mem tree 133 func LoadTree2MemDb(db dbm.DB, hash []byte, mp map[uint64]struct{}) { 134 nDb := newNodeDB(db, true) 135 node, err := nDb.getLightNode(nil, hash) 136 if err != nil { 137 fmt.Println("err", err) 138 return 139 } 140 pri := "" 141 if len(node.hash) > 32 { 142 pri = string(node.hash[:16]) 143 } 144 treelog.Info("hash node", "hash pri", pri, "hash", common.ToHex(node.hash), "height", node.height) 145 start := time.Now() 146 leftHash := make([]byte, len(node.leftHash)) 147 copy(leftHash, node.leftHash) 148 rightHash := make([]byte, len(node.rightHash)) 149 copy(rightHash, node.rightHash) 150 mp[farm.Hash64(node.hash)] = struct{}{} 151 node.loadNodeInfo(nDb, mp) 152 end := time.Now() 153 treelog.Info("hash node", "cost time", end.Sub(start), "node count", len(mp)) 154 PrintMemStats(1) 155 } 156 157 func (node *Node) loadNodeInfo(db *nodeDB, mp map[uint64]struct{}) { 158 if node.height == 0 { 159 //trMem.Add(Hash64(node.hash), &hashNode{leftHash: node.leftHash, rightHash: node.rightHash}) 160 leftHash := make([]byte, len(node.leftHash)) 161 copy(leftHash, node.leftHash) 162 rightHash := make([]byte, len(node.rightHash)) 163 copy(rightHash, node.rightHash) 164 mp[farm.Hash64(node.hash)] = struct{}{} 165 return 166 } 167 if node.leftHash != nil { 168 left, err := db.getLightNode(nil, node.leftHash) 169 if err != nil { 170 return 171 } 172 //trMem.Add(Hash64(left.hash), &hashNode{leftHash: left.leftHash, rightHash: left.rightHash}) 173 leftHash := make([]byte, len(left.leftHash)) 174 copy(leftHash, left.leftHash) 175 rightHash := make([]byte, len(left.rightHash)) 176 copy(rightHash, left.rightHash) 177 mp[farm.Hash64(left.hash)] = struct{}{} 178 left.loadNodeInfo(db, mp) 179 } 180 if node.rightHash != nil { 181 right, err := db.getLightNode(nil, node.rightHash) 182 if err != nil { 183 return 184 } 185 //trMem.Add(Hash64(right.hash), &hashNode{leftHash: right.leftHash, rightHash: right.rightHash}) 186 leftHash := make([]byte, len(right.leftHash)) 187 copy(leftHash, right.leftHash) 188 rightHash := make([]byte, len(right.rightHash)) 189 copy(rightHash, right.rightHash) 190 mp[farm.Hash64(right.hash)] = struct{}{} 191 right.loadNodeInfo(db, mp) 192 } 193 } 194 195 func (ndb *nodeDB) getLightNode(t *Tree, hash []byte) (*Node, error) { 196 // Doesn't exist, load from db. 197 var buf []byte 198 buf, err := ndb.db.Get(hash) 199 200 if len(buf) == 0 || err != nil { 201 return nil, ErrNodeNotExist 202 } 203 node, err := MakeNode(buf, t) 204 if err != nil { 205 panic(fmt.Sprintf("Error reading IAVLNode. bytes: %X error: %v", buf, err)) 206 } 207 node.hash = hash 208 node.key = nil 209 node.value = nil 210 return node, nil 211 } 212 213 func copyBytes(b []byte) (copiedBytes []byte) { 214 if b == nil { 215 return nil 216 } 217 copiedBytes = make([]byte, len(b)) 218 copy(copiedBytes, b) 219 return copiedBytes 220 }