private void CacheDelta(ObjectToPack srcObj, ObjectToPack resObj) { if (int.MaxValue < bestDelta.Length()) { return; } int rawsz = (int)bestDelta.Length(); if (deltaCache.CanCache(rawsz, srcObj, resObj)) { try { byte[] zbuf = new byte[DeflateBound(rawsz)]; DeltaWindow.ZipStream zs = new DeltaWindow.ZipStream(Deflater(), zbuf); bestDelta.WriteTo(zs, null); bestDelta = null; int len = zs.Finish(); resObj.SetCachedDelta(deltaCache.Cache(zbuf, len, rawsz)); resObj.SetCachedSize(rawsz); } catch (IOException) { deltaCache.Credit(rawsz); } catch (OutOfMemoryException) { deltaCache.Credit(rawsz); } } }
/// <summary>Commits the object header onto the stream.</summary> /// <remarks> /// Commits the object header onto the stream. /// <p> /// Once the header has been written, the object representation must be fully /// output, or packing must abort abnormally. /// </remarks> /// <param name="otp">the object to pack. Header information is obtained.</param> /// <param name="rawLength"> /// number of bytes of the inflated content. For an object that is /// in whole object format, this is the same as the object size. /// For an object that is in a delta format, this is the size of /// the inflated delta instruction stream. /// </param> /// <exception cref="System.IO.IOException">the underlying stream refused to accept the header. /// </exception> public void WriteHeader(ObjectToPack otp, long rawLength) { if (otp.IsDeltaRepresentation()) { if (packWriter.IsDeltaBaseAsOffset()) { ObjectToPack baseInPack = otp.GetDeltaBase(); if (baseInPack != null && baseInPack.IsWritten()) { long start = count; int n = EncodeTypeSize(Constants.OBJ_OFS_DELTA, rawLength); Write(headerBuffer, 0, n); long offsetDiff = start - baseInPack.GetOffset(); n = headerBuffer.Length - 1; headerBuffer[n] = unchecked ((byte)(offsetDiff & unchecked ((int)(0x7F)))); while ((offsetDiff >>= 7) > 0) { headerBuffer[--n] = unchecked ((byte)(unchecked ((int)(0x80)) | (--offsetDiff & unchecked ( (int)(0x7F))))); } Write(headerBuffer, n, headerBuffer.Length - n); return; } } int n_1 = EncodeTypeSize(Constants.OBJ_REF_DELTA, rawLength); otp.GetDeltaBaseId().CopyRawTo(headerBuffer, n_1); Write(headerBuffer, 0, n_1 + Constants.OBJECT_ID_LENGTH); } else { int n = EncodeTypeSize(otp.GetType(), rawLength); Write(headerBuffer, 0, n); } }
internal virtual bool CanCache(int length, ObjectToPack src, ObjectToPack res) { // If the cache would overflow, don't store. // if (0 < size && size < used + length) { CheckForGarbageCollectedObjects(); if (0 < size && size < used + length) { return(false); } } if (length < entryLimit) { used += length; return(true); } // If the combined source files are multiple megabytes but the delta // is on the order of a kilobyte or two, this was likely costly to // construct. Cache it anyway, even though its over the limit. // if (length >> 10 < (src.GetWeight() >> 20) + (res.GetWeight() >> 21)) { used += length; return(true); } return(false); }
internal override bool CanCache(int length, ObjectToPack src, ObjectToPack res) { Lock.Lock(); try { return(base.CanCache(length, src, res)); } finally { Lock.Unlock(); } }
private void Add(AnyObjectId id, int objectType, int pathHash) { ObjectToPack obj = new ObjectToPack(id, objectType); obj.SetEdge(); obj.SetPathHash(pathHash); if (objectsMap.AddIfAbsent(obj) == obj) { edgeObjects.AddItem(obj); progress.Update(1); } }
internal override bool CanCache(int length, ObjectToPack src, ObjectToPack res) { Lock.Lock(); try { return base.CanCache(length, src, res); } finally { Lock.Unlock(); } }
/// <exception cref="System.IO.IOException"></exception> internal override void SelectObjectRepresentation(PackWriter packer, ObjectToPack otp, WindowCursor curs) { ObjectDirectory.PackList pList = packList.Get(); for (; ; ) { foreach (PackFile p in pList.packs) { try { LocalObjectRepresentation rep = p.Representation(curs, otp); if (rep != null) { packer.Select(otp, rep); } } catch (PackMismatchException) { // Pack was modified; refresh the entire pack list. // pList = ScanPacks(pList); goto SEARCH_continue; } catch (IOException) { // Assume the pack is corrupted. // RemovePack(p); } } goto SEARCH_break; SEARCH_continue: ; } SEARCH_break: ; foreach (FileObjectDatabase.AlternateHandle h in MyAlternates()) { h.db.SelectObjectRepresentation(packer, otp, curs); } }
/// <summary>Determine if this pack contains the object representation given.</summary> /// <remarks> /// Determine if this pack contains the object representation given. /// <p> /// PackWriter uses this method during the finding sources phase to prune /// away any objects from the leading thin-pack that already appear within /// this pack and should not be sent twice. /// <p> /// Implementors are strongly encouraged to rely on looking at /// <code>rep</code> /// only and using its internal state to decide if this object is within this /// pack. Implementors should ensure a representation from this cached pack /// is tested as part of /// <see cref="ObjectReuseAsIs.SelectObjectRepresentation(PackWriter, NGit.ProgressMonitor, Sharpen.Iterable{T}) /// ">ObjectReuseAsIs.SelectObjectRepresentation(PackWriter, NGit.ProgressMonitor, Sharpen.Iterable<T>) /// </see> /// , ensuring this method would eventually return true if the object would /// be included by this cached pack. /// </remarks> /// <param name="obj">the object being packed. Can be used as an ObjectId.</param> /// <param name="rep"> /// representation from the /// <see cref="ObjectReuseAsIs">ObjectReuseAsIs</see> /// instance that /// originally supplied this CachedPack. /// </param> /// <returns>true if this pack contains this object.</returns> public abstract bool HasObject(ObjectToPack obj, StoredObjectRepresentation rep);
/// <summary>Commits the object header onto the stream.</summary> /// <remarks> /// Commits the object header onto the stream. /// <p> /// Once the header has been written, the object representation must be fully /// output, or packing must abort abnormally. /// </remarks> /// <param name="otp">the object to pack. Header information is obtained.</param> /// <param name="rawLength"> /// number of bytes of the inflated content. For an object that is /// in whole object format, this is the same as the object size. /// For an object that is in a delta format, this is the size of /// the inflated delta instruction stream. /// </param> /// <exception cref="System.IO.IOException">the underlying stream refused to accept the header. /// </exception> public void WriteHeader(ObjectToPack otp, long rawLength) { if (otp.IsDeltaRepresentation()) { if (packWriter.IsDeltaBaseAsOffset()) { ObjectToPack baseInPack = otp.GetDeltaBase(); if (baseInPack != null && baseInPack.IsWritten()) { long start = count; int n = EncodeTypeSize(Constants.OBJ_OFS_DELTA, rawLength); Write(headerBuffer, 0, n); long offsetDiff = start - baseInPack.GetOffset(); n = headerBuffer.Length - 1; headerBuffer[n] = unchecked((byte)(offsetDiff & unchecked((int)(0x7F)))); while ((offsetDiff >>= 7) > 0) { headerBuffer[--n] = unchecked((byte)(unchecked((int)(0x80)) | (--offsetDiff & unchecked( (int)(0x7F))))); } Write(headerBuffer, n, headerBuffer.Length - n); return; } } int n_1 = EncodeTypeSize(Constants.OBJ_REF_DELTA, rawLength); otp.GetDeltaBaseId().CopyRawTo(headerBuffer, n_1); Write(headerBuffer, 0, n_1 + Constants.OBJECT_ID_LENGTH); } else { int n = EncodeTypeSize(otp.GetType(), rawLength); Write(headerBuffer, 0, n); } }
/// <summary>Write one object.</summary> /// <remarks> /// Write one object. /// If the object was already written, this method does nothing and returns /// quickly. This case occurs whenever an object was written out of order in /// order to ensure the delta base occurred before the object that needs it. /// </remarks> /// <param name="otp">the object to write.</param> /// <exception cref="System.IO.IOException"> /// the object cannot be read from the object reader, or the /// output stream is no longer accepting output. Caller must /// examine the type of exception and possibly its message to /// distinguish between these cases. /// </exception> public void WriteObject(ObjectToPack otp) { packWriter.WriteObject(this, otp); }
public override bool HasObject(ObjectToPack obj, StoredObjectRepresentation rep) { try { LocalObjectRepresentation local = (LocalObjectRepresentation)rep; foreach (PackFile pack in GetPacks()) { if (local.pack == pack) { return true; } } return false; } catch (FileNotFoundException) { return false; } }
private static long EstimateSize(ObjectToPack ent) { return DeltaIndex.EstimateIndexSize(ent.GetWeight()); }
/// <exception cref="System.IO.IOException"></exception> internal override void SelectObjectRepresentation(PackWriter packer, ObjectToPack otp, WindowCursor curs) { wrapped.SelectObjectRepresentation(packer, otp, curs); }
/// <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(); }
/// <exception cref="System.IO.IOException"></exception> internal abstract void SelectObjectRepresentation(PackWriter packer, ObjectToPack otp, WindowCursor curs);
private static long EstimateSize(ObjectToPack ent) { return(DeltaIndex.EstimateIndexSize(ent.GetWeight())); }
/// <exception cref="System.IO.IOException"></exception> /// <exception cref="NGit.Errors.StoredObjectRepresentationNotAvailableException"></exception> public void CopyObjectAsIs(PackOutputStream @out, ObjectToPack otp) { LocalObjectToPack src = (LocalObjectToPack)otp; src.pack.CopyAsIs(@out, src, this); }
internal virtual void Set(ObjectToPack @object) { this.@object = @object; this.index = null; this.buffer = null; }
/// <exception cref="System.IO.IOException"></exception> internal virtual void Search(ProgressMonitor monitor, ObjectToPack[] toSearch, int off, int cnt) { try { for (int end = off + cnt; off < end; off++) { res = window[resSlot]; if (0 < maxMemory) { Clear(res); int tail = Next(resSlot); long need = EstimateSize(toSearch[off]); while (maxMemory < loaded + need && tail != resSlot) { Clear(window[tail]); tail = Next(tail); } } res.Set(toSearch[off]); if ([email protected]()) { // We don't actually want to make a delta for // them, just need to push them into the window // so they can be read by other objects. // KeepInWindow(); } else { // Search for a delta for the current window slot. // monitor.Update(1); Search(); } } } finally { if (deflater != null) { deflater.Finish(); } } }
/// <summary>Construct an error for an object.</summary> /// <remarks>Construct an error for an object.</remarks> /// <param name="otp">the object whose current representation is no longer present.</param> public StoredObjectRepresentationNotAvailableException(ObjectToPack otp) { }