[CVS nanning] Removed the KeyRemovalThread for BasicIdentifyingSystem and inlined reference cleanup code

Lecando Shared <[email protected]> Wed, 10 Sep 2003 07:24:26 -0500
Newsgroups gmane.comp.java.nanning.devel
Message-ID <[email protected]>
<html>
<head>
<style><!--
  body {background-color:#ffffff;}
  .file {border:1px solid #eeeeee;margin-top:1em;margin-bottom:1em;}
  .pathname {font-family:monospace; float:right;}
  .fileheader {margin-bottom:.5em;}
  .diff {margin:0;}
  .tasklist {padding:4px;border:1px dashed #000000;margin-top:1em;}
  .tasklist ul {margin-top:0;margin-bottom:0;}
  tr.alt {background-color:#eeeeee}
  #added {background-color:#ddffdd;}
  #addedchars {background-color:#99ff99;font-weight:bolder;}
  tr.alt #added {background-color:#ccf7cc;}
  #removed {background-color:#ffdddd;}
  #removedchars {background-color:#ff9999;font-weight:bolder;}
  tr.alt #removed {background-color:#f7cccc;}
  #info {color:#888888;}
  #context {background-color:#eeeeee;}
  td {padding-left:.3em;padding-right:.3em;}
  tr.head {border-bottom-width:1px;border-bottom-style:solid;}
  tr.head td {padding:0;padding-top:.2em;}
  .task {background-color:#ffff00;}
  .comment {padding:4px;border:1px dashed #000000;background-color:#ffffdd}
  .error {color:red;}
  hr {border-width:0px;height:2px;background:black;}
--></style>
</head>
<body>
<table cellspacing="0" cellpadding="0" border="0" rules="cols">
<tr class="head"><td colspan="4">Commit in <b><tt>nanning/src/frameworks/prevayler/src</tt></b> on <span id="info">MAIN</span></td></tr>
<tr><td><tt>main/org/codehaus/nanning/prevayler/<a href="#file1">BasicIdentifyingSystem.java</a></tt></td><td align="right" id="added">+29</td><td align="right" id="removed">-14</td><td nowrap="nowrap" align="center">1.4 -&gt; 1.5</td></tr>
<tr class="alt"><td><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/<a href="#file2">IdentifiableSoftReference.java</a></tt></td><td align="right" id="added">+4</td><td></td><td nowrap="nowrap" align="center">1.1 -&gt; 1.2</td></tr>
<tr><td><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/<a href="#file3"><span id="removed">KeyRemovalThread.java</span></a></tt></td><td></td><td align="right" id="removed">-46</td><td nowrap="nowrap">1.1 removed</td></tr>
<tr class="alt"><td><tt>test/org/codehaus/nanning/prevayler/<a href="#file4">BasicIdentifyingSystemGCTest.java</a></tt></td><td align="right" id="added">+9</td><td align="right" id="removed">-4</td><td nowrap="nowrap" align="center">1.3 -&gt; 1.4</td></tr>
<tr><td></td><td align="right" id="added">+42</td><td align="right" id="removed">-64</td><td></td></tr>
</table>
<small id="info">1 removed + 3 modified, total 4 files</small><br />
<pre class="comment">
Removed the KeyRemovalThread for BasicIdentifyingSystem and inlined reference cleanup code
</pre>
<hr /><a name="file1" /><div class="file">
<span class="pathname">nanning/src/frameworks/prevayler/src/main/org/codehaus/nanning/prevayler<br /></span>
<div class="fileheader"><big><b>BasicIdentifyingSystem.java</b></big> <small id="info">1.4 -&gt; 1.5</small></div>
<pre class="diff"><small id="info">diff -u -r1.4 -r1.5
--- BasicIdentifyingSystem.java	9 Sep 2003 11:10:27 -0000	1.4
+++ BasicIdentifyingSystem.java	10 Sep 2003 12:24:25 -0000	1.5
@@ -3,6 +3,7 @@
</small></pre><pre class="diff" id="context"> import java.io.*;
 import java.lang.ref.ReferenceQueue;
 import java.lang.ref.SoftReference;
</pre><pre class="diff" id="added">+import java.lang.ref.Reference;
</pre><pre class="diff" id="context"> import java.util.*;
 
 import org.apache.commons.logging.Log;
</pre><pre class="diff"><small id="info">@@ -13,24 +14,34 @@
</small></pre><pre class="diff" id="context">     private static final Log logger = LogFactory.getLog(BasicIdentifyingSystem.class);
     static final long serialVersionUID = 4503034161857395426L;
 
</pre><pre class="diff" id="added">+    private boolean somethingWasGCd;
</pre><pre class="diff" id="context">     private Map idToObject = new HashMap();
</pre><pre class="diff" id="removed">-    private ReferenceQueue queue = new ReferenceQueue();
-    private List readBackValues;
-    KeyRemovalThread keyRemoverThread;
</pre><pre class="diff" id="added">+    private transient ReferenceQueue queue = new ReferenceQueue();
+    private transient List readBackValues;
</pre><pre class="diff" id="context"> 
     private long nextObjectId = 0;
 
</pre><pre class="diff" id="removed">-    public BasicIdentifyingSystem() {
-        startKeyRemovalThread();
</pre><pre class="diff" id="added">+    private void removeUnreferencedKeys() {
+        SoftReference reference = (SoftReference) queue.poll();
+        if (reference == null) {
+            return;
+        }
+
+        somethingWasGCd = true;
+        idToObject.remove(new Long(((IdentifiableSoftReference) reference).getObjectId()));
</pre><pre class="diff" id="context">     }
 
</pre><pre class="diff" id="removed">-    private void startKeyRemovalThread() {
-        keyRemoverThread = new KeyRemovalThread(new SoftReference(this, queue), idToObject, queue);
-        keyRemoverThread.start();
</pre><pre class="diff" id="added">+    public boolean hasBeenGCdSinceLastCall() {
+        periodicalMaintenanceOperation();
+        if (somethingWasGCd) {
+            somethingWasGCd = false;
+            return true;
+        }
+        return false;
</pre><pre class="diff" id="context">     }
 
     public Identifiable getIdentifiable(long id) {
</pre><pre class="diff" id="removed">-        reinitValues();
</pre><pre class="diff" id="added">+        periodicalMaintenanceOperation();
</pre><pre class="diff" id="context">         SoftReference reference = getReference(id);
         if (reference == null || isUpForGC(reference)) {
             return null;
</pre><pre class="diff"><small id="info">@@ -48,7 +59,7 @@
</small></pre><pre class="diff" id="context">     }
 
     public long register(Object object) {
</pre><pre class="diff" id="removed">-        reinitValues();
</pre><pre class="diff" id="added">+        periodicalMaintenanceOperation();
</pre><pre class="diff" id="context">         if (!CurrentPrevayler.isInTransaction()) {
             throw new IllegalStateException("You have to be inside a transaction to register objects");
         }
</pre><pre class="diff"><small id="info">@@ -72,7 +83,7 @@
</small></pre><pre class="diff" id="context">     }
 
     public boolean isIDRegistered(long id) {
</pre><pre class="diff" id="removed">-        reinitValues();
</pre><pre class="diff" id="added">+        periodicalMaintenanceOperation();
</pre><pre class="diff" id="context">         SoftReference reference = getReference(id);
         if (reference == null || isUpForGC(reference)) {
             return false;
</pre><pre class="diff"><small id="info">@@ -81,12 +92,12 @@
</small></pre><pre class="diff" id="context">     }
 
     public boolean hasNoRegisteredObjects() {
</pre><pre class="diff" id="removed">-        reinitValues();
</pre><pre class="diff" id="added">+        periodicalMaintenanceOperation();
</pre><pre class="diff" id="context">         return getAllRegisteredObjects().isEmpty();
     }
 
     public Collection getAllRegisteredObjects() {
</pre><pre class="diff" id="removed">-        reinitValues();
</pre><pre class="diff" id="added">+        periodicalMaintenanceOperation();
</pre><pre class="diff" id="context">         List result = new ArrayList();
         for (Iterator i = idToObject.values().iterator(); i.hasNext();) {
             SoftReference reference = (SoftReference) i.next();
</pre><pre class="diff"><small id="info">@@ -123,7 +134,11 @@
</small></pre><pre class="diff" id="context">             Identifiable identifiable = (Identifiable) i.next();
             readBackValues.add(identifiable);
         }
</pre><pre class="diff" id="removed">-        startKeyRemovalThread();
</pre><pre class="diff" id="added">+    }
+
+    private void periodicalMaintenanceOperation() {
+        reinitValues();
+        removeUnreferencedKeys();
</pre><pre class="diff" id="context">     }
 
     private void reinitValues() {
</pre></div>
<hr /><a name="file2" /><div class="file">
<span class="pathname">nanning/src/frameworks/prevayler/src/main/org/codehaus/nanning/prevayler<br /></span>
<div class="fileheader"><big><b>IdentifiableSoftReference.java</b></big> <small id="info">1.1 -&gt; 1.2</small></div>
<pre class="diff"><small id="info">diff -u -r1.1 -r1.2
--- IdentifiableSoftReference.java	9 Sep 2003 11:10:27 -0000	1.1
+++ IdentifiableSoftReference.java	10 Sep 2003 12:24:25 -0000	1.2
@@ -11,6 +11,10 @@
</small></pre><pre class="diff" id="context">         this.id = referent.getObjectID();
     }
 
</pre><pre class="diff" id="added">+    public IdentifiableSoftReference() {
+        super(null);
+    }
+
</pre><pre class="diff" id="context">     public long getObjectId() {
         return id;
     }
</pre></div>
<hr /><a name="file3" /><div class="file">
<span class="pathname" id="removed">nanning/src/frameworks/prevayler/src/main/org/codehaus/nanning/prevayler<br /></span>
<div class="fileheader" id="removed"><big><b>KeyRemovalThread.java</b></big> <small id="info">removed after 1.1</small></div>
<pre class="diff"><small id="info">diff -N KeyRemovalThread.java
--- KeyRemovalThread.java	9 Sep 2003 11:10:27 -0000	1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,46 +0,0 @@
</small></pre><pre class="diff" id="removed">-package org.codehaus.nanning.prevayler;
-
-import java.lang.ref.SoftReference;
-import java.lang.ref.ReferenceQueue;
-import java.lang.ref.Reference;
-import java.util.Map;
-
-public class KeyRemovalThread extends Thread {
-    private boolean somethingWasGCd;
-    private SoftReference owner;
-    private ReferenceQueue queue;
-    private Map map;
-
-    public KeyRemovalThread(SoftReference owner, Map map, ReferenceQueue queue) {
-        this.owner = owner;
-        this.map = map;
-        this.queue = queue;
-        setDaemon(true);
-    }
-
-    public void run() {
-        while (!interrupted()) {
-            try {
-                SoftReference reference = (SoftReference) queue.remove();
-                if (timeToDie(reference)) {
-                    return;
-                }
-                somethingWasGCd = true;
-                map.remove(new Long(((IdentifiableSoftReference) reference).getObjectId()));
-            } catch (InterruptedException ignored) {
-            }
-        }
-    }
-
-    private boolean timeToDie(Reference reference) {
-        return reference == owner;
-    }
-
-    public boolean hasBeenGCdSinceLastCall() {
-        if (somethingWasGCd) {
-            somethingWasGCd = false;
-            return true;
-        }
-        return false;
-    }
-}
</pre></div>
<hr /><a name="file4" /><div class="file">
<span class="pathname">nanning/src/frameworks/prevayler/src/test/org/codehaus/nanning/prevayler<br /></span>
<div class="fileheader"><big><b>BasicIdentifyingSystemGCTest.java</b></big> <small id="info">1.3 -&gt; 1.4</small></div>
<pre class="diff"><small id="info">diff -u -r1.3 -r1.4
--- BasicIdentifyingSystemGCTest.java	9 Sep 2003 11:10:27 -0000	1.3
+++ BasicIdentifyingSystemGCTest.java	10 Sep 2003 12:24:26 -0000	1.4
@@ -43,7 +43,7 @@
</small></pre><pre class="diff" id="context">         long removedId = object1.getObjectID();
         object1 = null;
 
</pre><pre class="diff" id="removed">-        somethingWasGCd();
</pre><pre class="diff" id="added">+        somethingWasGCd(<span id="addedchars">2000</span>);
</pre><pre class="diff" id="context">         assertFalse("Key for value was not removed after GC", system.isIDRegistered(removedId));
         assertNull("Value was not removed after GC", system.getIdentifiable(removedId));
         assertEquals(1, system.getAllRegisteredObjects().size());
</pre><pre class="diff"><small id="info">@@ -59,7 +59,7 @@
</small></pre><pre class="diff" id="context"> 
         long object1ID = object1.getObjectID();
         object1 = null;
</pre><pre class="diff" id="removed">-        somethingWasGCd();
</pre><pre class="diff" id="added">+        somethingWasGCd(<span id="addedchars">2000</span>);
</pre><pre class="diff" id="context"> 
         assertFalse(system.isIDRegistered(object1ID));
         assertTrue(system.isIDRegistered(object2.getObjectID()));
</pre><pre class="diff"><small id="info">@@ -87,10 +87,15 @@
</small></pre><pre class="diff" id="context">        return readMap;
     }
 
</pre><pre class="diff" id="removed">-    private void somethingWasGCd() throws InterruptedException {
-        while (!system.keyRemoverThread.hasBeenGCdSinceLastCall()) {
</pre><pre class="diff" id="added">+    private void somethingWasGCd(long timeout) throws InterruptedException {
+        long timePassed = 0;
+        while (!system.hasBeenGCdSinceLastCall()) {
</pre><pre class="diff" id="context">             System.gc();
             Thread.sleep(50);
</pre><pre class="diff" id="added">+            timePassed += 50;
+            if (timePassed &gt; timeout) {
+                fail("Garbage collect did not occur within timeout");
+            }
</pre><pre class="diff" id="context">         }
     }
 
</pre></div>
</body></html>