private List<Triple<String,String,String>> getMulticastTreeInfoTables (MulticastTree t) { final DecimalFormat df = new DecimalFormat("###.##"); final NetPlan np = t.getNetPlan(); final List<Triple<String,String,String>> res = new ArrayList <> (); res.add(Triple.of("Tree index/id" , "Tree " + t.getIndex() + " (id " + t.getId() + ")", "multicastTre" + t.getId())); res.add(Triple.of("Layer" , "" + getLayerName(t.getLayer()) , "layer" + t.getLayer().getId())); res.add(Triple.of("Tree demand" , "Multicast demand " + t.getMulticastDemand().getIndex() + " (id " + t.getMulticastDemand().getId() + ")" , "multicastDemand" + t.getMulticastDemand().getId())); res.add(Triple.of("M. Demand offered traffic" , "" + df.format(t.getMulticastDemand().getOfferedTraffic()) + " " + np.getDemandTrafficUnitsName(t.getLayer()) , "")); res.add(Triple.of("M. Demand carried traffic" , "" + df.format(t.getMulticastDemand().getCarriedTraffic()) + " " + np.getDemandTrafficUnitsName(t.getLayer()) , "")); res.add(Triple.of("Tree carried traffic" , "" + df.format(t.getCarriedTraffic()) + " " + np.getDemandTrafficUnitsName(t.getLayer()), "")); res.add(Triple.of("Is up?" , "" + !t.isDown(), "")); res.add(Triple.of("Worst link utilization" , "" + df.format(t.getLinkSet().stream().mapToDouble(e->e.getUtilization()).max().orElse(0)), "")); res.add(Triple.of("E2E num. hops (av / max)" , "" + df.format(t.getTreeAveragePathLengthInHops()) + " / " + df.format(t.getTreeMaximumPathLengthInHops()) , "")); res.add(Triple.of("E2E length in km (av / max)" , "" + df.format(t.getTreeAveragePathLengthInHops()) + " / " + df.format(t.getTreeMaximumPathLengthInKm()) + " km", "")); res.add(Triple.of("E2E length in ms (av / max)" , "" + df.format(t.getTreeAveragePropagationDelayInMs()) + " / " + df.format(t.getTreeMaximumPropagationDelayInMs()) + " ms", "")); return res; } private List<Triple<String,String,String>> getDemandInfoTables (Demand d)
@Override public List<AjtColumnInfo<MulticastTree>> getNonBasicUserDefinedColumnsVisibleOrNot() { final List<AjtColumnInfo<MulticastTree>> res = new LinkedList<> (); res.add(new AjtColumnInfo<MulticastTree>(this , Node.class, null , "A", "Ingress node", null , d->d.getIngressNode() , AGTYPE.NOAGGREGATION , null)); res.add(new AjtColumnInfo<MulticastTree>(this , String.class, null , "Bs", "Egress nodes", null , d->d.getMulticastDemand().getEgressNodes().stream().map(n->n.getName().equals("")? "Node " + n.getIndex() : n.getName()).collect(Collectors.joining(",")) , AGTYPE.NOAGGREGATION , null)); res.add(new AjtColumnInfo<MulticastTree>(this , String.class, null , "Bs (reached)", "Reached egress nodes", null , d->d.getEgressNodesReached().stream().map(n->n.getName().equals("")? "Node " + n.getIndex() : n.getName()).collect(Collectors.joining(",")) , AGTYPE.NOAGGREGATION , null)); res.add(new AjtColumnInfo<MulticastTree>(this , Integer.class, null , "# Bs not reached", "Number of non-reached egress nodes", null , d->d.getMulticastDemand().getEgressNodes().size() - d.getEgressNodesReached().size() , AGTYPE.SUMINT , d-> d.getMulticastDemand().getEgressNodes().size() - d.getEgressNodesReached().size() > 0? Color.RED : null)); res.add(new AjtColumnInfo<MulticastTree>(this , MulticastDemand.class, null , "Demand", "Associated multicast demand", null , d->d.getMulticastDemand() , AGTYPE.NOAGGREGATION , null)); res.add(new AjtColumnInfo<MulticastTree>(this , Double.class, null , "Carried traffic (" + getTableNetworkLayer().getDemandTrafficUnits() + ")", "Carried traffic by the multicast tree", null , d->d.getCarriedTraffic() , AGTYPE.SUMDOUBLE , null)); res.add(new AjtColumnInfo<MulticastTree>(this , Double.class, null , "Occupied capacity (" + getTableNetworkLayer().getLinkCapacityUnits() + ")", "Occupied capacity in the traversed links", null, d->d.getOccupiedLinkCapacity() , AGTYPE.NOAGGREGATION , null)); res.add(new AjtColumnInfo<MulticastTree>(this , Collection.class, null , "Traversed links", "Traversed links in the non-failure state", null, d->d.getLinkSet() , AGTYPE.NOAGGREGATION , null)); res.add(new AjtColumnInfo<MulticastTree>(this , Double.class, null , "Total tree length (km)", "Sum of the lengths of all the tree links (accumulating any lower layer propagation lengths if any)", null, d->d.getTreeTotalLengthInKm() , AGTYPE.NOAGGREGATION , null)); res.add(new AjtColumnInfo<MulticastTree>(this , Double.class, null , "Worst e2e lat (ms)", "Current worst case end-to-end propagation time in miliseconds (accumulating any lower layer propagation times if any), from the origin node, to destination nodes reached", null, d->d.getTreeMaximumPropagationDelayInMs() , AGTYPE.NOAGGREGATION , d->{ final double m = d.getMulticastDemand().getMaximumAcceptableE2EWorstCaseLatencyInMs(); if (m >= 0) return null; return d.getTreeMaximumPropagationDelayInMs () > m? Color.RED : null; })); res.add(new AjtColumnInfo<MulticastTree>(this , Double.class, null , "Worst e2e length (km)", "Current worst case end-to-end propagation length in km (accumulating any lower layer propagation lengths if any)", null, d->d.getTreeMaximumPathLengthInKm() , AGTYPE.NOAGGREGATION , null)); res.add(new AjtColumnInfo<MulticastTree>(this , Double.class, null , "Worst e2e length (hops)", "Current worst case end-to-end propagation length in number of traversed links", null, d->d.getTreeMaximumPathLengthInHops() , AGTYPE.NOAGGREGATION , null)); return res; }
/** * <p>Returns the sum of the {@link com.net2plan.interfaces.networkDesign.Link Links} length in kms of the tree.</p> * @return The tree total length in km */ public double getTreeTotalLengthInKm () { checkAttachedToNetPlanObject(); double accum = 0; for (Link e : getLinkSet()) accum += e.getLengthInKm(); return accum; }
/** Returns true if the multicast tree is reaching all the egress nodes of the demand * @return see above */ public boolean isReachinAllDemandEgressNodes () { return getEgressNodesReached().equals(getMulticastDemand().getEgressNodes()); }
/** Returns a map with an entry for each traversed link, and associated to it the demand's traffic carried in that link. * If selected by the user, the carried traffic is given as a fraction respect to the demand offered traffic * @param normalizedToOfferedTraffic see above * @return see above */ public SortedMap<Link, Double> getTraversedLinksAndCarriedTraffic(final boolean normalizedToOfferedTraffic) { final SortedMap<Link, Double> res = new TreeMap<>(); final double normalizationFactor = (normalizedToOfferedTraffic ? (offeredTraffic <= Configuration.precisionFactor ? 1.0 : 1 / offeredTraffic) : 1.0); for (MulticastTree r : getMulticastTrees()) for (Link e : r.getLinkSet()) { final Double currentVal = res.get(e); final double newValue = (currentVal == null ? 0 : currentVal) + (r.getCarriedTraffic() * normalizationFactor); res.put(e, newValue); } return res; }
final int regularInterlineSpacePixels = fontMetrics.getHeight(); final int maxNumberOfTagsPerNode = 4; final int maxNumberOfHops = tree.getTreeMaximumPathLengthInHops(); final int initialTopYOfFirstLineOfNodes = initialYTitle + (generalMessage.size() * fontHeightTitle) + 20; final int spaceBetweenVerticalNodes = maxHeightOrSizeIcon + regularInterlineSpacePixels * maxNumberOfTagsPerNode + 20; this.drawnLines = new ArrayList<>(); final Point dnOriginTopLeftPosition = new Point(initialXTitle, initialTopYOfFirstLineOfNodes); final DrawNode ingressDn = new DrawNode(tree.getIngressNode(), tree.getLayer(), maxHeightOrSizeIcon); this.drawnNodes.add(ingressDn); DrawNode.addNodeToGraphics(g2d, ingressDn, dnOriginTopLeftPosition, fontMetrics, regularInterlineSpacePixels, Color.GREEN); nodesToDnMap.put(tree.getIngressNode(), ingressDn); for (int numHops = 1; numHops <= maxNumberOfHops; numHops++) for (Node egressNode : tree.getEgressNodesReached()) final List<Link> seqLinks = tree.getSeqLinksToEgressNode(egressNode); if (numHops - 1 < seqLinks.size()) linksThisHopIndex.add(seqLinks.get(numHops - 1)); final DrawNode dn = new DrawNode(tree.getIngressNode(), tree.getLayer(), maxHeightOrSizeIcon); this.drawnNodes.add(dn); DrawNode.addNodeToGraphics(g2d, dn, dnTopLeftPosition, fontMetrics, regularInterlineSpacePixels, tree.getEgressNodesReached().contains(n) ? Color.CYAN : null); nodesToDnMap.put(n, dn); yPositionTopDn += spaceBetweenVerticalNodes; final DrawLine dlLink = new DrawLine(dnOrigin, dn, e, dnOrigin.posEast(), dn.posWest(), tree.getOccupiedLinkCapacity()); DrawLine.addLineToGraphics(g2d, dlLink, fontMetrics, regularInterlineSpacePixels); drawnLines.add(dlLink);
for (MulticastTree other : otherDemand.getMulticastTrees()) final Set<Link> initialLinkSet = other.getInitialLinkSet().stream(). map(x->(Link) thatToThisTranslation.get(x)).collect(Collectors.toSet()); final Set<Link> currentLinkSet = other.getLinkSet().stream(). map(x->(Link)thatToThisTranslation.get(x)). collect(Collectors.toSet()); t.setLinks(new TreeSet<> (currentLinkSet)); t.setCarriedTraffic(other.getCarriedTrafficInNoFailureState(), other.getOccupiedLinkCapacityInNoFailureState()); t.setAttributeMap(other.getAttributes()); // previous attributes are not removed, just new added or existing updated for (String tag : other.getTags()) t.addTag(tag); thatToThisTranslation.put(other , t);
final boolean isTreeLayerVisibleInTheCanvas = vs.isLayerVisibleInCanvas(pickedTree.getLayer()); final GUINode gnOrigin = vs.getCanvasAssociatedGUINode(pickedTree.getIngressNode(), pickedTree.getLayer()); for (Node egressNode : pickedTree.getEgressNodesReached()) final GUINode gnDestination = vs.getCanvasAssociatedGUINode(egressNode, pickedTree.getLayer()); if (vs.isShowInCanvasThisLayerPropagation() && isTreeLayerVisibleInTheCanvas) final List<Link> linksPrimary = pickedTree.getSeqLinksToEgressNode(egressNode); DrawUtils.drawCollateralLinks(vs, linksPrimary, VisualizationConstants.DEFAULT_REGGUILINK_EDGECOLOR_PICKED); final Pair<SortedSet<Demand>, SortedSet<Pair<MulticastDemand, Node>>> downInfo = DrawUtils.getDownCoupling(pickedTree.getSeqLinksToEgressNode(egressNode)); final InterLayerPropagationGraph ipg = new InterLayerPropagationGraph(downInfo.getFirst(), null, downInfo.getSecond(), false); DrawUtils.drawCollateralLinks(vs, ipg.getLinksInGraph(), VisualizationConstants.DEFAULT_REGGUILINK_EDGECOLOR_PICKED); DrawUtils.drawDownPropagationInterLayerLinks(vs, ipg.getLinksInGraph(), VisualizationConstants.DEFAULT_REGGUILINK_EDGECOLOR_PICKED); if (vs.isShowInCanvasUpperLayerPropagation() && (vs.getNetPlan().getNumberOfLayers() > 1) && pickedTree.getMulticastDemand().isCoupled()) final SortedSet<Link> upperCoupledLink = DrawUtils.getUpCoupling(null, Arrays.asList(Pair.of(pickedTree.getMulticastDemand(), egressNode))); final InterLayerPropagationGraph ipg = new InterLayerPropagationGraph(null, upperCoupledLink, null, true); DrawUtils.drawCollateralLinks(vs, ipg.getLinksInGraph(), VisualizationConstants.DEFAULT_REGGUILINK_EDGECOLOR_PICKED);
void updateLinkTrafficAndOccupation () { /* Add the info of the demands with traversing routes */ this.cache_totalCarriedTraffic = 0; this.cache_totalOccupiedCapacity = 0; for (Entry<Route,Integer> travRouteInfo : cache_traversingRoutes.entrySet()) { final Route r = travRouteInfo.getKey(); final double carriedTraffic = r.getCarriedTraffic(); final double occupiedCapacity = r.getOccupiedCapacity(this); this.cache_totalCarriedTraffic += carriedTraffic; this.cache_totalOccupiedCapacity += occupiedCapacity; } /* Add the info of the demands with forwarding rules */ for (Entry<Demand,Pair<Double,Double>> entryInfo : this.cacheHbH_normCarriedOccupiedPerTraversingDemandCurrentState.entrySet()) { final Demand demand = entryInfo.getKey(); final double occupiedCapacityAndCarriedTraffic = entryInfo.getValue().getSecond(); this.cache_totalCarriedTraffic += occupiedCapacityAndCarriedTraffic; this.cache_totalOccupiedCapacity += occupiedCapacityAndCarriedTraffic; } for (MulticastTree t : cache_traversingTrees) { final MulticastDemand demand = t.getMulticastDemand(); final double occupiedCapacity = t.getOccupiedLinkCapacity(); final double carriedTraffic = t.getCarriedTraffic(); this.cache_totalCarriedTraffic += carriedTraffic; this.cache_totalOccupiedCapacity += occupiedCapacity; } }
private TBFToFromCarriedTraffic(MulticastTree tree, boolean onlyThisLayer) { super(tree.getNetPlan()); this.initialElement = tree; this.onlyThisLayer = onlyThisLayer; this.initialFR = null; this.auxLayerInNodes = null; final Set<Link> linksAllLayers = new HashSet<>(); final Set<Demand> demandsAllLayers = new HashSet<>(); final Set<MulticastDemand> mDemandsAllLayers = new HashSet<>(); mDemandsAllLayers.add(tree.getMulticastDemand()); linksAllLayers.addAll(tree.getLinkSet()); if (!onlyThisLayer) updatePropagationDownWards(linksAllLayers, linksAllLayers, demandsAllLayers, mDemandsAllLayers); if (!onlyThisLayer) updatePropagationUpWards(demandsAllLayers, mDemandsAllLayers, linksAllLayers, demandsAllLayers, mDemandsAllLayers); final Set<NetworkLayer> layersToKeepAllElements = onlyThisLayer ? Sets.difference(new HashSet<>(netPlan.getNetworkLayers()), Sets.newHashSet(tree.getLayer())) : new HashSet<>(); updateAllButLinksDemandsMDemandsUsingExistingInfo(linksAllLayers, demandsAllLayers, mDemandsAllLayers, layersToKeepAllElements); }
for (MulticastTree t : cache_traversingTrees) for (Node egressNode : t.getEgressNodesReached()) final List<Link> pathToEgressNode = t.getSeqLinksToEgressNode(egressNode); if (!pathToEgressNode.contains(this)) continue; if (!netPlan.isUp (pathToEgressNode)) continue; SortedSet<Link> linksSoFar = resMCast.get(Pair.of(t.getMulticastDemand() , egressNode)); if (linksSoFar == null) { linksSoFar = new TreeSet<> (); resMCast.put(Pair.of(t.getMulticastDemand() , egressNode), linksSoFar); } linksSoFar.addAll(pathToEgressNode);
if (isUp) // from down to up if (tree.getOccupiedLinkCapacity() != 0) throw new RuntimeException("Bad"); if (tree.getCarriedTraffic() != 0) throw new RuntimeException("Bad"); tree.layer.cache_multicastTreesDown.remove(tree); } else if (tree.getOccupiedLinkCapacity() != tree.occupiedLinkCapacityIfNotFailing) throw new RuntimeException("Bad"); if (tree.getCarriedTraffic() != tree.carriedTrafficIfNotFailing) throw new RuntimeException("Bad"); tree.layer.cache_multicastTreesDown.add(tree); tree.setCarriedTraffic(tree.carriedTrafficIfNotFailing, tree.occupiedLinkCapacityIfNotFailing); // updates links since all are up ErrorHandling.setDebug(previousDebug); } else throw new RuntimeException("Bad");
/** Returns the set of multicast trees in the given layer with the given tag. If no layer is provided, the defaulf layer is assumed. * @param tag the tag * @param optionalLayerParameter the layer (optional) * @return the set (or an empty set if there are no elements to return) */ public SortedSet<MulticastTree> getTaggedMulticastTrees (String tag , NetworkLayer... optionalLayerParameter) { final NetworkLayer layer = checkInThisNetPlanOptionalLayerParameter(optionalLayerParameter); final SortedSet<NetworkElement> el = cache_taggedElements.get (tag); if (el == null) return new TreeSet<> (); return el.stream ().filter (e->e instanceof MulticastTree).map(e->(MulticastTree) e).filter(e->e.getLayer().equals(layer)).collect (Collectors.toCollection(TreeSet::new)); } /** Returns the set of layers with the given tag.
@Override void checkCachesConsistency () { super.checkCachesConsistency (); if (!layer.multicastTrees.contains(this)) throw new RuntimeException ("Bad"); if (!demand.cache_multicastTrees.contains(this)) throw new RuntimeException ("Bad"); if (linkSet == null) throw new RuntimeException ("Multicast tree " + this + ", linkSet == null"); if (initialSetLinksWhenWasCreated == null) throw new RuntimeException ("Multicast Tree " + this + ", initialSetLinksWhenWasCreated == null"); netPlan.checkInThisNetPlanAndLayer(linkSet , layer); for (Link link : linkSet) if (!link.cache_traversingTrees.contains(this)) throw new RuntimeException ("Bad"); for (Node node : cache_traversedNodes) if (!node.cache_nodeAssociatedulticastTrees.contains(this)) throw new RuntimeException ("Bad"); boolean shouldBeUp = true; for (Link e : linkSet) if (!e.isUp) { shouldBeUp = false; break; } if (shouldBeUp) for (Node n : cache_traversedNodes) if (!n.isUp) { shouldBeUp = false; break; } if (!shouldBeUp != this.isDown()) throw new RuntimeException("Bad"); if (shouldBeUp) { if (getCarriedTraffic() != carriedTrafficIfNotFailing) throw new RuntimeException ("Bad"); } else { if (getCarriedTraffic() != 0) throw new RuntimeException ("Bad"); } }
String str_seqLinks = CollectionUtils.join(tree.linkSet, " , "); String treeInformation = String.format("mt%d (id %d), multicast demand: md%d (id %d), carried traffic: %.3g, occupied capacity: %.3g, links: %s, nodes: %s, attributes: %s", tree.index, tree.id, tree.demand.index, tree.demand.id, tree.getCarriedTraffic(), tree.getOccupiedLinkCapacity(), str_seqLinks, str_seqNodes, tree.attributes.isEmpty() ? "none" : tree.attributes); netPlanInformation.append(treeInformation); netPlanInformation.append(NEWLINE);
/** * <p>Returns the sum of the traffic carried by the {@link com.net2plan.interfaces.networkDesign.MulticastTree MulticastTree} traversing the link.</p> * @return The carried traffic (in traffic units) */ public double getMulticastCarriedTraffic() { double accum = 0; for (MulticastTree t : cache_traversingTrees) accum += t.getCarriedTraffic(); return accum; }
final boolean shoulbBeUp = (tree.getLinkSet().stream().allMatch(e->e.isUp) && (tree.getNodeSet().stream().allMatch(n->n.isUp))); final boolean travZeroCapLinks = tree.getLinkSet().stream().anyMatch(e->e.capacity < Configuration.precisionFactor); if (shoulbBeUp && cache_multicastTreesDown.contains(tree)) throw new RuntimeException (); if (!shoulbBeUp && !tree.getLinkSet().isEmpty() && !cache_multicastTreesDown.contains(tree)) throw new RuntimeException (); if (travZeroCapLinks && !cache_multicastTreesTravLinkZeroCap.contains(tree)) throw new RuntimeException ();
newOccupiedLinkCapacity = NetPlan.adjustToTolerance(newOccupiedLinkCapacity); checkAttachedToNetPlanObject(); netPlan.checkIsModifiable(); if ((newCarriedTraffic < 0) || (newOccupiedLinkCapacity < 0)) throw new Net2PlanException ("Carried traffics and occupied link capacities must be non-negative"); demand.carriedTraffic = 0; for (MulticastTree t : demand.cache_multicastTrees) demand.carriedTraffic += t.getCarriedTraffic(); if (demand.coupledUpperLayerLinks != null) for (Link e : demand.coupledUpperLayerLinks.values())
attributes.addAll(netPlan.getMulticastTreeFromId(treeId).getAttributes().keySet()); data[itemId][t + 1] = netPlan.getMulticastTreeFromId(treeId).getAttribute(attribute); if (data[itemId][t + 1] == null) data[itemId][t + 1] = "";