/// <returns>True if the route was better than existing routes.</returns> private bool Propose(ConversionDistance distance, ConversionRouter proposedBy) { MathIdentifier id = distance.CanConvertFrom; if (structureId.Equals(id)) { return(false); } distance.Lossless = distance.Lossless && losslessNeighbors.ContainsKey(proposedBy.structureId); distance.Cost++; if (distance.NextHop != null) //not a new neighbour { Converter <ValueStructure, ValueStructure> distanceC = distance.Convert, localC; if (losslessNeighbors.ContainsKey(proposedBy.structureId)) { localC = losslessNeighbors[proposedBy.structureId].Convert; } else { localC = lossyNeighbors[proposedBy.structureId].Convert; } distance.Convert = delegate(ValueStructure v) { return(localC(distanceC(v))); }; } distance.NextHop = proposedBy; if (vector.ContainsKey(id)) { ConversionDistance cd = vector[id]; if (distance.Lossless && !cd.Lossless || distance.Cost < cd.Cost && (distance.Lossless || !cd.Lossless)) { vector[id] = distance; BroadcastDistanceVector(); return(true); } return(false); } vector.Add(id, distance); BroadcastDistanceVector(); return(true); }
/// <returns>True if the route was better than existing routes.</returns> /// <remarks>It is expected that we already know the proposing neighbor router <c>proposedBy</c>!</remarks> public bool Propose(IRouteDistance distance, IConversionRouter proposedBy) { MathIdentifier id = distance.CanConvertFrom; // I'm already myself, so I won't accept it whatever you propose :) if (structureId.Equals(id)) { return(false); } bool knownLosslessProposer = losslessNeighbors.ContainsKey(proposedBy.TypeIdentifier); bool knownLossyProposer = lossyNeighbors.ContainsKey(proposedBy.TypeIdentifier); // does the router propose himself? if (proposedBy.TypeIdentifier.Equals(id)) { if (distance.Cost != 0) { throw new InvalidOperationException("An conversion router strangely thinks he can't reach himself with zero cost."); } // we didn't know it, or it's better than before, so we add it to the neighbor list if (distance.Lossless && !knownLosslessProposer) { losslessNeighbors[id] = new ConversionRoute(id, distance.Convert); } else if (!distance.Lossless && !knownLossyProposer) { lossyNeighbors[id] = new ConversionRoute(id, distance.Convert); } else { return(false); } // we also want to add this neighbour to the vector. vector[id] = new ConversionDistance(id, 1, distance.Lossless, proposedBy, distance.Convert); // before we broadcast our vector, we wan't to "subscribe" on this new inbound router // to receive all his broadcasts. proposedBy.AddTargetNeighbor(this); // now we broadcast (probably we already did this when the router sent any // broadcasts as a result of AddTargetNeighbor, but we want to be sure) BroadcastDistanceVector(); return(true); } if (!(knownLosslessProposer || knownLossyProposer)) { throw new InvalidOperationException("An unknown router strangely proposes some other host without first proposing himself."); } // apparently he proposes some other host to be routed through himself, // so we have to combine the poposed cost with those required to reach himself bool lossless = distance.Lossless && knownLosslessProposer; int cost = distance.Cost + 1; // is the proposed route better, or didn't we even know such a route yet? IRouteDistance existingDistance; if (!vector.TryGetValue(id, out existingDistance) || lossless && !existingDistance.Lossless || cost < existingDistance.Cost && (lossless || !existingDistance.Lossless)) { // then we want to add this route to our vector // we have to map the proposed conversion with then one required to convert from him Converter <object, object> distanceC = distance.Convert, localC, convert; if (knownLosslessProposer) { localC = losslessNeighbors[proposedBy.TypeIdentifier].Convert; } else { localC = lossyNeighbors[proposedBy.TypeIdentifier].Convert; } convert = delegate(object v) { return(localC(distanceC(v))); }; // Add route to vector and broadcast the vector. vector[id] = new ConversionDistance(id, cost, lossless, proposedBy, convert); BroadcastDistanceVector(); return(true); } else { return(false); } }
/// <returns>True if the route was better than existing routes.</returns> private bool Propose(ConversionDistance distance, ConversionRouter proposedBy) { MathIdentifier id = distance.CanConvertFrom; if(structureId.Equals(id)) return false; distance.Lossless = distance.Lossless && losslessNeighbors.ContainsKey(proposedBy.structureId); distance.Cost++; if(distance.NextHop != null) //not a new neighbour { Converter<ValueStructure, ValueStructure> distanceC = distance.Convert, localC; if(losslessNeighbors.ContainsKey(proposedBy.structureId)) localC = losslessNeighbors[proposedBy.structureId].Convert; else localC = lossyNeighbors[proposedBy.structureId].Convert; distance.Convert = delegate(ValueStructure v) { return localC(distanceC(v)); }; } distance.NextHop = proposedBy; if(vector.ContainsKey(id)) { ConversionDistance cd = vector[id]; if(distance.Lossless && !cd.Lossless || distance.Cost < cd.Cost && (distance.Lossless || !cd.Lossless)) { vector[id] = distance; BroadcastDistanceVector(); return true; } return false; } vector.Add(id, distance); BroadcastDistanceVector(); return true; }
/// <returns>True if the route was better than existing routes.</returns> /// <remarks>It is expected that we already know the proposing neighbor router <c>proposedBy</c>!</remarks> public bool Propose(IRouteDistance distance, IConversionRouter proposedBy) { MathIdentifier id = distance.CanConvertFrom; // I'm already myself, so I won't accept it whatever you propose :) if(structureId.Equals(id)) return false; bool knownLosslessProposer = losslessNeighbors.ContainsKey(proposedBy.TypeIdentifier); bool knownLossyProposer = lossyNeighbors.ContainsKey(proposedBy.TypeIdentifier); // does the router propose himself? if(proposedBy.TypeIdentifier.Equals(id)) { if(distance.Cost != 0) throw new InvalidOperationException("An conversion router strangely thinks he can't reach himself with zero cost."); // we didn't know it, or it's better than before, so we add it to the neighbor list if(distance.Lossless && !knownLosslessProposer) losslessNeighbors[id] = new ConversionRoute(id, distance.Convert); else if(!distance.Lossless && !knownLossyProposer) lossyNeighbors[id] = new ConversionRoute(id, distance.Convert); else return false; // we also want to add this neighbour to the vector. vector[id] = new ConversionDistance(id, 1, distance.Lossless, proposedBy, distance.Convert); // before we broadcast our vector, we wan't to "subscribe" on this new inbound router // to receive all his broadcasts. proposedBy.AddTargetNeighbor(this); // now we broadcast (probably we already did this when the router sent any // broadcasts as a result of AddTargetNeighbor, but we want to be sure) BroadcastDistanceVector(); return true; } if(!(knownLosslessProposer || knownLossyProposer)) throw new InvalidOperationException("An unknown router strangely proposes some other host without first proposing himself."); // apparently he proposes some other host to be routed through himself, // so we have to combine the poposed cost with those required to reach himself bool lossless = distance.Lossless && knownLosslessProposer; int cost = distance.Cost + 1; // is the proposed route better, or didn't we even know such a route yet? IRouteDistance existingDistance; if(!vector.TryGetValue(id, out existingDistance) || lossless && !existingDistance.Lossless || cost < existingDistance.Cost && (lossless || !existingDistance.Lossless)) { // then we want to add this route to our vector // we have to map the proposed conversion with then one required to convert from him Converter<object, object> distanceC = distance.Convert, localC, convert; if(knownLosslessProposer) localC = losslessNeighbors[proposedBy.TypeIdentifier].Convert; else localC = lossyNeighbors[proposedBy.TypeIdentifier].Convert; convert = delegate(object v) { return localC(distanceC(v)); }; // Add route to vector and broadcast the vector. vector[id] = new ConversionDistance(id, cost, lossless, proposedBy, convert); BroadcastDistanceVector(); return true; } else return false; }