github.com/braveheart12/insolar-09-08-19@v0.8.7/ledger/storage/nodes/nodes.go (about) 1 /* 2 * Copyright 2019 Insolar 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 nodes 18 19 import ( 20 "sync" 21 22 "github.com/insolar/insolar" 23 "github.com/insolar/insolar/core" 24 "github.com/insolar/insolar/ledger/storage" 25 ) 26 27 // Accessor provides info about active nodes. 28 //go:generate minimock -i github.com/insolar/insolar/ledger/storage/nodes.Accessor -o ./ -s _mock.go 29 type Accessor interface { 30 All(pulse core.PulseNumber) ([]insolar.Node, error) 31 InRole(pulse core.PulseNumber, role core.StaticRole) ([]insolar.Node, error) 32 } 33 34 // Setter provides methods for setting active nodes. 35 //go:generate minimock -i github.com/insolar/insolar/ledger/storage/nodes.Setter -o ./ -s _mock.go 36 type Setter interface { 37 Set(pulse core.PulseNumber, nodes []insolar.Node) error 38 Delete(pulse core.PulseNumber) 39 } 40 41 // Storage is an in-memory active node storage for each pulse. It's required to calculate node roles 42 // for past pulses to locate data. 43 // It should only contain previous N pulses. It should be stored on disk. 44 type Storage struct { 45 lock sync.RWMutex 46 nodes map[core.PulseNumber][]insolar.Node 47 } 48 49 // NewStorage create new instance of Storage 50 func NewStorage() *Storage { 51 // return new(nodeStorage) 52 return &Storage{nodes: map[core.PulseNumber][]insolar.Node{}} 53 } 54 55 // Set saves active nodes for pulse in memory. 56 func (a *Storage) Set(pulse core.PulseNumber, nodes []insolar.Node) error { 57 a.lock.Lock() 58 defer a.lock.Unlock() 59 60 if _, ok := a.nodes[pulse]; ok { 61 return storage.ErrOverride 62 } 63 64 if len(nodes) != 0 { 65 a.nodes[pulse] = append([]insolar.Node{}, nodes...) 66 } else { 67 a.nodes[pulse] = nil 68 } 69 70 return nil 71 } 72 73 // All return active nodes for specified pulse. 74 func (a *Storage) All(pulse core.PulseNumber) ([]insolar.Node, error) { 75 a.lock.RLock() 76 defer a.lock.RUnlock() 77 78 nodes, ok := a.nodes[pulse] 79 if !ok { 80 return nil, core.ErrNoNodes 81 } 82 res := append(nodes[:0:0], nodes...) 83 84 return res, nil 85 } 86 87 // InRole return active nodes for specified pulse and role. 88 func (a *Storage) InRole(pulse core.PulseNumber, role core.StaticRole) ([]insolar.Node, error) { 89 a.lock.RLock() 90 defer a.lock.RUnlock() 91 92 nodes, ok := a.nodes[pulse] 93 if !ok { 94 return nil, core.ErrNoNodes 95 } 96 var inRole []insolar.Node 97 for _, node := range nodes { 98 if node.Role == role { 99 inRole = append(inRole, node) 100 } 101 } 102 103 return inRole, nil 104 } 105 106 // Delete erases nodes for specified pulse. 107 func (a *Storage) Delete(pulse core.PulseNumber) { 108 a.lock.Lock() 109 delete(a.nodes, pulse) 110 a.lock.Unlock() 111 }