internal static DeltaBaseCache.Entry Get(PackFile pack, long position) { lock (typeof(DeltaBaseCache)) { DeltaBaseCache.Slot e = cache[Hash(position)]; if (e.provider == pack && e.position == position) { DeltaBaseCache.Entry buf = e.data.Get(); if (buf != null) { MoveToHead(e); return(buf); } } return(null); } }
internal virtual DeltaBaseCache.Entry Get(PackFile pack, long position) { DeltaBaseCache.Slot e = cache[Hash(position)]; if (e == null) { return(null); } if (e.provider == pack && e.position == position) { DeltaBaseCache.Entry buf = e.data.Get(); if (buf != null) { MoveToHead(e); return(buf); } } return(null); }
/// <exception cref="System.IO.IOException"></exception> internal virtual ObjectLoader Load(WindowCursor curs, long pos) { try { byte[] ib = curs.tempId; PackFile.Delta delta = null; byte[] data = null; int type = Constants.OBJ_BAD; bool cached = false; for (; ;) { ReadFully(pos, ib, 0, 20, curs); int c = ib[0] & unchecked ((int)(0xff)); int typeCode = (c >> 4) & 7; long sz = c & 15; int shift = 4; int p = 1; while ((c & unchecked ((int)(0x80))) != 0) { c = ib[p++] & unchecked ((int)(0xff)); sz += ((long)(c & unchecked ((int)(0x7f)))) << shift; shift += 7; } switch (typeCode) { case Constants.OBJ_COMMIT: case Constants.OBJ_TREE: case Constants.OBJ_BLOB: case Constants.OBJ_TAG: { if (sz < curs.GetStreamFileThreshold()) { data = Decompress(pos + p, (int)sz, curs); } if (delta != null) { type = typeCode; goto SEARCH_break; } if (data != null) { return(new ObjectLoader.SmallObject(typeCode, data)); } else { return(new LargePackedWholeObject(typeCode, sz, pos, p, this, curs.db)); } goto case Constants.OBJ_OFS_DELTA; } case Constants.OBJ_OFS_DELTA: { c = ib[p++] & unchecked ((int)(0xff)); long @base = c & 127; while ((c & 128) != 0) { @base += 1; c = ib[p++] & unchecked ((int)(0xff)); @base <<= 7; @base += (c & 127); } @base = pos - @base; delta = new PackFile.Delta(delta, pos, (int)sz, p, @base); if (sz != delta.deltaSize) { goto SEARCH_break; } DeltaBaseCache.Entry e = curs.GetDeltaBaseCache().Get(this, @base); if (e != null) { type = e.type; data = e.data; cached = true; goto SEARCH_break; } pos = @base; goto SEARCH_continue; } case Constants.OBJ_REF_DELTA: { ReadFully(pos + p, ib, 0, 20, curs); long @base = FindDeltaBase(ObjectId.FromRaw(ib)); delta = new PackFile.Delta(delta, pos, (int)sz, p + 20, @base); if (sz != delta.deltaSize) { goto SEARCH_break; } DeltaBaseCache.Entry e = curs.GetDeltaBaseCache().Get(this, @base); if (e != null) { type = e.type; data = e.data; cached = true; goto SEARCH_break; } pos = @base; goto SEARCH_continue; } default: { throw new IOException(MessageFormat.Format(JGitText.Get().unknownObjectType, Sharpen.Extensions.ValueOf (typeCode))); } } SEARCH_continue :; } SEARCH_break :; // At this point there is at least one delta to apply to data. // (Whole objects with no deltas to apply return early above.) if (data == null) { return(delta.Large(this, curs)); } do { // Cache only the base immediately before desired object. if (cached) { cached = false; } else { if (delta.next == null) { curs.GetDeltaBaseCache().Store(this, delta.basePos, data, type); } } pos = delta.deltaPos; byte[] cmds = Decompress(pos + delta.hdrLen, delta.deltaSize, curs); if (cmds == null) { data = null; // Discard base in case of OutOfMemoryError return(delta.Large(this, curs)); } long sz = BinaryDelta.GetResultSize(cmds); if (int.MaxValue <= sz) { return(delta.Large(this, curs)); } byte[] result; try { result = new byte[(int)sz]; } catch (OutOfMemoryException) { data = null; // Discard base in case of OutOfMemoryError return(delta.Large(this, curs)); } BinaryDelta.Apply(data, cmds, result); data = result; delta = delta.next; }while (delta != null); return(new ObjectLoader.SmallObject(type, data)); } catch (SharpZipBaseException dfe) { CorruptObjectException coe = new CorruptObjectException(MessageFormat.Format(JGitText .Get().objectAtHasBadZlibStream, Sharpen.Extensions.ValueOf(pos), GetPackFile()) ); Sharpen.Extensions.InitCause(coe, dfe); throw coe; } }