Subject: [JGIT PATCH] Fix WindowCacheGetTest.testCache_TooSmallLimit failures

From: "Shawn O. Pearce" <[email-masked]>
Date: Sat, 25 Jul 2009 13:00:56 -0700

Ever since 2d77d30b5f when I rewrote WindowCache we have been seeing
random failures inside of the TooSmallLimit test case.

These test failures have been occurring because the cache contained
more open bytes than it was configured to permit.

The cache was permitted to open more bytes than its configured limit
because the eviction routine was always skipping the last bucket
under some conditions.  If the cache table was sized the same as its
evictBatch, which happens for any fairly small table, the eviction
routine broke too early if it started at a non-zero position in the
table and wrapped around during its search.  By breaking too early
the routine did not actually perform an eviction, leaving windows
open it should have closed.

Signed-off-by: Shawn O. Pearce <[email-masked]>
---
  > Robin Rosenberg <[email-masked]> wrote:
  > > > Constantine Plotnikov <[email-masked]> wrote:
  > > > > The test WindowCacheGetTest.testCache_TooSmallLimit sometimes fails
  > > > > (on less than third of runs on Windows) with the following stacktrace:
  > > 
  > > Could it be threading-related (cache). I've never seen it on the machine where I build for
  > > the update site and it is a single core machine, but I "this" machine that has two cores it happens, not
  > > as offen as 1/6, but enough to annoy me a bit, perhaps 1/20. If it is related to bad synchronization
  > > it should happen more often the more cores you have.
  
  I think this fixes it.

 .../src/org/spearce/jgit/lib/OffsetCache.java      |    7 ++-----
 1 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/OffsetCache.java b/org.spearce.jgit/src/org/spearce/jgit/lib/OffsetCache.java
index b81c7e0..7ac532d 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/OffsetCache.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/OffsetCache.java
@@ -253,12 +253,11 @@ private void hit(final Ref<V> r) {
 	}
 
 	private void evict() {
-		final int start = rng.nextInt(tableSize);
-		int ptr = start;
 		while (isFull()) {
+			int ptr = rng.nextInt(tableSize);
 			Entry<V> old = null;
 			int slot = 0;
-			for (int b = evictBatch - 1; b >= 0; b--) {
+			for (int b = evictBatch - 1; b >= 0; b--, ptr++) {
 				if (tableSize <= ptr)
 					ptr = 0;
 				for (Entry<V> e = table.get(ptr); e != null; e = e.next) {
@@ -269,8 +268,6 @@ private void evict() {
 						slot = ptr;
 					}
 				}
-				if (++ptr == start)
-					return;
 			}
 			if (old != null) {
 				old.kill();
-- 
1.6.4.rc2.216.g769fa