Example #1
0
        /// <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;
        }