Esempio n. 1
0
        public void AddSourceNeighbor(ConversionRouter routerWeCanConvertFrom, bool lossless, Converter <ValueStructure, ValueStructure> directConvert)
        {
            MathIdentifier id = routerWeCanConvertFrom.structureId;

            if (Propose(new ConversionDistance(id, 0, lossless, null, directConvert), routerWeCanConvertFrom))
            {
                ConversionRoute route = new ConversionRoute(id, directConvert);
                if (lossless)
                {
                    if (losslessNeighbors.ContainsKey(id))
                    {
                        losslessNeighbors[id] = route;
                    }
                    else
                    {
                        losslessNeighbors.Add(id, route);
                    }
                }
                else
                {
                    if (lossyNeighbors.ContainsKey(id))
                    {
                        lossyNeighbors[id] = route;
                    }
                    else
                    {
                        lossyNeighbors.Add(id, route);
                    }
                }
                routerWeCanConvertFrom.AddTargetNeighbor(this); //receiving all its routes ...
                BroadcastDistanceVector();
            }
        }
        /// <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);
            }
        }
 public void AddSourceNeighbor(ConversionRouter routerWeCanConvertFrom, bool lossless, Converter<ValueStructure, ValueStructure> directConvert)
 {
     MathIdentifier id = routerWeCanConvertFrom.structureId;
     if(Propose(new ConversionDistance(id, 0, lossless, null, directConvert), routerWeCanConvertFrom))
     {
         ConversionRoute route = new ConversionRoute(id, directConvert);
         if(lossless)
         {
             if(losslessNeighbors.ContainsKey(id))
                 losslessNeighbors[id] = route;
             else
                 losslessNeighbors.Add(id, route);
         }
         else
         {
             if(lossyNeighbors.ContainsKey(id))
                 lossyNeighbors[id] = route;
             else
                 lossyNeighbors.Add(id, route);
         }
         routerWeCanConvertFrom.AddTargetNeighbor(this); //receiving all its routes ...
         BroadcastDistanceVector();
     }
 }
        /// <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;
        }