1 /* 2 * Copyright (C) 2010, Google Inc. 3 * and other copyright owners as documented in the project's IP log. 4 * 5 * This program and the accompanying materials are made available 6 * under the terms of the Eclipse Distribution License v1.0 which 7 * accompanies this distribution, is reproduced below, and is 8 * available at http://www.eclipse.org/org/documents/edl-v10.php 9 * 10 * All rights reserved. 11 * 12 * Redistribution and use in source and binary forms, with or 13 * without modification, are permitted provided that the following 14 * conditions are met: 15 * 16 * - Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * 19 * - Redistributions in binary form must reproduce the above 20 * copyright notice, this list of conditions and the following 21 * disclaimer in the documentation and/or other materials provided 22 * with the distribution. 23 * 24 * - Neither the name of the Eclipse Foundation, Inc. nor the 25 * names of its contributors may be used to endorse or promote 26 * products derived from this software without specific prior 27 * written permission. 28 * 29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 30 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 31 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 32 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 33 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 34 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 35 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 36 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 37 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 38 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 40 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 41 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 42 */ 43 44 package org.eclipse.jgit.internal.storage.pack; 45 46 import java.io.IOException; 47 import java.util.Collection; 48 import java.util.List; 49 50 import org.eclipse.jgit.errors.MissingObjectException; 51 import org.eclipse.jgit.errors.StoredObjectRepresentationNotAvailableException; 52 import org.eclipse.jgit.lib.AnyObjectId; 53 import org.eclipse.jgit.lib.BitmapIndex.BitmapBuilder; 54 import org.eclipse.jgit.lib.ProgressMonitor; 55 56 /** 57 * Extension of {@link org.eclipse.jgit.lib.ObjectReader} that supports reusing 58 * objects in packs. 59 * <p> 60 * {@code ObjectReader} implementations may also optionally implement this 61 * interface to support 62 * {@link org.eclipse.jgit.internal.storage.pack.PackWriter} with a means of 63 * copying an object that is already in pack encoding format directly into the 64 * output stream, without incurring decompression and recompression overheads. 65 */ 66 public interface ObjectReuseAsIs { 67 /** 68 * Allocate a new {@code PackWriter} state structure for an object. 69 * <p> 70 * {@link org.eclipse.jgit.internal.storage.pack.PackWriter} allocates these 71 * objects to keep track of the per-object state, and how to load the 72 * objects efficiently into the generated stream. Implementers may subclass 73 * this type with additional object state, such as to remember what file and 74 * offset contains the object's pack encoded data. 75 * 76 * @param objectId 77 * the id of the object that will be packed. 78 * @param type 79 * the Git type of the object that will be packed. 80 * @return a new instance for this object. 81 */ 82 public ObjectToPack newObjectToPack(AnyObjectId objectId, int type); 83 84 /** 85 * Select the best object representation for a packer. 86 * <p> 87 * Implementations should iterate through all available representations of 88 * an object, and pass them in turn to the PackWriter though 89 * {@link org.eclipse.jgit.internal.storage.pack.PackWriter#select(ObjectToPack, StoredObjectRepresentation)} 90 * so the writer can select the most suitable representation to reuse into 91 * the output stream. 92 * <p> 93 * If the implementation returns CachedPack from 94 * {@link #getCachedPacksAndUpdate(BitmapBuilder)} it must consider the 95 * representation of any object that is stored in any of the offered 96 * CachedPacks. PackWriter relies on this behavior to prune duplicate 97 * objects out of the pack stream when it selects a CachedPack and the 98 * object was also reached through the thin-pack enumeration. 99 * <p> 100 * The implementation may choose to consider multiple objects at once on 101 * concurrent threads, but must evaluate all representations of an object 102 * within the same thread. 103 * 104 * @param packer 105 * the packer that will write the object in the near future. 106 * @param monitor 107 * progress monitor, implementation should update the monitor 108 * once for each item in the iteration when selection is done. 109 * @param objects 110 * the objects that are being packed. 111 * @throws org.eclipse.jgit.errors.MissingObjectException 112 * there is no representation available for the object, as it is 113 * no longer in the repository. Packing will abort. 114 * @throws java.io.IOException 115 * the repository cannot be accessed. Packing will abort. 116 */ 117 public void selectObjectRepresentation(PackWriter packer, 118 ProgressMonitor monitor, Iterable<ObjectToPack> objects) 119 throws IOException, MissingObjectException; 120 121 /** 122 * Write objects to the pack stream in roughly the order given. 123 * 124 * {@code PackWriter} invokes this method to write out one or more objects, 125 * in approximately the order specified by the iteration over the list. A 126 * simple implementation of this method would just iterate the list and 127 * output each object: 128 * 129 * <pre> 130 * for (ObjectToPack obj : list) 131 * out.writeObject(obj) 132 * </pre> 133 * 134 * However more sophisticated implementors may try to perform some (small) 135 * reordering to access objects that are stored close to each other at 136 * roughly the same time. Implementations may choose to write objects out of 137 * order, but this may increase pack file size due to using a larger header 138 * format to reach a delta base that is later in the stream. It may also 139 * reduce data locality for the reader, slowing down data access. 140 * 141 * Invoking 142 * {@link org.eclipse.jgit.internal.storage.pack.PackOutputStream#writeObject(ObjectToPack)} 143 * will cause 144 * {@link #copyObjectAsIs(PackOutputStream, ObjectToPack, boolean)} to be 145 * invoked recursively on {@code this} if the current object is scheduled 146 * for reuse. 147 * 148 * @param out 149 * the stream to write each object to. 150 * @param list 151 * the list of objects to write. Objects should be written in 152 * approximately this order. Implementors may resort the list 153 * elements in-place during writing if desired. 154 * @throws java.io.IOException 155 * the stream cannot be written to, or one or more required 156 * objects cannot be accessed from the object database. 157 */ 158 public void writeObjects(PackOutputStream out, List<ObjectToPack> list) 159 throws IOException; 160 161 /** 162 * Output a previously selected representation. 163 * <p> 164 * {@code PackWriter} invokes this method only if a representation 165 * previously given to it by {@code selectObjectRepresentation} was chosen 166 * for reuse into the output stream. The {@code otp} argument is an instance 167 * created by this reader's own {@code newObjectToPack}, and the 168 * representation data saved within it also originated from this reader. 169 * <p> 170 * Implementors must write the object header before copying the raw data to 171 * the output stream. The typical implementation is like: 172 * 173 * <pre> 174 * MyToPack mtp = (MyToPack) otp; 175 * byte[] raw; 176 * if (validate) 177 * raw = validate(mtp); // throw SORNAE here, if at all 178 * else 179 * raw = readFast(mtp); 180 * out.writeHeader(mtp, mtp.inflatedSize); 181 * out.write(raw); 182 * </pre> 183 * 184 * @param out 185 * stream the object should be written to. 186 * @param otp 187 * the object's saved representation information. 188 * @param validate 189 * if true the representation must be validated and not be 190 * corrupt before being reused. If false, validation may be 191 * skipped as it will be performed elsewhere in the processing 192 * pipeline. 193 * @throws org.eclipse.jgit.errors.StoredObjectRepresentationNotAvailableException 194 * the previously selected representation is no longer 195 * available. If thrown before {@code out.writeHeader} the pack 196 * writer will try to find another representation, and write 197 * that one instead. If throw after {@code out.writeHeader}, 198 * packing will abort. 199 * @throws java.io.IOException 200 * the stream's write method threw an exception. Packing will 201 * abort. 202 */ 203 public void copyObjectAsIs(PackOutputStream out, ObjectToPack otp, 204 boolean validate) throws IOException, 205 StoredObjectRepresentationNotAvailableException; 206 207 /** 208 * Append an entire pack's contents onto the output stream. 209 * <p> 210 * The entire pack, excluding its header and trailing footer is sent. 211 * 212 * @param out 213 * stream to append the pack onto. 214 * @param pack 215 * the cached pack to send. 216 * @throws java.io.IOException 217 * the pack cannot be read, or stream did not accept a write. 218 */ 219 public abstract void copyPackAsIs(PackOutputStream out, CachedPack pack) 220 throws IOException; 221 222 /** 223 * Obtain the available cached packs that match the bitmap and update 224 * the bitmap by removing the items that are in the CachedPack. 225 * <p> 226 * A cached pack has known starting points and may be sent entirely as-is, 227 * with almost no effort on the sender's part. 228 * 229 * @param needBitmap 230 * the bitmap that contains all of the objects the client wants. 231 * @return the available cached packs. 232 * @throws java.io.IOException 233 * the cached packs cannot be listed from the repository. 234 * Callers may choose to ignore this and continue as-if there 235 * were no cached packs. 236 */ 237 public Collection<CachedPack> getCachedPacksAndUpdate( 238 BitmapBuilder needBitmap) throws IOException; 239 }