Ejemplo n.º 1
0
        private void Negotiate(ProgressMonitor monitor)
        {
            var  ackId                  = new MutableObjectId();
            int  resultsPending         = 0;
            int  havesSent              = 0;
            int  havesSinceLastContinue = 0;
            bool receivedContinue       = false;
            bool receivedAck            = false;
            bool sendHaves              = true;

            NegotiateBegin();
            while (sendHaves)
            {
                RevCommit c = _walk.next();
                if (c == null)
                {
                    break;
                }

                pckOut.WriteString("have " + c.getId().Name + "\n");
                havesSent++;
                havesSinceLastContinue++;

                if ((31 & havesSent) != 0)
                {
                    continue;
                }

                if (monitor.IsCancelled)
                {
                    throw new CancelledException();
                }

                pckOut.End();
                resultsPending++;

                if (havesSent == 32)
                {
                    continue;
                }

                for (; ;)
                {
                    PacketLineIn.AckNackResult anr = pckIn.readACK(ackId);

                    if (anr == PacketLineIn.AckNackResult.NAK)
                    {
                        resultsPending--;
                        break;
                    }

                    if (anr == PacketLineIn.AckNackResult.ACK)
                    {
                        _multiAck      = false;
                        resultsPending = 0;
                        receivedAck    = true;
                        sendHaves      = false;
                        break;
                    }

                    if (anr == PacketLineIn.AckNackResult.ACK_CONTINUE)
                    {
                        MarkCommon(_walk.parseAny(ackId));
                        receivedAck            = true;
                        receivedContinue       = true;
                        havesSinceLastContinue = 0;
                    }

                    if (monitor.IsCancelled)
                    {
                        throw new CancelledException();
                    }
                }

                if (receivedContinue && havesSinceLastContinue > MAX_HAVES)
                {
                    break;
                }
            }

            if (monitor.IsCancelled)
            {
                throw new CancelledException();
            }
            pckOut.WriteString("done\n");
            pckOut.Flush();

            if (!receivedAck)
            {
                _multiAck = false;
                resultsPending++;
            }

            while (resultsPending > 0 || _multiAck)
            {
                PacketLineIn.AckNackResult anr = pckIn.readACK(ackId);
                resultsPending--;

                if (anr == PacketLineIn.AckNackResult.ACK)
                {
                    break;
                }

                if (anr == PacketLineIn.AckNackResult.ACK_CONTINUE)
                {
                    _multiAck = true;
                }

                if (monitor.IsCancelled)
                {
                    throw new CancelledException();
                }
            }
        }
Ejemplo n.º 2
0
        public void testId()
        {
            RevCommit a = Commit();

            Assert.AreSame(a, a.getId());
        }
        private void Negotiate(ProgressMonitor monitor)
        {
            var  ackId                  = new MutableObjectId();
            int  resultsPending         = 0;
            int  havesSent              = 0;
            int  havesSinceLastContinue = 0;
            bool receivedContinue       = false;
            bool receivedAck            = false;

            NegotiateBegin();
            for (; ;)
            {
                RevCommit c = _walk.next();
                if (c == null)
                {
                    goto END_SEND_HAVES;
                }

                pckOut.WriteString("have " + c.getId().Name + "\n");
                havesSent++;
                havesSinceLastContinue++;

                if ((31 & havesSent) != 0)
                {
                    // We group the have lines into blocks of 32, each marked
                    // with a flush (aka end). This one is within a block so
                    // continue with another have line.
                    //
                    continue;
                }

                if (monitor.IsCancelled)
                {
                    throw new CancelledException();
                }

                pckOut.End();
                resultsPending++; // Each end will cause a result to come back.

                if (havesSent == 32)
                {
                    // On the first block we race ahead and try to send
                    // more of the second block while waiting for the
                    // remote to respond to our first block request.
                    // This keeps us one block ahead of the peer.
                    //
                    continue;
                }

                for (; ;)
                {
                    PacketLineIn.AckNackResult anr = pckIn.readACK(ackId);

                    switch (anr)
                    {
                    case PacketLineIn.AckNackResult.NAK:
                        // More have lines are necessary to compute the
                        // pack on the remote side. Keep doing that.

                        resultsPending--;
                        goto END_READ_RESULT;

                    case PacketLineIn.AckNackResult.ACK:
                        // The remote side is happy and knows exactly what
                        // to send us. There is no further negotiation and
                        // we can break out immediately.

                        _multiAck      = MultiAck.OFF;
                        resultsPending = 0;
                        receivedAck    = true;
                        goto END_SEND_HAVES;

                    case PacketLineIn.AckNackResult.ACK_CONTINUE:
                    case PacketLineIn.AckNackResult.ACK_COMMON:
                    case PacketLineIn.AckNackResult.ACK_READY:
                        // The server knows this commit (ackId). We don't
                        // need to send any further along its ancestry, but
                        // we need to continue to talk about other parts of
                        // our local history.

                        MarkCommon(_walk.parseAny(ackId));
                        receivedAck            = true;
                        receivedContinue       = true;
                        havesSinceLastContinue = 0;
                        break;
                    }


                    if (monitor.IsCancelled)
                    {
                        throw new CancelledException();
                    }
                }

END_READ_RESULT:
                if (receivedContinue && havesSinceLastContinue > MAX_HAVES)
                {
                    // Our history must be really different from the remote's.
                    // We just sent a whole slew of have lines, and it did not
                    // recognize any of them. Avoid sending our entire history
                    // to them by giving up early.
                    //
                    break;
                }
            }

END_SEND_HAVES:

            // Tell the remote side we have run out of things to talk about.
            //
            if (monitor.IsCancelled)
            {
                throw new CancelledException();
            }
            pckOut.WriteString("done\n");
            pckOut.Flush();

            if (!receivedAck)
            {
                // Apparently if we have never received an ACK earlier
                // there is one more result expected from the done we
                // just sent to the remote.
                //
                _multiAck = MultiAck.OFF;
                resultsPending++;
            }

            while (resultsPending > 0 || _multiAck != MultiAck.OFF)
            {
                PacketLineIn.AckNackResult anr = pckIn.readACK(ackId);
                resultsPending--;

                switch (anr)
                {
                case PacketLineIn.AckNackResult.NAK:
                    // A NAK is a response to an end we queued earlier
                    // we eat it and look for another ACK/NAK message.
                    //
                    break;

                case PacketLineIn.AckNackResult.ACK:
                    // A solitary ACK at this point means the remote won't
                    // speak anymore, but is going to send us a pack now.
                    //
                    goto END_READ_RESULT_2;

                case PacketLineIn.AckNackResult.ACK_CONTINUE:
                case PacketLineIn.AckNackResult.ACK_COMMON:
                case PacketLineIn.AckNackResult.ACK_READY:
                    // We will expect a normal ACK to break out of the loop.
                    //
                    _multiAck = MultiAck.CONTINUE;
                    break;
                }

                if (monitor.IsCancelled)
                {
                    throw new CancelledException();
                }
            }

END_READ_RESULT_2:
            ;
        }