[JGIT PATCH 12/23] Change ByteArrayWindow to read content outside of WindowCache's lock

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This improves the concurrency limit of WindowCache by allowing the
individual windows to be paged in outside of the cache lock.  By
moving it out multiple threads can read in different windows of
the same (or different) pack files concurrently, but we still do
only one read per window.

Signed-off-by: Shawn O. Pearce <spearce@xxxxxxxxxxx>
---
 .../src/org/spearce/jgit/lib/ByteArrayWindow.java  |   17 +++++++++++++++++
 .../src/org/spearce/jgit/lib/WindowCache.java      |    2 +-
 .../src/org/spearce/jgit/lib/WindowedFile.java     |   15 +++++++--------
 3 files changed, 25 insertions(+), 9 deletions(-)

diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/ByteArrayWindow.java b/org.spearce.jgit/src/org/spearce/jgit/lib/ByteArrayWindow.java
index cea71be..b32d4f8 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/ByteArrayWindow.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/ByteArrayWindow.java
@@ -38,6 +38,8 @@
 
 package org.spearce.jgit.lib;
 
+import java.io.IOException;
+import java.nio.ByteBuffer;
 import java.util.zip.DataFormatException;
 import java.util.zip.Inflater;
 
@@ -45,6 +47,8 @@
  * A {@link ByteWindow} with an underlying byte array for storage.
  */
 final class ByteArrayWindow extends ByteWindow<byte[]> {
+	boolean loaded;
+
 	/**
 	 * Constructor for ByteWindow.
 	 * 
@@ -64,6 +68,7 @@ ByteArrayWindow(final WindowedFile o, final long p, final int d,
 	}
 
 	int copy(final byte[] array, final int p, final byte[] b, final int o, int n) {
+		ensureLoaded(array);
 		n = Math.min(array.length - p, n);
 		System.arraycopy(array, p, b, o, n);
 		return n;
@@ -71,6 +76,7 @@ int copy(final byte[] array, final int p, final byte[] b, final int o, int n) {
 
 	int inflate(final byte[] array, final int pos, final byte[] b, int o,
 			final Inflater inf) throws DataFormatException {
+		ensureLoaded(array);
 		while (!inf.finished()) {
 			if (inf.needsInput()) {
 				inf.setInput(array, pos, array.length - pos);
@@ -82,4 +88,15 @@ int inflate(final byte[] array, final int pos, final byte[] b, int o,
 			o += inf.inflate(b, o, b.length - o);
 		return o;
 	}
+
+	private synchronized void ensureLoaded(final byte[] array) {
+		if (!loaded) {
+			try {
+				provider.fd.getChannel().read(ByteBuffer.wrap(array), start);
+			} catch (IOException e) {
+				throw new RuntimeException("Cannot fault in window", e);
+			}
+			loaded = true;
+		}
+	}
 }
\ No newline at end of file
diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/WindowCache.java b/org.spearce.jgit/src/org/spearce/jgit/lib/WindowCache.java
index f478f04..649567b 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/WindowCache.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/WindowCache.java
@@ -270,7 +270,7 @@ public static synchronized final void get(final WindowCursor curs,
 		releaseMemory();
 		runClearedWindowQueue();
 
-		wp.loadWindow(curs, id, id << windowSizeShift, wsz);
+		wp.allocWindow(curs, id, id << windowSizeShift, wsz);
 		final ByteWindow<?> e = curs.window;
 		e.chainNext = cache[idx];
 		cache[idx] = e;
diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/WindowedFile.java b/org.spearce.jgit/src/org/spearce/jgit/lib/WindowedFile.java
index 9c5cf1e..7626693 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/WindowedFile.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/WindowedFile.java
@@ -73,7 +73,7 @@
 
 	final int hash;
 
-	private RandomAccessFile fd;
+	RandomAccessFile fd;
 
 	private long length;
 
@@ -298,8 +298,8 @@ void cacheClose() {
 		fd = null;
 	}
 
-	void loadWindow(final WindowCursor curs, final int windowId,
-			final long pos, final int size) throws IOException {
+	void allocWindow(final WindowCursor curs, final int windowId,
+			final long pos, final int size) {
 		if (WindowCache.mmap) {
 			MappedByteBuffer map;
 			try {
@@ -323,7 +323,10 @@ void loadWindow(final WindowCursor curs, final int windowId,
 			if (map != null) {
 				if (map.hasArray()) {
 					final byte[] b = map.array();
-					curs.window = new ByteArrayWindow(this, pos, windowId, b);
+					final ByteArrayWindow w;
+					w = new ByteArrayWindow(this, pos, windowId, b);
+					w.loaded = true;
+					curs.window = w;
 					curs.handle = b;
 				} else {
 					curs.window = new ByteBufferWindow(this, pos, windowId, map);
@@ -334,10 +337,6 @@ void loadWindow(final WindowCursor curs, final int windowId,
 		}
 
 		final byte[] b = new byte[size];
-		synchronized (fd) {
-			fd.seek(pos);
-			fd.readFully(b);
-		}
 		curs.window = new ByteArrayWindow(this, pos, windowId, b);
 		curs.handle = b;
 	}
-- 
1.6.1.rc4.301.g5497a

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux