Reduce contention on PackFile.idx() function.
In case of concurrent pack file access, threads may wait on the idx() function even for already open files. This happens especially with a slow file system. Performance numbers are listed in the bug report. Bug: 543739 Change-Id: Iff328d347fa65ae07ecce3267d44184161248978 Signed-off-by: Juergen Denner <j.denner@sap.com> Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
This commit is contained in:
parent
7b3ee6f62e
commit
19c4380689
|
@ -139,7 +139,7 @@ public int compare(final PackFile a, final PackFile b) {
|
|||
|
||||
private byte[] packChecksum;
|
||||
|
||||
private PackIndex loadedIdx;
|
||||
private volatile PackIndex loadedIdx;
|
||||
|
||||
private PackReverseIndex reverseIdx;
|
||||
|
||||
|
@ -174,35 +174,44 @@ public PackFile(final File packFile, int extensions) {
|
|||
length = Long.MAX_VALUE;
|
||||
}
|
||||
|
||||
private synchronized PackIndex idx() throws IOException {
|
||||
if (loadedIdx == null) {
|
||||
if (invalid)
|
||||
throw new PackInvalidException(packFile);
|
||||
private PackIndex idx() throws IOException {
|
||||
PackIndex idx = loadedIdx;
|
||||
if (idx == null) {
|
||||
synchronized (this) {
|
||||
idx = loadedIdx;
|
||||
if (idx == null) {
|
||||
if (invalid) {
|
||||
throw new PackInvalidException(packFile);
|
||||
}
|
||||
try {
|
||||
idx = PackIndex.open(extFile(INDEX));
|
||||
|
||||
try {
|
||||
final PackIndex idx = PackIndex.open(extFile(INDEX));
|
||||
|
||||
if (packChecksum == null) {
|
||||
packChecksum = idx.packChecksum;
|
||||
} else if (!Arrays.equals(packChecksum, idx.packChecksum)) {
|
||||
throw new PackMismatchException(MessageFormat.format(
|
||||
JGitText.get().packChecksumMismatch,
|
||||
packFile.getPath(),
|
||||
ObjectId.fromRaw(packChecksum).name(),
|
||||
ObjectId.fromRaw(idx.packChecksum).name()));
|
||||
if (packChecksum == null) {
|
||||
packChecksum = idx.packChecksum;
|
||||
} else if (!Arrays.equals(packChecksum,
|
||||
idx.packChecksum)) {
|
||||
throw new PackMismatchException(MessageFormat
|
||||
.format(JGitText.get().packChecksumMismatch,
|
||||
packFile.getPath(),
|
||||
ObjectId.fromRaw(packChecksum)
|
||||
.name(),
|
||||
ObjectId.fromRaw(idx.packChecksum)
|
||||
.name()));
|
||||
}
|
||||
loadedIdx = idx;
|
||||
} catch (InterruptedIOException e) {
|
||||
// don't invalidate the pack, we are interrupted from
|
||||
// another thread
|
||||
throw e;
|
||||
} catch (IOException e) {
|
||||
invalid = true;
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
loadedIdx = idx;
|
||||
} catch (InterruptedIOException e) {
|
||||
// don't invalidate the pack, we are interrupted from another thread
|
||||
throw e;
|
||||
} catch (IOException e) {
|
||||
invalid = true;
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
return loadedIdx;
|
||||
return idx;
|
||||
}
|
||||
|
||||
/** @return the File object which locates this pack on disk. */
|
||||
public File getPackFile() {
|
||||
return packFile;
|
||||
|
|
Loading…
Reference in New Issue