1 /* 2 * Copyright (C) 2012, 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 11 package org.eclipse.jgit.internal.storage.file; 12 13 import java.io.File; 14 import java.io.IOException; 15 import java.io.InputStream; 16 import java.text.MessageFormat; 17 18 import org.eclipse.jgit.errors.CorruptObjectException; 19 import org.eclipse.jgit.internal.JGitText; 20 import org.eclipse.jgit.lib.AnyObjectId; 21 import org.eclipse.jgit.lib.ObjectId; 22 import org.eclipse.jgit.util.io.SilentFileInputStream; 23 24 import com.googlecode.javaewah.EWAHCompressedBitmap; 25 26 /** 27 * Logical representation of the bitmap data stored in the pack index. 28 * {@link org.eclipse.jgit.lib.ObjectId}s are encoded as a single integer in the 29 * range [0, {@link #getObjectCount()}). Compressed bitmaps are available at 30 * certain {@code ObjectId}s, which represent all of the objects reachable from 31 * that {@code ObjectId} (include the {@code ObjectId} itself). The meaning of 32 * the positions in the bitmaps can be decoded using {@link #getObject(int)} and 33 * {@link #ofObjectType(EWAHCompressedBitmap, int)}. Furthermore, 34 * {@link #findPosition(AnyObjectId)} can be used to build other bitmaps that a 35 * compatible with the encoded bitmaps available from the index. 36 */ 37 public abstract class PackBitmapIndex { 38 /** Flag bit denoting the bitmap should be reused during index creation. */ 39 public static final int FLAG_REUSE = 1; 40 41 /** 42 * Read an existing pack bitmap index file from a buffered stream. 43 * <p> 44 * The format of the file will be automatically detected and a proper access 45 * implementation for that format will be constructed and returned to the 46 * caller. The file may or may not be held open by the returned instance. 47 * 48 * @param idxFile 49 * existing pack .bitmap to read. 50 * @param packIndex 51 * the pack index for the corresponding pack file. 52 * @param reverseIndex 53 * the pack reverse index for the corresponding pack file. 54 * @return a copy of the index in-memory. 55 * @throws java.io.IOException 56 * the stream cannot be read. 57 * @throws CorruptObjectException 58 * the stream does not contain a valid pack bitmap index. 59 */ 60 public static PackBitmapIndex open(File idxFile, PackIndex packIndex, 61 PackReverseIndex reverseIndex) 62 throws IOException { 63 try (SilentFileInputStream fd = new SilentFileInputStream(idxFile)) { 64 try { 65 return read(fd, packIndex, reverseIndex); 66 } catch (IOException ioe) { 67 throw new IOException( 68 MessageFormat.format(JGitText.get().unreadablePackIndex, 69 idxFile.getAbsolutePath()), 70 ioe); 71 } 72 } 73 } 74 75 /** 76 * Read an existing pack bitmap index file from a buffered stream. 77 * <p> 78 * The format of the file will be automatically detected and a proper access 79 * implementation for that format will be constructed and returned to the 80 * caller. The file may or may not be held open by the returned instance. 81 * 82 * @param fd 83 * stream to read the bitmap index file from. The stream must be 84 * buffered as some small IOs are performed against the stream. 85 * The caller is responsible for closing the stream. 86 * @param packIndex 87 * the pack index for the corresponding pack file. 88 * @param reverseIndex 89 * the pack reverse index for the corresponding pack file. 90 * @return a copy of the index in-memory. 91 * @throws java.io.IOException 92 * the stream cannot be read. 93 * @throws CorruptObjectException 94 * the stream does not contain a valid pack bitmap index. 95 */ 96 public static PackBitmapIndex read(InputStream fd, PackIndex packIndex, 97 PackReverseIndex reverseIndex) throws IOException { 98 return new PackBitmapIndexV1(fd, packIndex, reverseIndex); 99 } 100 101 /** 102 * Read an existing pack bitmap index file from a buffered stream. 103 * <p> 104 * The format of the file will be automatically detected and a proper access 105 * implementation for that format will be constructed and returned to the 106 * caller. The file may or may not be held open by the returned instance. 107 * 108 * @param fd 109 * stream to read the bitmap index file from. The stream must be 110 * buffered as some small IOs are performed against the stream. 111 * The caller is responsible for closing the stream. 112 * @param packIndexSupplier 113 * the supplier for pack index for the corresponding pack file. 114 * @param reverseIndexSupplier 115 * the supplier for pack reverse index for the corresponding pack 116 * file. 117 * @param loadParallelRevIndex 118 * whether reverse index should be loaded in parallel 119 * @return a copy of the index in-memory. 120 * @throws java.io.IOException 121 * the stream cannot be read. 122 * @throws CorruptObjectException 123 * the stream does not contain a valid pack bitmap index. 124 */ 125 public static PackBitmapIndex read(InputStream fd, 126 SupplierWithIOException<PackIndex> packIndexSupplier, 127 SupplierWithIOException<PackReverseIndex> reverseIndexSupplier, 128 boolean loadParallelRevIndex) 129 throws IOException { 130 return new PackBitmapIndexV1(fd, packIndexSupplier, 131 reverseIndexSupplier, loadParallelRevIndex); 132 } 133 134 /** Footer checksum applied on the bottom of the pack file. */ 135 byte[] packChecksum; 136 137 /** 138 * Finds the position in the bitmap of the object. 139 * 140 * @param objectId 141 * the id for which the bitmap position will be found. 142 * @return the bitmap id or -1 if the object was not found. 143 */ 144 public abstract int findPosition(AnyObjectId objectId); 145 146 /** 147 * Get the object at the bitmap position. 148 * 149 * @param position 150 * the id for which the object will be found. 151 * @return the ObjectId. 152 * @throws java.lang.IllegalArgumentException 153 * when the item is not found. 154 */ 155 public abstract ObjectId getObject(int position) 156 throws IllegalArgumentException; 157 158 /** 159 * Returns a bitmap containing positions for objects that have the given Git 160 * type. 161 * 162 * @param bitmap 163 * the object bitmap. 164 * @param type 165 * the Git type. 166 * @return the object bitmap with only objects of the Git type. 167 */ 168 public abstract EWAHCompressedBitmap ofObjectType( 169 EWAHCompressedBitmap bitmap, int type); 170 171 /** 172 * Returns the previously constructed bitmap for the object. 173 * 174 * @param objectId 175 * the id for which the bitmap will be found. 176 * @return the bitmap or null if the object was not found. 177 */ 178 public abstract EWAHCompressedBitmap getBitmap(AnyObjectId objectId); 179 180 /** 181 * Obtain the total number of objects described by this index. 182 * {@code getObjectCount() - 1} is the largest bit that will be set in a 183 * bitmap. 184 * 185 * @return number of objects in this index, and likewise in the associated 186 * pack that this index was generated from. 187 */ 188 public abstract int getObjectCount(); 189 190 /** 191 * Returns the number of bitmaps in this bitmap index. 192 * 193 * @return the number of bitmaps in this bitmap index. 194 */ 195 public abstract int getBitmapCount(); 196 197 /** 198 * Supplier that propagates IOException. 199 * 200 * @param <T> 201 * the return type which is expected from {@link #get()} 202 */ 203 @FunctionalInterface 204 public interface SupplierWithIOException<T> { 205 /** 206 * @return result 207 * @throws IOException 208 */ 209 T get() throws IOException; 210 } 211 }