LargePackedWholeObject.java

  1. /*
  2.  * Copyright (C) 2010, Google Inc. and others
  3.  *
  4.  * This program and the accompanying materials are made available under the
  5.  * terms of the Eclipse Distribution License v. 1.0 which is available at
  6.  * https://www.eclipse.org/org/documents/edl-v10.php.
  7.  *
  8.  * SPDX-License-Identifier: BSD-3-Clause
  9.  */

  10. package org.eclipse.jgit.internal.storage.dfs;

  11. import java.io.BufferedInputStream;
  12. import java.io.IOException;
  13. import java.io.InputStream;
  14. import java.util.zip.InflaterInputStream;

  15. import org.eclipse.jgit.errors.LargeObjectException;
  16. import org.eclipse.jgit.errors.MissingObjectException;
  17. import org.eclipse.jgit.lib.ObjectId;
  18. import org.eclipse.jgit.lib.ObjectLoader;
  19. import org.eclipse.jgit.lib.ObjectStream;

  20. final class LargePackedWholeObject extends ObjectLoader {
  21.     private final int type;

  22.     private final long size;

  23.     private final long objectOffset;

  24.     private final int headerLength;

  25.     private final DfsPackFile pack;

  26.     private final DfsObjDatabase db;

  27.     LargePackedWholeObject(int type, long size, long objectOffset,
  28.             int headerLength, DfsPackFile pack, DfsObjDatabase db) {
  29.         this.type = type;
  30.         this.size = size;
  31.         this.objectOffset = objectOffset;
  32.         this.headerLength = headerLength;
  33.         this.pack = pack;
  34.         this.db = db;
  35.     }

  36.     /** {@inheritDoc} */
  37.     @Override
  38.     public int getType() {
  39.         return type;
  40.     }

  41.     /** {@inheritDoc} */
  42.     @Override
  43.     public long getSize() {
  44.         return size;
  45.     }

  46.     /** {@inheritDoc} */
  47.     @Override
  48.     public boolean isLarge() {
  49.         return true;
  50.     }

  51.     /** {@inheritDoc} */
  52.     @Override
  53.     public byte[] getCachedBytes() throws LargeObjectException {
  54.         throw new LargeObjectException();
  55.     }

  56.     /** {@inheritDoc} */
  57.     @Override
  58.     public ObjectStream openStream() throws MissingObjectException, IOException {
  59.         PackInputStream packIn;
  60.         // ctx is closed by PackInputStream, or explicitly in the finally block
  61.         DfsReader ctx = db.newReader();
  62.         try {
  63.             try {
  64.                 packIn = new PackInputStream(
  65.                         pack, objectOffset + headerLength, ctx);
  66.                 ctx = null; // owned by packIn
  67.             } catch (IOException packGone) {
  68.                 // If the pack file cannot be pinned into the cursor, it
  69.                 // probably was repacked recently. Go find the object
  70.                 // again and open the stream from that location instead.
  71.                 ObjectId obj = pack.getReverseIdx(ctx).findObject(objectOffset);
  72.                 return ctx.open(obj, type).openStream();
  73.             }
  74.         } finally {
  75.             if (ctx != null) {
  76.                 ctx.close();
  77.             }
  78.         }

  79.         // Align buffer to inflater size, at a larger than default block.
  80.         // This reduces the number of context switches from the
  81.         // caller down into the pack stream inflation.
  82.         int bufsz = 8192;
  83.         InputStream in = new BufferedInputStream(
  84.                 new InflaterInputStream(packIn, packIn.ctx.inflater(), bufsz),
  85.                 bufsz);
  86.         return new ObjectStream.Filter(type, size, in);
  87.     }
  88. }