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; }
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); }
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); }
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); } }
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); } }
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; } } }
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); } }
public void SetReuseLoader(PackedObjectLoader reuseLoader) { _reuseLoader = reuseLoader; }
public void DisposeLoader() { _reuseLoader = null; }