]> source.dussan.org Git - jgit.git/commitdiff
Gc#writePack: write the reverse index file to disk 85/197585/39
authorAnna Papitto <annapapitto@google.com>
Tue, 30 May 2023 14:20:54 +0000 (16:20 +0200)
committerAnna Papitto <annapapitto@google.com>
Wed, 31 May 2023 08:09:50 +0000 (10:09 +0200)
The reverse index is currently created in-memory when needed. A writer
for reverse index files was already implemented.

Make garbage collection write the reverse index file when the PackConfig
enables it. Write it during #writePack, which mirrors how the primary
index is written.

Change-Id: I50131af6622c41a7b24534aaaf2a423ab4178981
Signed-off-by: Anna Papitto <annapapitto@google.com>
org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcReverseIndexTest.java [new file with mode: 0644]
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java

diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcReverseIndexTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcReverseIndexTest.java
new file mode 100644 (file)
index 0000000..cbb0943
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2023, Google LLC 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 static org.eclipse.jgit.internal.storage.pack.PackExt.REVERSE_INDEX;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.util.Collections;
+
+import org.eclipse.jgit.junit.TestRepository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.storage.pack.PackConfig;
+import org.eclipse.jgit.util.IO;
+import org.junit.Test;
+
+public class GcReverseIndexTest extends GcTestCase {
+
+       @Test
+       public void testWriteDefault() throws Exception {
+               PackConfig config = new PackConfig(repo);
+               gc.setPackConfig(config);
+
+               RevCommit tip = commitChain(10);
+               TestRepository.BranchBuilder bb = tr.branch("refs/heads/main");
+               bb.update(tip);
+
+               gc.gc().get();
+               assertRidxDoesNotExist(repo);
+       }
+
+       @Test
+       public void testWriteDisabled() throws Exception {
+               PackConfig config = new PackConfig(repo);
+               config.setWriteReverseIndex(false);
+               gc.setPackConfig(config);
+
+               RevCommit tip = commitChain(10);
+               TestRepository.BranchBuilder bb = tr.branch("refs/heads/main");
+               bb.update(tip);
+
+               gc.gc().get();
+               assertRidxDoesNotExist(repo);
+       }
+
+       @Test
+       public void testWriteEmptyRepo() throws Exception {
+               PackConfig config = new PackConfig(repo);
+               config.setWriteReverseIndex(true);
+               gc.setPackConfig(config);
+
+               gc.gc().get();
+               assertRidxDoesNotExist(repo);
+       }
+
+       @Test
+       public void testWriteShallowRepo() throws Exception {
+               PackConfig config = new PackConfig(repo);
+               config.setWriteReverseIndex(true);
+               gc.setPackConfig(config);
+
+               RevCommit tip = commitChain(2);
+               TestRepository.BranchBuilder bb = tr.branch("refs/heads/main");
+               bb.update(tip);
+               repo.getObjectDatabase().setShallowCommits(Collections.singleton(tip));
+
+               gc.gc().get();
+               assertValidRidxExists(repo);
+       }
+
+       @Test
+       public void testWriteEnabled() throws Exception {
+               PackConfig config = new PackConfig(repo);
+               config.setWriteReverseIndex(true);
+               gc.setPackConfig(config);
+
+               RevCommit tip = commitChain(10);
+               TestRepository.BranchBuilder bb = tr.branch("refs/heads/main");
+               bb.update(tip);
+
+               gc.gc().get();
+               assertValidRidxExists(repo);
+       }
+
+       private static void assertValidRidxExists(FileRepository repo)
+                       throws Exception {
+               PackFile packFile = repo.getObjectDatabase().getPacks().iterator()
+                               .next().getPackFile();
+               File file = packFile.create(REVERSE_INDEX);
+               assertTrue(file.exists());
+               try (InputStream os = new FileInputStream(file)) {
+                       byte[] magic = new byte[4];
+                       IO.readFully(os, magic, 0, 4);
+                       assertArrayEquals(new byte[] { 'R', 'I', 'D', 'X' }, magic);
+               }
+       }
+
+       private static void assertRidxDoesNotExist(FileRepository repo) {
+               File packDir = repo.getObjectDatabase().getPackDirectory();
+               String[] reverseIndexFilenames = packDir.list(
+                               (dir, name) -> name.endsWith(REVERSE_INDEX.getExtension()));
+               assertEquals(0, reverseIndexFilenames.length);
+       }
+}
index 11757aabdafd501017f3100a375cbe0fbe266308..10b53b6661944eb25b4a084cc8d9e06a87563cf5 100644 (file)
@@ -1323,6 +1323,25 @@ public class GC {
                                idxChannel.force(true);
                        }
 
+                       if (pw.isReverseIndexEnabled()) {
+                               File tmpReverseIndexFile = new File(packdir,
+                                               tmpBase + REVERSE_INDEX.getTmpExtension());
+                               tmpExts.put(REVERSE_INDEX, tmpReverseIndexFile);
+                               if (!tmpReverseIndexFile.createNewFile()) {
+                                       throw new IOException(MessageFormat.format(
+                                                       JGitText.get().cannotCreateIndexfile,
+                                                       tmpReverseIndexFile.getPath()));
+                               }
+                               try (FileOutputStream fos = new FileOutputStream(
+                                               tmpReverseIndexFile);
+                                               FileChannel channel = fos.getChannel();
+                                               OutputStream stream = Channels
+                                                               .newOutputStream(channel)) {
+                                       pw.writeReverseIndex(stream);
+                                       channel.force(true);
+                               }
+                       }
+
                        if (pw.prepareBitmapIndex(pm)) {
                                File tmpBitmapIdx = new File(packdir,
                                                tmpBase + BITMAP_INDEX.getTmpExtension());