Example #1
0
 // We should drop the current source entry from the window,
 // it is somehow invalid for us to work with.
 private bool IsBetterDelta(DeltaWindowEntry src, TemporaryBuffer.Heap resDelta)
 {
     if (bestDelta == null)
     {
         return(true);
     }
     // If both delta sequences are the same length, use the one
     // that has a shorter delta chain since it would be faster
     // to access during reads.
     //
     if (resDelta.Length() == bestDelta.Length())
     {
         return(src.Depth() < window[bestSlot].Depth());
     }
     return(resDelta.Length() < bestDelta.Length());
 }
Example #2
0
        private static int DeltaSizeLimit(DeltaWindowEntry res, int maxDepth, DeltaWindowEntry
                                          src)
        {
            // Ideally the delta is at least 50% of the original size,
            // but we also want to account for delta header overhead in
            // the pack file (to point to the delta base) so subtract off
            // some of those header bytes from the limit.
            //
            int limit = res.Size() / 2 - 20;
            // Distribute the delta limit over the entire chain length.
            // This is weighted such that deeper items in the chain must
            // be even smaller than if they were earlier in the chain, as
            // they cost significantly more to unpack due to the increased
            // number of recursive unpack calls.
            //
            int remainingDepth = maxDepth - src.Depth();

            return((limit * remainingDepth) / maxDepth);
        }
Example #3
0
 // We should drop the current source entry from the window,
 // it is somehow invalid for us to work with.
 private bool IsBetterDelta(DeltaWindowEntry src, TemporaryBuffer.Heap resDelta)
 {
     if (bestDelta == null)
     {
         return true;
     }
     // If both delta sequences are the same length, use the one
     // that has a shorter delta chain since it would be faster
     // to access during reads.
     //
     if (resDelta.Length() == bestDelta.Length())
     {
         return src.Depth() < window[bestSlot].Depth();
     }
     return resDelta.Length() < bestDelta.Length();
 }
Example #4
0
 /// <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;
 }
Example #5
0
        private static int DeltaSizeLimit(DeltaWindowEntry res, int maxDepth, DeltaWindowEntry
			 src)
        {
            // Ideally the delta is at least 50% of the original size,
            // but we also want to account for delta header overhead in
            // the pack file (to point to the delta base) so subtract off
            // some of those header bytes from the limit.
            //
            int limit = res.Size() / 2 - 20;
            // Distribute the delta limit over the entire chain length.
            // This is weighted such that deeper items in the chain must
            // be even smaller than if they were earlier in the chain, as
            // they cost significantly more to unpack due to the increased
            // number of recursive unpack calls.
            //
            int remainingDepth = maxDepth - src.Depth();
            return (limit * remainingDepth) / maxDepth;
        }
Example #6
0
        /// <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);
        }