Exemplo n.º 1
0
 /// <exception cref="System.IO.IOException"></exception>
 private static PacketLineIn AsPacketLineIn(TemporaryBuffer.Heap buf)
 {
     return(new PacketLineIn(new ByteArrayInputStream(buf.ToByteArray())));
 }
        /// <exception cref="System.IO.IOException"></exception>
        private int Delta(DeltaWindowEntry src, int srcSlot)
        {
            // Objects must use only the same type as their delta base.
            // If we are looking at something where that isn't true we
            // have exhausted everything of the correct type and should
            // move on to the next thing to examine.
            //
            if (src.Type() != res.Type())
            {
                KeepInWindow();
                return(NEXT_RES);
            }
            // Only consider a source with a short enough delta chain.
            if (src.Depth() > resMaxDepth)
            {
                return(NEXT_SRC);
            }
            // Estimate a reasonable upper limit on delta size.
            int msz = DeltaSizeLimit(res, resMaxDepth, src);

            if (msz <= 8)
            {
                return(NEXT_SRC);
            }
            // If we have to insert a lot to make this work, find another.
            if (res.Size() - src.Size() > msz)
            {
                return(NEXT_SRC);
            }
            // If the sizes are radically different, this is a bad pairing.
            if (res.Size() < src.Size() / 16)
            {
                return(NEXT_SRC);
            }
            DeltaIndex srcIndex;

            try
            {
                srcIndex = Index(src);
            }
            catch (LargeObjectException)
            {
                // If the source is too big to work on, skip it.
                DropFromWindow(srcSlot);
                return(NEXT_SRC);
            }
            catch (IOException notAvailable)
            {
                if ([email protected]())
                {
                    // This is an edge that is suddenly not available.
                    DropFromWindow(srcSlot);
                    return(NEXT_SRC);
                }
                else
                {
                    throw;
                }
            }
            byte[] resBuf;
            try
            {
                resBuf = Buffer(res);
            }
            catch (LargeObjectException)
            {
                // If its too big, move on to another item.
                return(NEXT_RES);
            }
            // If we already have a delta for the current object, abort
            // encoding early if this new pairing produces a larger delta.
            if (bestDelta != null && bestDelta.Length() < msz)
            {
                msz = (int)bestDelta.Length();
            }
            TemporaryBuffer.Heap delta = new TemporaryBuffer.Heap(msz);
            try
            {
                if (!srcIndex.Encode(delta, resBuf, msz))
                {
                    return(NEXT_SRC);
                }
            }
            catch (IOException)
            {
                // This only happens when the heap overflows our limit.
                return(NEXT_SRC);
            }
            if (IsBetterDelta(src, delta))
            {
                bestDelta = delta;
                bestSlot  = srcSlot;
            }
            return(NEXT_SRC);
        }
Exemplo n.º 3
0
 /// <exception cref="System.IO.IOException"></exception>
 private void Receive(ReceivePack rp, TemporaryBuffer.Heap inBuf, TemporaryBuffer.Heap
                      outBuf)
 {
     rp.Receive(new ByteArrayInputStream(inBuf.ToByteArray()), outBuf, null);
 }
        /// <exception cref="System.IO.IOException"></exception>
        private void Search()
        {
            // TODO(spearce) If the object is used as a base for other
            // objects in this pack we should limit the depth we create
            // for ourselves to be the remainder of our longest dependent
            // chain and the configured maximum depth. This can happen
            // when the dependents are being reused out a pack, but we
            // cannot be because we are near the edge of a thin pack.
            //
            resMaxDepth = maxDepth;
            // Loop through the window backwards, considering every entry.
            // This lets us look at the bigger objects that came before.
            //
            for (int srcSlot = Prior(resSlot); srcSlot != resSlot; srcSlot = Prior(srcSlot))
            {
                DeltaWindowEntry src = window[srcSlot];
                if (src.Empty())
                {
                    break;
                }
                if (Delta(src, srcSlot) == NEXT_RES)
                {
                    bestDelta = null;
                    return;
                }
            }
            // We couldn't find a suitable delta for this object, but it may
            // still be able to act as a base for another one.
            //
            if (bestDelta == null)
            {
                KeepInWindow();
                return;
            }
            // Select this best matching delta as the base for the object.
            //
            ObjectToPack srcObj = window[bestSlot].@object;
            ObjectToPack resObj = res.@object;

            if (srcObj.IsEdge())
            {
                // The source (the delta base) is an edge object outside of the
                // pack. Its part of the common base set that the peer already
                // has on hand, so we don't want to send it. We have to store
                // an ObjectId and *NOT* an ObjectToPack for the base to ensure
                // the base isn't included in the outgoing pack file.
                //
                resObj.SetDeltaBase(srcObj.Copy());
            }
            else
            {
                // The base is part of the pack we are sending, so it should be
                // a direct pointer to the base.
                //
                resObj.SetDeltaBase(srcObj);
            }
            resObj.SetDeltaDepth(srcObj.GetDeltaDepth() + 1);
            resObj.ClearReuseAsIs();
            CacheDelta(srcObj, resObj);
            // Discard the cached best result, otherwise it leaks.
            //
            bestDelta = null;
            // If this should be the end of a chain, don't keep
            // it in the window. Just move on to the next object.
            //
            if (resObj.GetDeltaDepth() == maxDepth)
            {
                return;
            }
            ShuffleBaseUpInPriority();
            KeepInWindow();
        }