public PackedObjectLoader UseLoader()
            {
                PackedObjectLoader r = _reuseLoader;

                _reuseLoader = null;
                return(r);
            }
        private void WriteDeltaObjectReuse(ObjectToPack otp, PackedObjectLoader reuse)
        {
            if (DeltaBaseAsOffset && otp.DeltaBase != null)
            {
                WriteObjectHeader(Constants.OBJ_OFS_DELTA, reuse.RawSize);

                ObjectToPack deltaBase  = otp.DeltaBase;
                long         offsetDiff = otp.Offset - deltaBase.Offset;
                int          localPos   = _buf.Length - 1;
                _buf[localPos] = (byte)(offsetDiff & 0x7F);
                while ((offsetDiff >>= 7) > 0)
                {
                    _buf[--localPos] = (byte)(0x80 | (--offsetDiff & 0x7F));
                }

                _pos.Write(_buf, localPos, _buf.Length - localPos);
            }
            else
            {
                WriteObjectHeader(Constants.OBJ_REF_DELTA, reuse.RawSize);
                otp.DeltaBaseId.copyRawTo(_buf, 0);
                _pos.Write(_buf, 0, Constants.OBJECT_ID_LENGTH);
            }

            reuse.CopyRawData(_pos, _buf, _windowCursor);
        }
        private void SelectDeltaReuseForObject(ObjectToPack otp, IEnumerable <PackedObjectLoader> loaders)
        {
            PackedObjectLoader bestLoader = null;
            ObjectId           bestBase   = null;

            foreach (PackedObjectLoader loader in loaders)
            {
                ObjectId idBase = loader.DeltaBase;
                if (idBase == null)
                {
                    continue;
                }
                ObjectToPack otpBase = _objectsMap.Get(idBase);

                if ((otpBase != null || (Thin && _edgeObjects.Get(idBase) != null)) && IsBetterDeltaReuseLoader(bestLoader, loader))
                {
                    bestLoader = loader;
                    bestBase   = (otpBase ?? idBase);
                }
            }

            if (bestLoader == null)
            {
                return;
            }

            otp.SetReuseLoader(bestLoader);
            otp.DeltaBaseId = bestBase;
        }
Beispiel #4
0
        public override void OpenObjectInAllPacksImplementation(ICollection <PackedObjectLoader> @out, WindowCursor windowCursor, AnyObjectId objectId)
        {
            PackList pList = _packList.get();

            while (true)
            {
SEARCH:
                foreach (PackFile p in pList.packs)
                {
                    try
                    {
                        PackedObjectLoader ldr = p.Get(windowCursor, objectId);
                        if (ldr != null)
                        {
                            @out.Add(ldr);
                        }
                    }
                    catch (PackMismatchException)
                    {
                        // Pack was modified; refresh the entire pack list.
                        //
                        pList = ScanPacks(pList);
                        goto SEARCH;
                    }
                    catch (IOException)
                    {
                        // Assume the pack is corrupted.
                        //
                        RemovePack(p);
                    }
                }

                break;
            }
        }
        private void WriteObject(ObjectToPack otp)
        {
            otp.MarkWantWrite();
            if (otp.IsDeltaRepresentation)
            {
                ObjectToPack deltaBase = otp.DeltaBase;
                Debug.Assert(deltaBase != null || Thin);
                if (deltaBase != null && !deltaBase.IsWritten)
                {
                    if (deltaBase.WantWrite)
                    {
                        otp.ClearDeltaBase();
                        otp.DisposeLoader();
                    }
                    else
                    {
                        WriteObject(deltaBase);
                    }
                }
            }

            Debug.Assert(!otp.IsWritten);

            _pos.resetCRC32();
            otp.Offset = _pos.Length;

            PackedObjectLoader reuse = Open(otp);

            if (reuse != null)
            {
                try
                {
                    if (otp.IsDeltaRepresentation)
                    {
                        WriteDeltaObjectReuse(otp, reuse);
                    }
                    else
                    {
                        WriteObjectHeader(otp.Type, reuse.Size);
                        reuse.CopyRawData(_pos, _buf, _windowCursor);
                    }
                }
                finally
                {
                    reuse.endCopyRawData();
                }
            }
            else if (otp.IsDeltaRepresentation)
            {
                throw new IOException("creating deltas is not implemented");
            }
            else
            {
                WriteWholeObjectDeflate(otp);
            }

            otp.CRC = _pos.getCRC32();
            _writeMonitor.Update(1);
        }
Beispiel #6
0
        public override PackedObjectLoader GetBaseLoader(WindowCursor curs)
        {
            PackedObjectLoader or = PackFile.Get(curs, _deltaBase);

            if (or == null)
            {
                throw new MissingObjectException(_deltaBase, "delta base");
            }
            return(or);
        }
        private static bool IsBetterDeltaReuseLoader(PackedObjectLoader currentLoader, PackedObjectLoader loader)
        {
            if (currentLoader == null)
            {
                return(true);
            }

            if (loader.RawSize < currentLoader.RawSize)
            {
                return(true);
            }

            return(loader.RawSize == currentLoader.RawSize &&
                   loader.SupportsFastCopyRawData &&
                   !currentLoader.SupportsFastCopyRawData);
        }
Beispiel #8
0
        public override void Materialize(WindowCursor curs)
        {
            if (curs == null)
            {
                throw new System.ArgumentNullException("curs");
            }

            if (CachedBytes != null)
            {
                return;
            }

            if (Type != ObjCommit)
            {
                UnpackedObjectCache.Entry cache = PackFile.readCache(DataOffset);
                if (cache != null)
                {
                    curs.Release();
                    Type        = cache.type;
                    Size        = cache.data.Length;
                    CachedBytes = cache.data;
                    return;
                }
            }

            try
            {
                PackedObjectLoader baseLoader = GetBaseLoader(curs);
                baseLoader.Materialize(curs);
                CachedBytes = BinaryDelta.Apply(baseLoader.CachedBytes, PackFile.decompress(DataOffset, _deltaSize, curs));
                curs.Release();
                Type = baseLoader.Type;
                Size = CachedBytes.Length;
                if (Type != ObjCommit)
                {
                    PackFile.saveCache(DataOffset, CachedBytes, Type);
                }
            }
            catch (IOException dfe)
            {
                throw new CorruptObjectException("object at " + DataOffset + " in "
                                                 + PackFile.File.FullName + " has bad zlib stream", dfe);
            }
        }
Beispiel #9
0
        internal void CopyRawData <T>(PackedObjectLoader loader, T @out, byte[] buf, WindowCursor cursor)
            where T : Stream
        {
            long objectOffset = loader.ObjectOffset;
            long dataOffset   = loader.DataOffset;
            var  cnt          = (int)(FindEndOffset(objectOffset) - dataOffset);

            if (LoadPackIndex().HasCRC32Support)
            {
                var crc       = new Crc32();
                var headerCnt = (int)(dataOffset - objectOffset);
                while (headerCnt > 0)
                {
                    int toRead = Math.Min(headerCnt, buf.Length);
                    ReadFully(objectOffset, buf, 0, toRead, cursor);
                    crc.Update(buf, 0, toRead);
                    headerCnt -= toRead;
                }
                var crcOut = new CheckedOutputStream(@out, crc);
                CopyToStream(dataOffset, buf, cnt, crcOut, cursor);
                long     computed = crc.Value;
                ObjectId id       = FindObjectForOffset(objectOffset);
                long     expected = LoadPackIndex().FindCRC32(id);
                if (computed != expected)
                {
                    throw new CorruptObjectException("object at " + dataOffset + " in " + File.FullName + " has bad zlib stream");
                }
            }
            else
            {
                try
                {
                    cursor.InflateVerify(this, dataOffset);
                }
                catch (Exception fe)                 // [henon] was DataFormatException
                {
                    throw new CorruptObjectException("object at " + dataOffset + " in " + File.FullName + " has bad zlib stream", fe);
                }

                CopyToStream(dataOffset, buf, cnt, @out, cursor);
            }
        }
Beispiel #10
0
        private PackedObjectLoader Open(ObjectToPack otp)
        {
            while (true)
            {
                PackedObjectLoader reuse = otp.UseLoader();
                if (reuse == null)
                {
                    return(null);
                }

                try
                {
                    reuse.beginCopyRawData();
                    return(reuse);
                }
                catch (IOException)
                {
                    otp.ClearDeltaBase();
                    SearchForReuse(new List <PackedObjectLoader>(), otp);
                    continue;
                }
            }
        }
Beispiel #11
0
        public override ObjectLoader openObject1(WindowCursor curs, AnyObjectId objectId)
        {
            PackList pList = _packList.get();

            while (true)
            {
SEARCH:
                foreach (PackFile p in pList.packs)
                {
                    try
                    {
                        PackedObjectLoader ldr = p.Get(curs, objectId);
                        if (ldr != null)
                        {
                            ldr.Materialize(curs);
                            return(ldr);
                        }
                    }
                    catch (PackMismatchException)
                    {
                        // Pack was modified; refresh the entire pack list.
                        //
                        pList = ScanPacks(pList);
                        goto SEARCH;
                    }
                    catch (IOException)
                    {
                        // Assume the pack is corrupted.
                        //
                        RemovePack(p);
                    }
                }

                return(null);
            }
        }
Beispiel #12
0
 public void SetReuseLoader(PackedObjectLoader reuseLoader)
 {
     _reuseLoader = reuseLoader;
 }
Beispiel #13
0
 public void DisposeLoader()
 {
     _reuseLoader = null;
 }