Esempio n. 1
0
        private void SendDg()
        {
            foreach (var node in Nodes)
                for (var iBuf = 0; iBuf < node.Buffer.Count; iBuf++)
                {
                    var package = node.Buffer[iBuf];
                    if (package.IsDatagram && package.Sent == 0 && !package.AlreadySentOnThisTick)
                    {
                        // Sender part
                        // -----------------------------------------------------------------
                        // Select local route
                        for (var i = 0; i < Nodes[package.FromNow].Table.Count; i++)
                        {
                            var row = Nodes[package.FromNow].Table[i];

                            // ReSharper disable once InvertIf
                            if (row.From == package.From &&
                                row.To == package.To &&
                                package.ReceivedFrom != row.SendTo &&
                                ConnectionIsFilled(package, row.SendThroughConnection))
                            {
                                package.ToNow = row.SendTo;
                                package.SelectedRoute = i;
                                package.SendThroughConnection = row.SendThroughConnection;

                                // If this is half duplex, make it taken
                                Connections[package.SendThroughConnection].MakeItFreeOnNextTact = false;

                                break;
                            }
                        }

                        // Cannot find route (all routes are totally filled or half duplex to other current)
                        if (package.SelectedRoute == -1)
                            continue;

                        var willSend = HowManySend(package);

                        // For statistics
                        //DatagramsSent++;
                        if (!package.IsService)
                            AvarageWaitTimeDatagram += TickNumber - package.CreatedOn;

                        // If package is last in half duplex
                        if (!Connections[package.SendThroughConnection].IsFullDuplex &&
                            package.Sent + willSend == package.SizeTotal())
                            Connections[package.SendThroughConnection].MakeItFreeOnNextTact = true;

                        // Other side buffer is overflowed
                        if (BufferSize <= Nodes[package.ToNow].Buffer.Count)
                        {
                            package.ReceiverHasOverflowedBuffer = true;

                            // Package sended
                            if (CheckIsPackageSent(package))
                                iBuf--;

                            continue;
                        }

                        // Remember receiver index in buffer
                        package.ReceiverBufIdx = Nodes[package.ToNow].Buffer.Count;

                        // Receiver part
                        // -----------------------------------------------------------------
                        var receiverPackage = new Package
                        {
                            To = package.To,
                            From = package.From,
                            IsDatagram = true,
                            Id = package.Id,
                            PartIdx = package.PartIdx,
                            SizeInformation = package.SizeInformation,
                            MyBufIdx = package.ReceiverBufIdx, // Itself
                            FromNow = package.ToNow,
                            Received = willSend,
                            TickGeneratedOn = package.TickGeneratedOn,
                            AlreadySentOnThisTick = true,
                            ReceivedFrom = package.FromNow,
                            IsService = package.IsService,
                            ApprovesPackage = package.ApprovesPackage,
                            //ApprovesMessage = package.ApprovesMessage,
                            ApproveBufferIdxWhoWait = package.ApproveBufferIdxWhoWait,
                            ApproveFrom = package.FromNow,
                            //ApproveTo = package.ToNow,
                        };
                        Nodes[package.ToNow].Buffer.Add(receiverPackage);

                        // Package sended
                        if (CheckIsPackageSent(package))
                            iBuf--;
                    }
                }
        }
Esempio n. 2
0
        private void SendVc()
        {
            foreach (var node in Nodes)
                for (var iBuf = 0; iBuf < node.Buffer.Count; iBuf++)
                {
                    var package = node.Buffer[iBuf];
                    if (!package.IsDatagram && package.Sent == 0 && !package.AlreadySentOnThisTick)
                    {
                        // Sender part
                        // -----------------------------------------------------------------
                        // Select local route
                        foreach (var row in Nodes[package.FromNow].Table.Where(row => row.From == package.From &&
                                                                                      row.To == package.To &&
                                                                                      package.ReceivedFrom != row.SendTo &&
                                                                                      row.PathPriority == package.Label))
                        {
                            package.ToNow = row.SendTo;
                            package.SendThroughConnection = row.SendThroughConnection;

                            // If this is half duplex, make it taken
                            Connections[package.SendThroughConnection].MakeItFreeOnNextTact = false;
                            break;
                        }

                        if (package.ToNow == -1) // If sending to node without route to it (some connection is disabled)
                            continue;

                        var willSend = HowManySend(package);

                        if (willSend == 0)
                            continue;

                        // For statistics
                        //VirtualSent++;
                        AvarageWaitTimeVirtual += TickNumber - package.CreatedOn;

                        // If package is last in half duplex
                        if (!Connections[package.SendThroughConnection].IsFullDuplex &&
                            package.Sent + willSend == package.SizeTotal())
                            Connections[package.SendThroughConnection].MakeItFreeOnNextTact = true;

                        // Other side buffer is overflowed
                        if (BufferSize <= Nodes[package.ToNow].Buffer.Count)
                        {
                            package.ReceiverHasOverflowedBuffer = true;

                            // Package sended
                            if (CheckIsPackageSent(package))
                                iBuf--;

                            continue;
                        }

                        // Remember receiver index in buffer
                        package.ReceiverBufIdx = Nodes[package.ToNow].Buffer.Count;

                        // Receiver part
                        // -----------------------------------------------------------------
                        var receiverPackage = new Package
                        {
                            To = package.To,
                            From = package.From,
                            IsDatagram = false,
                            Id = package.Id,
                            PartIdx = package.PartIdx,
                            SizeInformation = package.SizeInformation,
                            MyBufIdx = package.ReceiverBufIdx, // Itself
                            FromNow = package.ToNow,
                            Received = willSend,
                            Label = package.Label,
                            TickGeneratedOn = package.TickGeneratedOn,
                            AlreadySentOnThisTick = true,
                            ReceivedFrom = package.FromNow,
                            IsService = package.IsService,
                            ApprovesPackage = package.ApprovesPackage,
                            //ApprovesMessage = package.ApprovesMessage,
                            ApproveBufferIdxWhoWait = package.ApproveBufferIdxWhoWait,
                            ApproveFrom = package.FromNow,
                            //ApproveTo = package.ToNow,
                        };
                        Nodes[package.ToNow].Buffer.Add(receiverPackage);

                        // Package sent
                        if (CheckIsPackageSent(package))
                            iBuf--;
                        //if (CheckIsPackageSent(package))
                        //iBuf--;
                    }
                }
        }
Esempio n. 3
0
        /// <summary>
        /// Checks how many bytes can be sent from package throughselected connection
        /// </summary>
        /// <param name="package">Specified package</param>
        /// <returns></returns>
        private int HowManySend(Package package)
        {
            var connSendThrough = Connections[package.SendThroughConnection];
            int willSend;

            // Sending through full duplex
            if (connSendThrough.IsFullDuplex)
            {
                willSend = connSendThrough.TransferRate / 2;
                if (connSendThrough.SendingFromNode == package.FromNow)
                    willSend -= connSendThrough.FilledFromNode;
                else
                    willSend -= connSendThrough.FilledToNode;
            }
            else // Sending through half duplex
            {
                willSend = connSendThrough.TransferRate;
                if (connSendThrough.SendingFromNode == package.FromNow)
                    willSend -= connSendThrough.FilledFromNode;
                else
                    willSend -= connSendThrough.FilledToNode;
            }

            // "Send"
            if (package.SizeTotal() < package.Sent + willSend)
                willSend = package.SizeTotal() - package.Sent;
            package.Sent += willSend;

            // Set connection fill
            if (connSendThrough.IsFullDuplex)
                if (connSendThrough.SendingFromNode == package.FromNow)
                    connSendThrough.FilledFromNode += willSend;
                else
                    connSendThrough.FilledToNode += willSend;
            else // Sending through half duplex
                if (connSendThrough.SendingFromNode == package.FromNow)
                connSendThrough.FilledFromNode += willSend;
            else
                connSendThrough.FilledToNode += willSend;

            return willSend;
        }
Esempio n. 4
0
        private void DeletePackage(Package package)
        {
            var myNode = Nodes[package.FromNow];
            for (var i = package.MyBufIdx + 1; i < myNode.Buffer.Count; i++)
                myNode.Buffer[i].MyBufIdx--;

            // Increase self buffer indexes for packages in my buffer
            foreach (var bufRow in Nodes.Where(t => t != myNode).SelectMany(node =>
            node.Buffer.Where(t => t.ToNow == package.FromNow && package.MyBufIdx < t.ReceiverBufIdx)))
                bufRow.ReceiverBufIdx--;

            // Increase self buffer indexes for packages in my buffer
            //if (!package.IsService)
            foreach (var bufRow in Nodes.Where(t => t != myNode).SelectMany(node =>
            node.Buffer.Where(t => t.ApprovesPackage && t.ApproveFrom == package.FromNow && package.MyBufIdx < t.ApproveBufferIdxWhoWait)))
                bufRow.ApproveBufferIdxWhoWait--;

            // For statistics
            if (package.FromNow == package.To && !package.IsService)
                if (package.IsDatagram)
                {
                    MessagesReceivedDatagram++;
                    AverageSendTimeDatagram += TickNumber - package.TickGeneratedOn;
                }
                else
                {
                    MessagesReceivedVirtual++;
                    AverageSendTimeVirtual += TickNumber - package.TickGeneratedOn;
                }

            // Remember to history
            package.TickCompletedOn = TickNumber;
            myNode.History.Add(package);

            myNode.Buffer.RemoveAt(package.MyBufIdx);
        }
Esempio n. 5
0
        /// <summary>
        /// Check connectinion for ability to transfer at least 1B
        /// </summary>
        /// <param name="package">Package try try to transfer</param>
        /// <param name="connection">Index of the connection</param>
        /// <returns></returns>
        private bool ConnectionIsFilled(Package package, int connection)
        {
            var connExplore = Connections[connection];
            int willSend;

            // Sending through full duplex
            if (connExplore.IsFullDuplex)
            {
                willSend = connExplore.TransferRate / 2;
                if (package.IsDatagram && connExplore.SendingFromNode == package.FromNow ||
                    !package.IsDatagram && connExplore.SendingFromNode == package.From)
                    willSend -= connExplore.FilledFromNode;
                else
                    willSend -= connExplore.FilledToNode;
            }
            else // Sending through half duplex
            {
                willSend = connExplore.TransferRate;
                if (package.IsDatagram && connExplore.SendingFromNode == package.FromNow ||
                    !package.IsDatagram && connExplore.SendingFromNode == package.From)
                    willSend -= connExplore.FilledFromNode;
                else
                    willSend -= connExplore.FilledToNode;
            }
            return willSend != 0;
        }
Esempio n. 6
0
        /// <summary>
        /// Checks package for completed transfer
        /// </summary>
        /// <param name="package">Specified package</param>
        private bool CheckIsPackageSent(Package package)
        {
            if (package.Sent == package.SizeTotal() ||    // Sended from some node
                package.To == package.FromNow)              // Reached next node
            {
                if (package.ImInfoAndICanBeDeleted || package.IsService)
                    DeletePackage(package);

                // If need further send
                if (!package.ReceiverHasOverflowedBuffer && package.Sent == package.SizeTotal())
                {
                    var packageOtherSide = Nodes[package.ToNow].Buffer[package.ReceiverBufIdx];

                    if (!package.IsService)
                    {
                        Nodes[package.ToNow].Buffer.Add(new Package
                        {
                            IsService = true,
                            ApprovesPackage = true,
                            ApproveFrom = package.FromNow,
                            //ApproveTo = package.ToNow,
                            From = package.ToNow,
                            To = package.FromNow,
                            FromNow = package.ToNow,
                            AlreadySentOnThisTick = true,
                            Sent = 0,
                            MyBufIdx = Nodes[package.ToNow].Buffer.Count,
                            IsDatagram = true,
                            ApproveBufferIdxWhoWait = package.MyBufIdx,
                        });

                        if (package.IsDatagram)
                            ServiceDg++;
                        else
                            ServiceVc++;

                        // For statistics
                        if (package.Sent == package.SizeTotal())
                            if (package.IsDatagram)
                                DatagramsReceived++;
                            else
                                VirtualReceived++;

                        // For global history
                        if (packageOtherSide.FromNow == packageOtherSide.To)
                        {
                            var completedPacks =
                                Nodes[packageOtherSide.FromNow].Buffer.Count(pack => pack.Id == packageOtherSide.Id);
                            if (completedPacks == packageOtherSide.Parts &&
                                !CompletedMessages.Contains(packageOtherSide.Id))
                            {
                                CompletedMessages.Add(packageOtherSide.Id);
                                _messages[packageOtherSide.Id].MessageCompletedOn = TickNumber;
                            }
                        }

                        packageOtherSide.Received = -1;
                        packageOtherSide.Sent = 0;
                        packageOtherSide.CreatedOn = TickNumber;

                        // If other size package reached final destiny
                        if (package.To == package.ToNow)
                            DeletePackage(packageOtherSide);
                    }
                    else
                    {
                        if (package.ApprovesPackage)
                            DeletePackage(packageOtherSide);
                    }
                }

                if (package.ApprovesPackage && package.To == package.ToNow)
                {
                    var packageInfo = Nodes[package.ApproveFrom].Buffer[package.ApproveBufferIdxWhoWait];
                    packageInfo.ImInfoAndICanBeDeleted = true;
                    DeletePackage(packageInfo);
                }

                return true;
            }
            return false;
        }
Esempio n. 7
0
        /// <summary>
        /// Sends message (from template in parameter)
        /// </summary>
        /// <param name="package">Package with initial data</param>
        public void SendPackage(Package package)
        {
            // Divide to packages
            var packages = new List<Package>();
            _messages.Add(new Package
            {
                Id = FreeId,
                MessageCreatedOn = TickNumber
            });

            if (package.SizeTotal() <= SizeMaxPackage)  // If message is in size like one package
            {
                package.FromNow = package.From;
                package.Id = FreeId;
                package.MyBufIdx = Nodes[package.From].Buffer.Count;
                package.Sent = 0;
                package.PartIdx = 0;
                package.TickGeneratedOn = TickNumber;  // For statistics
                package.CreatedOn = TickNumber;        // For statistics
                packages.Add(package);
                SendedMessagePart = 1;    // For external world

                if (package.IsDatagram) DatagramsSent++;
                else VirtualSent++;
            }
            else   // If bigger
            {
                // Divide message to packages
                var sizeMaxInf = SizeMaxPackage - Package.SizeHeader;
                var packagesNumber = Convert.ToInt32(Math.Ceiling(package.SizeInformation / (double)sizeMaxInf));

                if (package.IsDatagram) DatagramsSent += packagesNumber;
                else VirtualSent += packagesNumber;

                SendedMessagePart = packagesNumber;    // For external world
                var firstBufIdx = Nodes[package.From].Buffer.Count;
                for (var i = 0; i < packagesNumber - 1; i++)    // Several the same packages
                    packages.Add(new Package
                    {
                        To = package.To,
                        FromNow = package.From,
                        From = package.From,
                        IsDatagram = package.IsDatagram,
                        Id = FreeId,
                        PartIdx = i,
                        SizeInformation = sizeMaxInf,
                        MyBufIdx = firstBufIdx + i,
                        Sent = 0,
                        Parts = packagesNumber,
                        TickGeneratedOn = TickNumber,  // For statistics
                        CreatedOn = TickNumber         // For statistics
                    });

                // Last package can be lesser in size
                var sizeLastInf = package.SizeInformation % sizeMaxInf;
                packages.Add(new Package
                {
                    To = package.To,
                    FromNow = package.From,
                    From = package.From,
                    IsDatagram = package.IsDatagram,
                    Id = FreeId,
                    PartIdx = packagesNumber - 1,
                    SizeInformation = sizeLastInf,
                    MyBufIdx = firstBufIdx + packagesNumber - 1,
                    Sent = 0,
                    Parts = packagesNumber,
                    TickGeneratedOn = TickNumber,  // For statistics
                    CreatedOn = TickNumber         // For statistics
                });
            }

            // Add packages while it isn't filled
            foreach (var pack in packages.TakeWhile(pack => BufferSize > Nodes[package.From].Buffer.Count))
                Nodes[package.From].Buffer.Add(pack);

            // Add new packages to buffer
            //Nodes[package.From].Buffer.AddRange(packages);

            FreeId++;
        }