diff options
Diffstat (limited to 'org.eclipse.jgit/src')
-rw-r--r-- | org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java | 34 | ||||
-rw-r--r-- | org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFile.java | 11 |
2 files changed, 38 insertions, 7 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java index 1aa71e5a59..00e39533b1 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java @@ -349,6 +349,7 @@ public class ObjectDirectory extends FileObjectDatabase { for (PackFile p : pList.packs) { try { p.resolve(matches, id, RESOLVE_ABBREV_LIMIT); + p.resetTransientErrorCount(); } catch (IOException e) { handlePackError(e, p); } @@ -430,6 +431,7 @@ public class ObjectDirectory extends FileObjectDatabase { for (PackFile p : pList.packs) { try { ObjectLoader ldr = p.get(curs, objectId); + p.resetTransientErrorCount(); if (ldr != null) return ldr; } catch (PackMismatchException e) { @@ -510,6 +512,7 @@ public class ObjectDirectory extends FileObjectDatabase { for (PackFile p : pList.packs) { try { long len = p.getObjectSize(curs, id); + p.resetTransientErrorCount(); if (0 <= len) return len; } catch (PackMismatchException e) { @@ -549,6 +552,7 @@ public class ObjectDirectory extends FileObjectDatabase { for (final PackFile p : pList.packs) { try { LocalObjectRepresentation rep = p.representation(curs, otp); + p.resetTransientErrorCount(); if (rep != null) packer.select(otp, rep); } catch (PackMismatchException e) { @@ -569,6 +573,8 @@ public class ObjectDirectory extends FileObjectDatabase { private void handlePackError(IOException e, PackFile p) { String warnTmpl = null; + int transientErrorCount = 0; + String errTmpl = JGitText.get().exceptionWhileReadingPack; if ((e instanceof CorruptObjectException) || (e instanceof PackInvalidException)) { warnTmpl = JGitText.get().corruptPack; @@ -576,14 +582,17 @@ public class ObjectDirectory extends FileObjectDatabase { removePack(p); } else if (e instanceof FileNotFoundException) { if (p.getPackFile().exists()) { - warnTmpl = JGitText.get().packInaccessible; + errTmpl = JGitText.get().packInaccessible; + transientErrorCount = p.incrementTransientErrorCount(); } else { warnTmpl = JGitText.get().packWasDeleted; + removePack(p); } - removePack(p); } else if (FileUtils.isStaleFileHandleInCausalChain(e)) { warnTmpl = JGitText.get().packHandleIsStale; removePack(p); + } else { + transientErrorCount = p.incrementTransientErrorCount(); } if (warnTmpl != null) { if (LOG.isDebugEnabled()) { @@ -594,14 +603,25 @@ public class ObjectDirectory extends FileObjectDatabase { p.getPackFile().getAbsolutePath())); } } else { - // Don't remove the pack from the list, as the error may be - // transient. - LOG.error(MessageFormat.format( - JGitText.get().exceptionWhileReadingPack, p.getPackFile() - .getAbsolutePath()), e); + if (doLogExponentialBackoff(transientErrorCount)) { + // Don't remove the pack from the list, as the error may be + // transient. + LOG.error(MessageFormat.format(errTmpl, + p.getPackFile().getAbsolutePath()), + Integer.valueOf(transientErrorCount), e); + } } } + /** + * @param n + * count of consecutive failures + * @return @{code true} if i is a power of 2 + */ + private boolean doLogExponentialBackoff(int n) { + return (n & (n - 1)) == 0; + } + @Override InsertLooseObjectResult insertUnpackedObject(File tmp, ObjectId id, boolean createDuplicate) throws IOException { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFile.java index d90e2cf2bf..f4a77d2a2a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFile.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFile.java @@ -62,6 +62,7 @@ import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; import java.util.zip.CRC32; import java.util.zip.DataFormatException; import java.util.zip.Inflater; @@ -127,6 +128,8 @@ public class PackFile implements Iterable<PackIndex.MutableEntry> { private boolean invalidBitmap; + private AtomicInteger transientErrorCount = new AtomicInteger(); + private byte[] packChecksum; private PackIndex loadedIdx; @@ -571,6 +574,14 @@ public class PackFile implements Iterable<PackIndex.MutableEntry> { invalid = true; } + int incrementTransientErrorCount() { + return transientErrorCount.incrementAndGet(); + } + + void resetTransientErrorCount() { + transientErrorCount.set(0); + } + private void readFully(final long position, final byte[] dstbuf, int dstoff, final int cnt, final WindowCursor curs) throws IOException { |