]> source.dussan.org Git - jgit.git/commitdiff
Allow to discover bitmap on disk created after the packfile 96/1174396/15
authorLuca Milanesio <luca.milanesio@gmail.com>
Wed, 10 Jan 2024 19:38:46 +0000 (19:38 +0000)
committerMatthias Sohn <matthias.sohn@sap.com>
Tue, 20 Feb 2024 21:54:54 +0000 (22:54 +0100)
When the bitmap file was created *after* a packfile had been
loaded into the memory, JGit was unable to discover them.

That happed because of two problems:

1. The PackDirectory.getPacks() does not implement the usual
   while loop that is scanning through the packs directory
   as in the other parts of JGit.

2. The scan packs does not look for newly created bitmap files
   if the packfile is already loaded in memory.

Implement the normal packfiles scanning whenever the PackDirectory
needs to return a list of packs, and make sure that any reused
Pack object would have its associated bitmap properly refreshed
from disk.

Adapt the assertions in GcConcurrentTest with the rescanned list
of Pack from the objects/packs directory.

Bug: jgit-15
Change-Id: I2ed576cefd78a0e128b175228a59c9af51523d7b

org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcConcurrentTest.java
org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/Pack.java
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackDirectory.java

index 1519873b627fbbea83aafb52478800f0640c1741..96a064989b5a31ae423964011928b5e2a5e1f0a0 100644 (file)
@@ -186,13 +186,12 @@ public class GcConcurrentTest extends GcTestCase {
                // make sure gc() has caused creation of a new packfile
                assertNotEquals(oldPackName, newPackName);
 
-               // Even when asking again for the set of packfiles outdated data
-               // will be returned. As long as the repository can work on cached data
-               // it will do so and not detect that a new packfile exists.
-               assertNotEquals(getSinglePack(repository).getPackName(), newPackName);
+               // When asking again for the set of packfiles the new updated data
+               // will be returned because of the rescan of the pack directory.
+               assertEquals(getSinglePack(repository).getPackName(), newPackName);
 
-               // Only when accessing object content it is required to rescan the pack
-               // directory and the new packfile will be detected.
+               // When accessing object content the new packfile refreshed from
+               // the rescan triggered from the list of packs.
                repository.getObjectDatabase().open(b).getSize();
                assertEquals(getSinglePack(repository).getPackName(), newPackName);
                assertNotNull(getSinglePack(repository).getBitmapIndex());
index 45a67947f1dcf9b344b6956e9072d62d7ffb16ee..eabb0c6fa4e1540088414c8e9e187a6b5afc6476 100644 (file)
@@ -64,6 +64,8 @@ binaryHunkDecodeError=Binary hunk, line {0}: invalid input
 binaryHunkInvalidLength=Binary hunk, line {0}: input corrupt; expected length byte, got 0x{1}
 binaryHunkLineTooShort=Binary hunk, line {0}: input ended prematurely
 binaryHunkMissingNewline=Binary hunk, line {0}: input line not terminated by newline
+bitmapAccessErrorForPackfile=Error whilst trying to access bitmap file for {}
+bitmapFailedToGet=Failed to get bitmap index file {}
 bitmapMissingObject=Bitmap at {0} is missing {1}.
 bitmapsMustBePrepared=Bitmaps must be prepared before they may be written.
 blameNotCommittedYet=Not Committed Yet
index c7cad43d960f3727451740d5dc0d685cf7906ceb..1d5a2e1f6be084cc7802ca2697eab81576a6483e 100644 (file)
@@ -93,6 +93,8 @@ public class JGitText extends TranslationBundle {
        /***/ public String binaryHunkInvalidLength;
        /***/ public String binaryHunkLineTooShort;
        /***/ public String binaryHunkMissingNewline;
+       /***/ public String bitmapAccessErrorForPackfile;
+       /***/ public String bitmapFailedToGet;
        /***/ public String bitmapMissingObject;
        /***/ public String bitmapsMustBePrepared;
        /***/ public String blameNotCommittedYet;
index d6c25b25877058f0eb7f006996de2e81217744d1..7d39b1fbcc8f437888b7bf10041feb5cc9dc45e9 100644 (file)
@@ -1160,6 +1160,19 @@ public class Pack implements Iterable<PackIndex.MutableEntry> {
                return bitmapIdx;
        }
 
+       synchronized void refreshBitmapIndex(PackFile bitmapIndexFile) {
+               this.bitmapIdx = null;
+               this.invalid = false;
+               this.bitmapIdxFile = bitmapIndexFile;
+               try {
+                       getBitmapIndex();
+               } catch (IOException e) {
+                       LOG.warn(JGitText.get().bitmapFailedToGet, bitmapIdxFile, e);
+                       this.bitmapIdx = null;
+                       this.bitmapIdxFile = null;
+               }
+       }
+
        private synchronized PackReverseIndex getReverseIdx() throws IOException {
                if (reverseIdx == null)
                        reverseIdx = new PackReverseIndex(idx());
index 6a99cb3d83aa66b2bd4c460bbad106c3211b49b7..1676d8bc1893126f2b3588e88a4ee0f09964cbfb 100644 (file)
@@ -115,10 +115,13 @@ class PackDirectory {
        }
 
        Collection<Pack> getPacks() {
-               PackList list = packList.get();
-               if (list == NO_PACKS) {
-                       list = scanPacks(list);
-               }
+               PackList list;
+               do {
+                       list = packList.get();
+                       if (list == NO_PACKS) {
+                               list = scanPacks(list);
+                       }
+               } while (searchPacksAgain(list));
                Pack[] packs = list.packs;
                return Collections.unmodifiableCollection(Arrays.asList(packs));
        }
@@ -455,6 +458,13 @@ class PackDirectory {
                                        && !oldPack.getFileSnapshot().isModified(packFile)) {
                                forReuse.remove(packFile.getName());
                                list.add(oldPack);
+                               try {
+                                       if(oldPack.getBitmapIndex() == null) {
+                                               oldPack.refreshBitmapIndex(packFilesByExt.get(BITMAP_INDEX));
+                                       }
+                               } catch (IOException e) {
+                                       LOG.warn(JGitText.get().bitmapAccessErrorForPackfile, oldPack.getPackName(), e);
+                               }
                                continue;
                        }