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 }