go.ligato.io/vpp-agent/v3@v3.5.0/plugins/kvscheduler/internal/graph/node_read.go (about)

     1  // Copyright (c) 2018 Cisco and/or its affiliates.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at:
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package graph
    16  
    17  import (
    18  	"google.golang.org/protobuf/proto"
    19  )
    20  
    21  // maximum number of flags allowed to have defined
    22  const maxFlags = 8
    23  
    24  // nodeR implements Node.
    25  type nodeR struct {
    26  	graph *graphR
    27  
    28  	key           string
    29  	label         string
    30  	value         proto.Message
    31  	flags         [maxFlags]Flag
    32  	metadata      interface{}
    33  	metadataAdded bool
    34  	metadataMap   string
    35  
    36  	// same length and corresponding order (lexicographically by relation+label)
    37  	targets    Targets
    38  	targetsDef []RelationTargetDef
    39  
    40  	sources Targets
    41  }
    42  
    43  // newNodeR creates a new instance of nodeR.
    44  func newNodeR() *nodeR {
    45  	return &nodeR{}
    46  }
    47  
    48  // GetKey returns the key associated with the node.
    49  func (node *nodeR) GetKey() string {
    50  	return node.key
    51  }
    52  
    53  // GetLabel returns the label associated with this node.
    54  func (node *nodeR) GetLabel() string {
    55  	return node.label
    56  }
    57  
    58  // GetValue returns the value associated with the node.
    59  func (node *nodeR) GetValue() proto.Message {
    60  	return node.value
    61  }
    62  
    63  // GetFlag returns reference to the given flag or nil if the node doesn't have
    64  // this flag associated.
    65  func (node *nodeR) GetFlag(flagIndex int) Flag {
    66  	return node.flags[flagIndex]
    67  }
    68  
    69  // GetMetadata returns the value metadata associated with the node.
    70  func (node *nodeR) GetMetadata() interface{} {
    71  	return node.metadata
    72  }
    73  
    74  // GetTargets returns a set of nodes, indexed by relation labels, that the
    75  // edges of the given relation points to.
    76  func (node *nodeR) GetTargets(relation string) (runtimeTargets RuntimeTargets) {
    77  	for i := node.targets.RelationBegin(relation); i < len(node.targets); i++ {
    78  		if node.targets[i].Relation != relation {
    79  			break
    80  		}
    81  		var nodes []Node
    82  		for _, key := range node.targets[i].MatchingKeys.Iterate() {
    83  			nodes = append(nodes, node.graph.nodes[key])
    84  		}
    85  		runtimeTargets = append(runtimeTargets, RuntimeTarget{
    86  			Label: node.targets[i].Label,
    87  			Nodes: nodes,
    88  		})
    89  	}
    90  	return runtimeTargets
    91  }
    92  
    93  // IterTargets allows to iterate over the set of nodes that the edges of the given
    94  // relation points to.
    95  func (node *nodeR) IterTargets(relation string, callback TargetIterator) {
    96  	for i := node.targets.RelationBegin(relation); i < len(node.targets); i++ {
    97  		if node.targets[i].Relation != relation {
    98  			break
    99  		}
   100  		for _, key := range node.targets[i].MatchingKeys.Iterate() {
   101  			skipLabel, abort := callback(node.graph.nodes[key], node.targets[i].Label)
   102  			if abort {
   103  				return
   104  			}
   105  			if skipLabel {
   106  				// no more targets from this label to iterate through
   107  				// (just the closing nil one)
   108  				break
   109  			}
   110  		}
   111  		// mark the end of the targets for the given label with nil target
   112  		_, abort := callback(nil, node.targets[i].Label)
   113  		if abort {
   114  			return
   115  		}
   116  	}
   117  }
   118  
   119  // GetSources returns edges pointing to this node in the reverse
   120  // orientation.
   121  func (node *nodeR) GetSources(relation string) (runtimeTargets RuntimeTargets) {
   122  	for i := node.sources.RelationBegin(relation); i < len(node.sources); i++ {
   123  		if node.sources[i].Relation != relation {
   124  			break
   125  		}
   126  		var nodes []Node
   127  		for _, key := range node.sources[i].MatchingKeys.Iterate() {
   128  			nodes = append(nodes, node.graph.nodes[key])
   129  		}
   130  		runtimeTargets = append(runtimeTargets, RuntimeTarget{
   131  			Label: node.sources[i].Label,
   132  			Nodes: nodes,
   133  		})
   134  	}
   135  	return runtimeTargets
   136  }
   137  
   138  // copy returns a deep copy of the node.
   139  func (node *nodeR) copy() *nodeR {
   140  	nodeCopy := newNodeR()
   141  	nodeCopy.key = node.key
   142  	nodeCopy.label = node.label
   143  	nodeCopy.value = node.value
   144  	nodeCopy.metadata = node.metadata
   145  	nodeCopy.metadataAdded = node.metadataAdded
   146  	nodeCopy.metadataMap = node.metadataMap
   147  
   148  	// copy flags (arrays are passed by value)
   149  	nodeCopy.flags = node.flags
   150  
   151  	// shallow-copy target definitions (immutable)
   152  	nodeCopy.targetsDef = node.targetsDef
   153  
   154  	// copy targets
   155  	nodeCopy.targets = node.targets.copy()
   156  
   157  	// copy sources
   158  	nodeCopy.sources = node.sources.copy()
   159  	return nodeCopy
   160  }