/** * <p>Returns the {@code SortedSet} of {@link com.net2plan.interfaces.networkDesign.Link Links} this demand is coupled to, or an empty {@code SortedSet} if this demand is not coupled.</p> * @return The {@code SortedSet} of links (a copy , any changes will not affect the coupling) */ public SortedSet<Link> getCoupledLinks () { checkAttachedToNetPlanObject(); return coupledUpperLayerLinks == null? new TreeSet<Link> () : new TreeSet<Link> (coupledUpperLayerLinks.values()); }
/** * <p>Returns the multicast tree of this demand with lowest cost (and its cost), using the cost per link array provided. * If more than one minimum cost tree exists, all of them are returned. If the cost vector provided is {@code null}, * all links are assigned a cost of one.</p> * * @param costs Link weights * @return A {@code Pair} where the first element is a {@code SortedSet} of minimum cost trees, and the second element is the common minimum cost */ public Pair<SortedSet<MulticastTree>,Double> computeMinimumCostMulticastTrees (double [] costs) { checkAttachedToNetPlanObject(); if (costs == null) costs = DoubleUtils.ones(layer.links.size ()); else if (costs.length != layer.links.size()) throw new Net2PlanException ("The array of costs must have the same length as the number of links in the layer"); SortedSet<MulticastTree> minCostTrees = new TreeSet<MulticastTree> (); double minCost = Double.MAX_VALUE; for (MulticastTree t : cache_multicastTrees) { double cost = 0; for (Link link : t.linkSet) cost += costs [link.index]; if (cost < minCost) { minCost = cost; minCostTrees.clear(); minCostTrees.add (t); } else if (cost == minCost) { minCostTrees.add (t); } } return Pair.of(minCostTrees , minCost); }
/** Returns the set of links in this layer that could potentially carry traffic of this multicast demand, * when flowing from the origin node to the given egress node, according to the multicast trees defined. * These are the links that are part of any path from demand ingress, the given egress node * defined, in any multicast tree. If one of these paths contains a failed link, none of these * links of such multicast tree are considered. * @param egressNode the egress node * @return see above */ public SortedSet<Link> getLinksNoDownPropagationPotentiallyCarryingTraffic (Node egressNode) { checkAttachedToNetPlanObject(); if (!this.egressNodes.contains(egressNode)) throw new Net2PlanException ("This is not an egress node of the multicast demand"); SortedSet<Link> res = new TreeSet<> (); for (MulticastTree t : cache_multicastTrees) { List<Link> pathToTarget = t.getSeqLinksToEgressNode(egressNode); if (pathToTarget == null) continue; if (!netPlan.isUp(pathToTarget)) continue; res.addAll(pathToTarget); } return res; }
/** * <p>Removes this multicast demand, and any associated multicast trees. If the demand is coupled, it is first decoupled. </p> */ public void remove() { checkAttachedToNetPlanObject(); netPlan.checkIsModifiable(); if (this.coupledUpperLayerLinks != null) this.decouple (); for (MulticastTree tree : new TreeSet<MulticastTree> (cache_multicastTrees)) tree.remove(); netPlan.cache_id2MulticastDemandMap.remove(id); NetPlan.removeNetworkElementAndShiftIndexes (layer.multicastDemands , index); ingressNode.cache_nodeOutgoingMulticastDemands.remove (this); for (Node egressNode : egressNodes) egressNode.cache_nodeIncomingMulticastDemands.remove (this); for (String tag : tags) netPlan.cache_taggedElements.get(tag).remove(this); final Pair<SortedSet<Demand>,SortedSet<MulticastDemand>> qosInfo = layer.cache_qosTypes2DemandMap.get(qosType); assert qosInfo != null; final boolean removed = qosInfo.getSecond().remove(this); assert removed; if (qosInfo.getFirst().isEmpty() && qosInfo.getSecond().isEmpty()) layer.cache_qosTypes2DemandMap.remove(qosType); final NetPlan npOld = this.netPlan; removeId(); if (ErrorHandling.isDebugEnabled()) npOld.checkCachesConsistency(); }
/** * <p>Decouples this mulicast demand from a set of upper layer {@link com.net2plan.interfaces.networkDesign.Link Links}. If the demand is not coupled, an exception is thrown</p> */ public void decouple() { checkAttachedToNetPlanObject(); netPlan.checkIsModifiable(); if (coupledUpperLayerLinks == null) throw new Net2PlanException ("The multicast demand is not coupled"); Collection<Link> links = coupledUpperLayerLinks.values(); for (Link link : links) link.checkAttachedToNetPlanObject(this.netPlan); for (Link link : links) if (link.coupledLowerLayerMulticastDemand != this) throw new RuntimeException ("Bad"); final NetworkLayer upperLayer = links.iterator().next().layer; final NetworkLayer lowerLayer = layer; upperLayer.cache_coupledLinks.removeAll(links); layer.cache_coupledMulticastDemands.remove(this); for (Link link : links) link.coupledLowerLayerMulticastDemand = null; DemandLinkMapping coupling_thisLayerPair = netPlan.interLayerCoupling.getEdge(lowerLayer, upperLayer); coupling_thisLayerPair.remove(this); if (coupling_thisLayerPair.isEmpty()) netPlan.interLayerCoupling.removeEdge(lowerLayer , upperLayer); coupledUpperLayerLinks = null; if (ErrorHandling.isDebugEnabled()) netPlan.checkCachesConsistency(); }
/** * <p>Sets the offered traffic by a multicast demand. This does not change the carried traffic, which only depends on the associated multicast trees. </p> * @param offeredTraffic Offered traffic */ public void setOfferedTraffic(double offeredTraffic) { offeredTraffic = NetPlan.adjustToTolerance(offeredTraffic); checkAttachedToNetPlanObject(); netPlan.checkIsModifiable(); if (offeredTraffic < 0) throw new Net2PlanException("Offered traffic must be greater or equal than zero"); this.offeredTraffic = offeredTraffic; if (ErrorHandling.isDebugEnabled()) netPlan.checkCachesConsistency(); }
this.checkAttachedToNetPlanObject(); netPlan.checkIsModifiable(); if (links.size () != egressNodes.size ()) throw new Net2PlanException ("Multicast demands can be coupled to a set of links, starting in the demand ingress node, and ending in each of the multicast demand egress nodes");
/** * <p>Creates new links in the given layer, from the demand ingress node to each one of the demand egress nodes, and couples these newly created links to the multicast demand.</p> * @param newLinkLayer The layer where the new links will be created * @return The set of created links, already coupled to the demand */ public SortedSet<Link> coupleToNewLinksCreated (NetworkLayer newLinkLayer) { checkAttachedToNetPlanObject(); netPlan.checkIsModifiable(); newLinkLayer.checkAttachedToNetPlanObject(this.netPlan); if (this.layer.equals (newLinkLayer)) throw new Net2PlanException ("Cannot couple a link and a demand in the same layer"); if (isCoupled()) throw new Net2PlanException ("The multicast demand is already coupled"); SortedSet<Link> newLinks = new TreeSet<Link> (); try { for (Node egressNode : egressNodes) { Link newLink = netPlan.addLink(ingressNode , egressNode , carriedTraffic , netPlan.getNodePairEuclideanDistance(ingressNode , egressNode) , 200000 , null , newLinkLayer); newLinks.add (newLink); } couple (newLinks); } catch (Exception e) { for (Link link : newLinks) link.remove (); throw e; } if (ErrorHandling.isDebugEnabled()) netPlan.checkCachesConsistency(); return newLinks; }