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  }