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 }