MultiPackIndex: add the checksum to the midx

The bitmap index requires "The SHA1 checksum of the pack/MIDX this bitmap index
belongs to.", but we don't have access to it for the midx file, because it is
ignored at loading time.

Read the checksum from the file, store it in the midx and add a getter for it.

Change-Id: I32a3d1a3d8995a0408a5797168fcb7956a6a6964
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/midx/MultiPackIndexTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/midx/MultiPackIndexTest.java
index dac4654..3a90e21 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/midx/MultiPackIndexTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/midx/MultiPackIndexTest.java
@@ -126,6 +126,7 @@ public void basicMidx() throws IOException {
 				1502);
 
 		assertNull(midx.find(ObjectId.zeroId()));
+		assertNotNull(midx.getChecksum());
 	}
 
 	@Test
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/midx/MultiPackIndex.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/midx/MultiPackIndex.java
index 9b20691..31fea79 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/midx/MultiPackIndex.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/midx/MultiPackIndex.java
@@ -26,7 +26,7 @@ public interface MultiPackIndex {
 	 * <p>
 	 * The pack ids correspond to positions in this list.
 	 *
-	 * @return array of packnames refered in this multipak index
+	 * @return array of packnames refered in this multipack index
 	 */
 	String[] getPackNames();
 
@@ -76,7 +76,7 @@ public interface MultiPackIndex {
 	int findBitmapPosition(PackOffset po);
 
 	/**
-	 * Object id at the specified position in offset order (i.e position in the
+	 * Object id at the specified position in offset order (i.e. position in the
 	 * ridx or bitmap)
 	 *
 	 * @param bitmapPosition
@@ -119,6 +119,13 @@ public interface MultiPackIndex {
 	void resolve(Set<ObjectId> matches, AbbreviatedObjectId id, int matchLimit);
 
 	/**
+	 * Index checksum of the contents of this midx file
+	 *
+	 * @return checksum of the contents of this midx file
+	 */
+	byte[] getChecksum();
+
+	/**
 	 * Memory size of this multipack index
 	 *
 	 * @return size of this multipack index in memory, in bytes
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/midx/MultiPackIndexLoader.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/midx/MultiPackIndexLoader.java
index 8501b63..4b70c2c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/midx/MultiPackIndexLoader.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/midx/MultiPackIndexLoader.java
@@ -195,6 +195,9 @@ public static MultiPackIndex read(InputStream fd)
 						Integer.toHexString(chunkId)));
 			}
 		}
+		byte[] checksum = new byte[20];
+		IO.readFully(fd, checksum, 0, 20);
+		builder.addChecksum(checksum);
 		return builder.build();
 	}
 
@@ -226,6 +229,8 @@ static class MultiPackIndexBuilder {
 		// Optional
 		private byte[] bitmapPackOrder;
 
+		private byte[] checksum;
+
 		private MultiPackIndexBuilder(int hashLength) {
 			this.hashLength = hashLength;
 		}
@@ -304,7 +309,7 @@ MultiPackIndex build() throws MultiPackIndexFormatException {
 			assertPackCounts(packCount, packNames.length);
 			return new MultiPackIndexV1(hashLength, oidFanout, oidLookup,
 					packNames, bitmappedPackfiles, objectOffsets,
-					largeObjectOffsets, bitmapPackOrder);
+					largeObjectOffsets, bitmapPackOrder, checksum);
 		}
 
 		private static void assertChunkNotNull(Object object, int chunkId)
@@ -334,6 +339,10 @@ private static void assertPackCounts(int headerCount,
 						Integer.valueOf(packfileNamesCount)));
 			}
 		}
+
+		public void addChecksum(byte[] checksum) {
+			this.checksum = checksum;
+		}
 	}
 
 	/**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/midx/MultiPackIndexV1.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/midx/MultiPackIndexV1.java
index d5802dc..08e4bfc 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/midx/MultiPackIndexV1.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/midx/MultiPackIndexV1.java
@@ -40,15 +40,19 @@ class MultiPackIndexV1 implements MultiPackIndex {
 
 	private final ReverseIndex ridx;
 
+	private final byte[] checksum;
+
 	MultiPackIndexV1(int hashLength, @NonNull byte[] oidFanout,
 			@NonNull byte[] oidLookup, String[] packNames,
 			byte[] bitmappedPackfiles, byte[] objectOffsets,
-			byte[] largeObjectOffsets, byte[] bitmapPackOrder) throws MultiPackIndexFormatException {
+			byte[] largeObjectOffsets, byte[] bitmapPackOrder, byte[] checksum)
+			throws MultiPackIndexFormatException {
 		this.idx = new OidLookup(hashLength, oidFanout, oidLookup);
 		this.offsets = new OffsetLookup(objectOffsets, largeObjectOffsets);
 		this.packNames = packNames;
 		this.ridx = new ReverseIndex(bitmapPackOrder, idx, offsets,
 				bitmappedPackfiles);
+		this.checksum = checksum;
 	}
 
 	@Override
@@ -104,11 +108,16 @@ public void resolve(Set<ObjectId> matches, AbbreviatedObjectId id,
 	}
 
 	@Override
+	public byte[] getChecksum() {
+		return checksum;
+	}
+
+	@Override
 	public long getMemorySize() {
 		int packNamesSize = Arrays.stream(packNames)
 				.mapToInt(s -> s.getBytes(StandardCharsets.UTF_8).length).sum();
-		return packNamesSize + ridx.getMemorySize()
-				+ idx.getMemorySize() + offsets.getMemorySize();
+		return packNamesSize + ridx.getMemorySize() + idx.getMemorySize()
+				+ offsets.getMemorySize() + checksum.length;
 	}
 
 	@Override