aboutsummaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndex.java
blob: cbda8fc77c1d24b90d07b249f0e245df87f67368 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
/*
 * Copyright (C) 2012, Google Inc. and others
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Distribution License v. 1.0 which is available at
 * https://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

package org.eclipse.jgit.internal.storage.file;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.text.MessageFormat;
import java.util.function.Supplier;

import org.eclipse.jgit.errors.CorruptObjectException;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.util.io.SilentFileInputStream;

import com.googlecode.javaewah.EWAHCompressedBitmap;

/**
 * Logical representation of the bitmap data stored in the pack index.
 * {@link org.eclipse.jgit.lib.ObjectId}s are encoded as a single integer in the
 * range [0, {@link #getObjectCount()}). Compressed bitmaps are available at
 * certain {@code ObjectId}s, which represent all of the objects reachable from
 * that {@code ObjectId} (include the {@code ObjectId} itself). The meaning of
 * the positions in the bitmaps can be decoded using {@link #getObject(int)} and
 * {@link #ofObjectType(EWAHCompressedBitmap, int)}. Furthermore,
 * {@link #findPosition(AnyObjectId)} can be used to build other bitmaps that a
 * compatible with the encoded bitmaps available from the index.
 */
public interface PackBitmapIndex {
	/** Flag bit denoting the bitmap should be reused during index creation. */
	public static final int FLAG_REUSE = 1;

	/**
	 * Read an existing pack bitmap index file from a buffered stream.
	 * <p>
	 * The format of the file will be automatically detected and a proper access
	 * implementation for that format will be constructed and returned to the
	 * caller. The file may or may not be held open by the returned instance.
	 *
	 * @param idxFile
	 *            existing pack .bitmap to read.
	 * @param packIndex
	 *            the pack index for the corresponding pack file.
	 * @param reverseIndex
	 *            the pack reverse index for the corresponding pack file.
	 * @return a copy of the index in-memory.
	 * @throws java.io.IOException
	 *             the stream cannot be read.
	 * @throws CorruptObjectException
	 *             the stream does not contain a valid pack bitmap index.
	 */
	public static PackBitmapIndex open(File idxFile, PackIndex packIndex,
			PackReverseIndex reverseIndex)
			throws IOException {
		try (SilentFileInputStream fd = new SilentFileInputStream(idxFile)) {
			try {
				return read(fd, packIndex, reverseIndex);
			} catch (IOException ioe) {
				throw new IOException(
						MessageFormat.format(JGitText.get().unreadablePackIndex,
								idxFile.getAbsolutePath()),
						ioe);
			}
		}
	}

	/**
	 * Read an existing pack bitmap index file from a buffered stream.
	 * <p>
	 * The format of the file will be automatically detected and a proper access
	 * implementation for that format will be constructed and returned to the
	 * caller. The file may or may not be held open by the returned instance.
	 *
	 * @param fd
	 *            stream to read the bitmap index file from. The stream must be
	 *            buffered as some small IOs are performed against the stream.
	 *            The caller is responsible for closing the stream.
	 * @param packIndex
	 *            the pack index for the corresponding pack file.
	 * @param reverseIndex
	 *            the pack reverse index for the corresponding pack file.
	 * @return a copy of the index in-memory.
	 * @throws java.io.IOException
	 *             the stream cannot be read.
	 * @throws CorruptObjectException
	 *             the stream does not contain a valid pack bitmap index.
	 */
	public static PackBitmapIndex read(InputStream fd, PackIndex packIndex,
			PackReverseIndex reverseIndex) throws IOException {
		return new PackBitmapIndexV1(fd, packIndex, reverseIndex);
	}

	/**
	 * Read an existing pack bitmap index file from a buffered stream.
	 * <p>
	 * The format of the file will be automatically detected and a proper access
	 * implementation for that format will be constructed and returned to the
	 * caller. The file may or may not be held open by the returned instance.
	 *
	 * @param fd
	 *            stream to read the bitmap index file from. The stream must be
	 *            buffered as some small IOs are performed against the stream.
	 *            The caller is responsible for closing the stream.
	 * @param packIndexSupplier
	 *            the supplier for pack index for the corresponding pack file.
	 * @param reverseIndexSupplier
	 *            the supplier for pack reverse index for the corresponding pack
	 *            file.
	 * @param loadParallelRevIndex
	 *            whether reverse index should be loaded in parallel
	 * @return a copy of the index in-memory.
	 * @throws java.io.IOException
	 *             the stream cannot be read.
	 * @throws CorruptObjectException
	 *             the stream does not contain a valid pack bitmap index.
	 */
	public static PackBitmapIndex read(InputStream fd,
			SupplierWithIOException<PackIndex> packIndexSupplier,
			SupplierWithIOException<PackReverseIndex> reverseIndexSupplier,
			boolean loadParallelRevIndex)
			throws IOException {
		return new PackBitmapIndexV1(fd, packIndexSupplier,
				reverseIndexSupplier, loadParallelRevIndex);
	}

	/**
	 * Footer checksum applied on the bottom of the pack file.
	 *
	 * @return checksum as a byte array
	 */
	default byte[] getPackChecksum() {
		return null;
	}

	/**
	 * Finds the position in the bitmap of the object.
	 *
	 * @param objectId
	 *            the id for which the bitmap position will be found.
	 * @return the bitmap id or -1 if the object was not found.
	 */
	public abstract int findPosition(AnyObjectId objectId);

	/**
	 * Get the object at the bitmap position.
	 *
	 * @param position
	 *            the offset in the bitmap which corresponds to an object of
	 *            interest. This position is the same as the order of the object
	 *            in the {@link PackFile}.
	 * @return the ObjectId.
	 * @throws java.lang.IllegalArgumentException
	 *             when the item is not found.
	 */
	public abstract ObjectId getObject(int position)
			throws IllegalArgumentException;

	/**
	 * Returns a bitmap containing positions for objects that have the given Git
	 * type.
	 *
	 * @param bitmap
	 *            the object bitmap.
	 * @param type
	 *            the Git type.
	 * @return the object bitmap with only objects of the Git type.
	 */
	public abstract EWAHCompressedBitmap ofObjectType(
			EWAHCompressedBitmap bitmap, int type);

	/**
	 * Returns the previously constructed bitmap for the object.
	 *
	 * @param objectId
	 *            the id for which the bitmap will be found.
	 * @return the bitmap or null if the object was not found.
	 */
	public abstract EWAHCompressedBitmap getBitmap(AnyObjectId objectId);

	/**
	 * Obtain the total number of objects described by this index.
	 * {@code getObjectCount() - 1} is the largest bit that will be set in a
	 * bitmap.
	 *
	 * @return number of objects in this index, and likewise in the associated
	 *         pack that this index was generated from.
	 */
	public abstract int getObjectCount();

	/**
	 * Returns the number of bitmaps in this bitmap index.
	 *
	 * @return the number of bitmaps in this bitmap index.
	 */
	public abstract int getBitmapCount();

	/**
	 * Returns the number of bitmaps in this bitmap index ready to use, not
	 * XOR'ed against other entries.
	 *
	 * @return the number of bitmaps in this bitmap index ready to use.
	 */
	public abstract int getBaseBitmapCount();

	/**
	 * Current size in bytes of all base bitmaps in the index.
	 *
	 * Resolving xors for bitmaps can affect this size.
	 *
	 * @return Current size (in bytes) of all base bitmaps in this index.
	 */
	public abstract long getBaseBitmapSizeInBytes();

	/**
	 * Returns the number of bitmaps in this bitmap index XOR'ed against other
	 * entries.
	 *
	 * @return the number of bitmaps in this bitmap index represented as XOR
	 *         masks.
	 */
	public abstract int getXorBitmapCount();

	/**
	 * Current size in bytes of all XOR'ed bitmaps in the index.
	 *
	 * Resolving xors for bitmaps can affect this size.
	 *
	 * @return Current size (in bytes) of all xor bitmaps in this index.
	 */
	public abstract long getXorBitmapSizeInBytes();

	/**
	 * Supplier that propagates IOException.
	 *
	 * @param <T>
	 *            the return type which is expected from {@link #get()}
	 */
	@FunctionalInterface
	public interface SupplierWithIOException<T> {
		/**
		 * Get result.
		 *
		 * @see Supplier#get()
		 *
		 * @return result
		 * @throws IOException
		 *             if an IO error occurred
		 */
		T get() throws IOException;
	}
}