github.com/braveheart12/insolar-09-08-19@v0.8.7/ledger/storage/jet/tree.go (about) 1 /* 2 * Copyright 2019 Insolar Technologies 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package jet 18 19 import ( 20 "bytes" 21 "fmt" 22 "strings" 23 24 "github.com/insolar/insolar/core" 25 "github.com/pkg/errors" 26 "github.com/ugorji/go/codec" 27 ) 28 29 type jet struct { 30 Left *jet 31 Right *jet 32 Actual bool 33 } 34 35 // Find returns jet for provided reference. 36 func (j *jet) Find(val []byte, depth uint8) (*jet, uint8) { 37 if j == nil || val == nil { 38 return nil, 0 39 } 40 41 if getBit(val, depth) { 42 if j.Right != nil { 43 return j.Right.Find(val, depth+1) 44 } 45 } else { 46 if j.Left != nil { 47 return j.Left.Find(val, depth+1) 48 } 49 } 50 return j, depth 51 } 52 53 // Update add missing tree branches for provided prefix. 54 func (j *jet) Update(prefix []byte, setActual bool, maxDepth, depth uint8) { 55 if depth == maxDepth { 56 if setActual { 57 j.Actual = true 58 } 59 return 60 } 61 62 if j.Right == nil { 63 j.Right = &jet{} 64 } 65 if j.Left == nil { 66 j.Left = &jet{} 67 } 68 if getBit(prefix, depth) { 69 j.Right.Update(prefix, setActual, maxDepth, depth+1) 70 } else { 71 j.Left.Update(prefix, setActual, maxDepth, depth+1) 72 } 73 } 74 75 // Clone clones tree either keeping actuality state or resetting it to false 76 func (j *jet) Clone(keep bool) *jet { 77 res := &jet{Actual: keep && j.Actual} 78 if j.Left != nil { 79 res.Left = j.Left.Clone(keep) 80 } 81 if j.Right != nil { 82 res.Right = j.Right.Clone(keep) 83 } 84 return res 85 } 86 87 func (j *jet) ExtractLeafIDs(ids *[]core.RecordID, path []byte, depth uint8) { 88 if j == nil { 89 return 90 } 91 if j.Left == nil && j.Right == nil { 92 *ids = append(*ids, *NewID(depth, path)) 93 return 94 } 95 96 if j.Left != nil { 97 j.Left.ExtractLeafIDs(ids, path, depth+1) 98 } 99 if j.Right != nil { 100 rightPath := make([]byte, len(path)) 101 copy(rightPath, path) 102 setBit(rightPath, depth) 103 j.Right.ExtractLeafIDs(ids, rightPath, depth+1) 104 } 105 } 106 107 // Tree stores jet in a binary tree. 108 type Tree struct { 109 Head *jet 110 } 111 112 // String visualizes Jet's tree. 113 func (t Tree) String() string { 114 if t.Head == nil { 115 return "<nil>" 116 } 117 return nodeDeepFmt(0, "", t.Head) 118 } 119 120 func (t *Tree) toArray() []*jet { 121 queue := []*jet{t.Head} 122 queueIndex := 0 123 lastElementIndex := 0 124 125 for queueIndex <= lastElementIndex { 126 currentNode := queue[queueIndex] 127 if currentNode == nil { 128 queueIndex++ 129 continue 130 } 131 nextLeftIndex := (queueIndex * 2) + 1 132 nextRightIndex := (queueIndex * 2) + 2 133 134 if nextRightIndex >= len(queue) { 135 for nextRightIndex >= len(queue) { 136 queue = append(queue, nil) 137 } 138 } 139 140 queue[nextLeftIndex] = queue[queueIndex].Left 141 queue[nextRightIndex] = queue[queueIndex].Right 142 143 if queue[nextLeftIndex] != nil && nextLeftIndex > lastElementIndex { 144 lastElementIndex = nextLeftIndex 145 } 146 147 if queue[nextRightIndex] != nil && nextRightIndex > lastElementIndex { 148 lastElementIndex = nextRightIndex 149 } 150 queueIndex++ 151 } 152 153 return queue[:lastElementIndex+1] 154 } 155 156 // Merge merges two trees to one 157 func (t *Tree) Merge(newTree *Tree) *Tree { 158 maxLengthFunc := func(left int, right int) int { 159 if left > right { 160 return left 161 } 162 163 return right 164 } 165 166 savedTree := t.toArray() 167 inputTree := newTree.toArray() 168 169 maxLength := maxLengthFunc(len(savedTree), len(inputTree)) 170 171 result := make([]*jet, maxLength) 172 173 for index := 0; index < maxLength; index++ { 174 var savedItem *jet 175 var newItem *jet 176 177 if index < len(savedTree) { 178 savedItem = savedTree[index] 179 } 180 if index < len(inputTree) { 181 newItem = inputTree[index] 182 } 183 184 if savedItem == nil { 185 result[index] = newItem 186 continue 187 } 188 if newItem == nil { 189 result[index] = savedItem 190 continue 191 } 192 193 if !savedItem.Actual && newItem.Actual { 194 result[index] = newItem 195 } else { 196 result[index] = savedItem 197 } 198 } 199 200 for index := 0; index < (maxLength/2)+1; index++ { 201 current := result[index] 202 if current != nil { 203 leftIndex := index*2 + 1 204 if leftIndex < len(result) { 205 current.Left = result[index*2+1] 206 } 207 208 rightIndex := index*2 + 2 209 if rightIndex < len(result) { 210 current.Right = result[index*2+2] 211 } 212 } 213 } 214 215 return &Tree{Head: result[0]} 216 } 217 218 func nodeDeepFmt(deep int, binPrefix string, node *jet) string { 219 prefix := strings.Repeat(" ", deep) 220 if deep == 0 { 221 prefix = "root" 222 } 223 s := fmt.Sprintf("%s%v (level=%v actual=%v)\n", prefix, binPrefix, deep, node.Actual) 224 225 if node.Left != nil { 226 s += nodeDeepFmt(deep+1, binPrefix+"0", node.Left) 227 } 228 if node.Right != nil { 229 s += nodeDeepFmt(deep+1, binPrefix+"1", node.Right) 230 } 231 return s 232 } 233 234 // NewTree creates new tree. 235 func NewTree(isActual bool) *Tree { 236 return &Tree{Head: &jet{Actual: isActual}} 237 } 238 239 // Clone clones the tree keeping actuality or setting everything to false 240 func (t *Tree) Clone(keep bool) *Tree { 241 return &Tree{Head: t.Head.Clone(keep)} 242 } 243 244 // Find returns jet for provided reference. If found jet is actual, the second argument will be true. 245 func (t *Tree) Find(id core.RecordID) (*core.RecordID, bool) { 246 if id.Pulse() == core.PulseNumberJet { 247 return &id, true 248 } 249 hash := id.Hash() 250 j, depth := t.Head.Find(hash, 0) 251 return NewID(uint8(depth), ResetBits(hash, depth)), j.Actual 252 } 253 254 // Update add missing tree branches for provided prefix. If 'setActual' is set, all encountered nodes will be marked as 255 // actual. 256 func (t *Tree) Update(id core.RecordID, setActual bool) { 257 maxDepth, prefix := Jet(id) 258 t.Head.Update(prefix, setActual, maxDepth, 0) 259 } 260 261 // Bytes serializes pulse. 262 func (t *Tree) Bytes() []byte { 263 var buf bytes.Buffer 264 enc := codec.NewEncoder(&buf, &codec.CborHandle{}) 265 enc.MustEncode(t) 266 return buf.Bytes() 267 } 268 269 // Split looks for provided jet and creates (and returns) two branches for it. If provided jet is not found, an error 270 // will be returned. 271 func (t *Tree) Split(jetID core.RecordID) (*core.RecordID, *core.RecordID, error) { 272 depth, prefix := Jet(jetID) 273 j, foundDepth := t.Head.Find(prefix, 0) 274 if depth != foundDepth { 275 return nil, nil, errors.New("failed to split: incorrect jet provided") 276 } 277 j.Right = &jet{} 278 j.Left = &jet{} 279 leftPrefix := ResetBits(prefix, depth) 280 rightPrefix := ResetBits(prefix, depth) 281 setBit(rightPrefix, depth) 282 return NewID(depth+1, leftPrefix), NewID(depth+1, rightPrefix), nil 283 } 284 285 func (t *Tree) LeafIDs() []core.RecordID { 286 var ids []core.RecordID 287 t.Head.ExtractLeafIDs(&ids, make([]byte, core.RecordHashSize), 0) 288 return ids 289 } 290 291 func getBit(value []byte, index uint8) bool { 292 if uint(index) >= uint(len(value)*8) { 293 panic(fmt.Sprintf("index overflow: value=%08b, index=%v", value, index)) 294 } 295 byteIndex := uint(index / 8) 296 bitIndex := uint(7 - index%8) 297 mask := byte(1 << bitIndex) 298 return value[byteIndex]&mask != 0 299 } 300 301 func setBit(value []byte, index uint8) { 302 if uint(index) >= uint(len(value)*8) { 303 panic("index overflow") 304 } 305 byteIndex := uint(index / 8) 306 bitIndex := uint(7 - index%8) 307 mask := byte(1 << bitIndex) 308 value[byteIndex] |= mask 309 } 310 311 // ResetBits returns a new byte slice with all bits in 'value' reset, starting from 'start' number of bit. If 'start' 312 // is bigger than len(value), the original slice will be returned. 313 func ResetBits(value []byte, start uint8) []byte { 314 if int(start) >= len(value)*8 { 315 return value 316 } 317 318 startByte := start / 8 319 startBit := start % 8 320 321 result := make([]byte, len(value)) 322 copy(result, value[:startByte]) 323 324 // Reset bits in starting byte. 325 mask := byte(0xFF) 326 mask <<= 8 - byte(startBit) 327 result[startByte] = value[startByte] & mask 328 329 return result 330 }