Beispiel #1
0
        //Will return 0, 1, or 2 batches
        public SafeOrderedReturn Ordered(SafeEnvelope msg, int index)
        {
            try
            {
                SafeBatch[] batches        = new SafeBatch[2];
                bool        ispendingbatch = true;
                ulong       MsgSizeBytes   = (ulong)msg.Payload.Length; //Length of byte array = size in bytes

                //Message is too big and thus will overflow, send pending and this msg in its own batch
                if (MsgSizeBytes > MaxPendingSizeBytes)
                {
                    if (PendingBatch.Messages.Count() > 0)
                    {
                        batches[0] = Cut(); //Add pending batch to return
                    }
                    SafeBatch newbatch = new SafeBatch();
                    newbatch.Messages    = new SafeEnvelope[1];
                    newbatch.Messages[0] = msg;
                    batches[1]           = newbatch;
                    ispendingbatch       = false;
                }
                else
                {
                    //Message will cause overflow, cut pending batch
                    if (PendingBatchSizeBytes + MsgSizeBytes > MaxPendingSizeBytes)
                    {
                        batches[0] = Cut(); //Add pending batch to return
                    }

                    while (index > MsgNum || pendinglocked)
                    {
                    }                                       //Wait for it to be this msg's turn and not currently cutting batch

                    AddToPending(msg, MsgSizeBytes, index); //Add message to pending batch

                    //Pending batch has reached max count, must cut
                    //If the last if statement was true, this one will not be true
                    if (PendingBatch.MsgCount >= MaxPendingMsgCount)
                    {
                        pendinglocked  = true;
                        batches[1]     = Cut(); //Add pending batch to return
                        ispendingbatch = false;
                    }

                    Interlocked.Add(ref MsgNum, 1); //Increment msgnum
                }
                SafeOrderedReturn toreturn = new SafeOrderedReturn();
                toreturn.Batches        = batches;
                toreturn.IsPendingBatch = ispendingbatch;
                return(toreturn);
            }
            catch
            {
                int a = 1;
                return(new SafeOrderedReturn());
            }
        }
Beispiel #2
0
        //Return and reset pending batch
        public SafeBatch Cut()
        {
            SafeBatch returnbatch = PendingBatch; //Set batch to return

            PendingBatch          = new SafeBatch();
            PendingBatch.Messages = new SafeEnvelope[MaxPendingMsgCount];
            PendingBatch.MsgCount = 0;
            PendingBatchSizeBytes = 0;
            pendinglocked         = false;
            return(returnbatch);
        }
Beispiel #3
0
        public static unsafe void HandleMessageCPU(SafeMessage msg, int index)
        {
            Console.WriteLine(String.Format("HandleMessageCPU {0}", index));
            //Check if configmsg is initialized. If not, it's a normal message.
            bool config = false;

            if (config) //It's a config message
            {
                //Cut pending batch so we can make and send the block then a config block
                SafeBatch newbatch = Cutter.Cut();
                Console.WriteLine("Config Message, newbatch message count={0}", newbatch.Messages.Count());
                if (newbatch.Messages.Count() > 0)
                {
                    Task.Factory.StartNew(() => MakeBlockCPU(newbatch, false));
                }
                //Now make a config block
                SafeBatch newconfigbatch = new SafeBatch();
                newconfigbatch.Messages    = new SafeEnvelope[1];
                newconfigbatch.Messages[0] = msg.ConfigMsg;
                Task.Factory.StartNew(() => MakeBlockCPU(newconfigbatch, true));
            }
            else //It's a normal message
            {
                //Stopwatch sw1 = new Stopwatch();
                //sw1.Start();
                SafeOrderedReturn OR = Cutter.Ordered(msg.NormalMsg, index);
                //sw1.Stop();
                //string output = "Time taken: " + sw1.ElapsedTicks + " ticks" + Environment.NewLine;
                //Console.WriteLine(output);
                //Ordered returns 0, 1, or 2 batches, process each one
                Console.WriteLine("Normal Message, batches: {0}, {1}", OR.Batches[0], OR.Batches[1]);
                Parallel.For(0, 2, i =>
                {
                    if (OR.Batches[i] != null)
                    {
                        Task.Factory.StartNew(() => MakeBlockCPU(OR.Batches[i], false));
                    }
                });

                //Handle setting of timer
                bool pending   = OR.IsPendingBatch;       //There is a pending batch
                bool timernull = Timer == new DateTime(); //Timer is default value
                if (!timernull && !pending)               //There is a timer but no pending batches, unnecessary
                {
                    Timer = new DateTime();               //Set timer to default value
                }
                else if (timernull && pending)
                {
                    Timer = DateTime.Now; //Start timer
                }
            }
        }
Beispiel #4
0
        public Block CreateNextBlockCPU(SafeBatch newbatch)
        {
            byte[]    previousblockhash = BlockHeaderHash(PreviousBlockHeader);
            BlockData blockdata         = new BlockData();

            byte[][] data = new byte[newbatch.Messages.Count()][];
            //Convert each message to byte format to add to data
            Parallel.For(0, newbatch.Messages.Count(), i =>
            {
                data[i] = Marshal(newbatch.Messages[i]);
            });
            blockdata.Data = data;
            Block newblock = NewBlock(PreviousBlockHeader.Number + 1, previousblockhash);

            newblock.Header.DataHash = BlockDataHash(blockdata);
            newblock.Data            = blockdata;
            PreviousBlockHeader      = newblock.Header;
            return(newblock);
        }
Beispiel #5
0
        //Uses blockwriter to create a new block and then write it down
        static void MakeBlockCPU(SafeBatch newbatch, bool config)
        {
            DateTime blockwritetimer = DateTime.Now;
            Block    newblock        = Writer.CreateNextBlockCPU(newbatch);

            if (config)
            {
                Writer.WriteConfigBlock(newblock);
            }
            else
            {
                Interlocked.Increment(ref BlockCount);
                //Writer.WriteBlock(newblock);
            }
            string blockoutput = "Creating " + (config ? "config" : "normal") + " block " + newblock.Header.Number + Environment.NewLine;

            blockoutput += "Message count: " + newbatch.MsgCount + Environment.NewLine;
            blockoutput += "Time taken: " + (DateTime.Now - blockwritetimer).TotalMilliseconds + "ms" + Environment.NewLine;
            blockoutput += "---------------------------------------------------------------------" + Environment.NewLine;
            Console.WriteLine(blockoutput);
        }