Author: cbegin
Date: Fri Sep  5 08:37:22 2008
New Revision: 692465

URL: http://svn.apache.org/viewvc?rev=692465&view=rev
Log:
SoftCache and WeakCache are now decorators rather than independent 
implementations

Added:
    
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/cache/decorators/SoftCache.java
      - copied, changed from r692345, 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/cache/impl/SoftCache.java
    
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/cache/decorators/WeakCache.java
      - copied, changed from r692345, 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/cache/impl/WeakCache.java
Removed:
    ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/javax/
    
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/cache/impl/SoftCache.java
    
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/cache/impl/WeakCache.java
Modified:
    
ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/builder/Ibatis2Configuration.java
    
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/cache/Cache.java
    
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/cache/impl/FifoCache.java
    
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/cache/impl/LruCache.java
    
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/cache/SoftCacheTest.java
    
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/cache/WeakCacheTest.java

Modified: 
ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/builder/Ibatis2Configuration.java
URL: 
http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/builder/Ibatis2Configuration.java?rev=692465&r1=692464&r2=692465&view=diff
==============================================================================
--- 
ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/builder/Ibatis2Configuration.java
 (original)
+++ 
ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/builder/Ibatis2Configuration.java
 Fri Sep  5 08:37:22 2008
@@ -6,6 +6,7 @@
 import com.ibatis.sqlmap.engine.transaction.jdbc.JdbcTransactionConfig;
 import com.ibatis.sqlmap.engine.transaction.jta.JtaTransactionConfig;
 import org.apache.ibatis.cache.impl.*;
+import org.apache.ibatis.cache.decorators.WeakCache;
 import org.apache.ibatis.mapping.Configuration;
 
 import javax.sql.DataSource;
@@ -44,7 +45,7 @@
     // CACHE ALIASES
     this.getTypeAliasRegistry().registerAlias("FIFO", 
FifoCache.class.getName());
     this.getTypeAliasRegistry().registerAlias("LRU", LruCache.class.getName());
-    this.getTypeAliasRegistry().registerAlias("MEMORY", 
WeakCache.class.getName());
+    this.getTypeAliasRegistry().registerAlias("MEMORY", 
LruCache.class.getName());
   }
 
   public TransactionManager getTransactionManager() {

Modified: 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/cache/Cache.java
URL: 
http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/cache/Cache.java?rev=692465&r1=692464&r2=692465&view=diff
==============================================================================
--- 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/cache/Cache.java
 (original)
+++ 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/cache/Cache.java
 Fri Sep  5 08:37:22 2008
@@ -11,7 +11,7 @@
 
   int getSize();
 
-  void putObject(Object key, Object object);
+  void putObject(Object key, Object value);
 
   Object getObject(Object key);
 

Copied: 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/cache/decorators/SoftCache.java
 (from r692345, 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/cache/impl/SoftCache.java)
URL: 
http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/cache/decorators/SoftCache.java?p2=ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/cache/decorators/SoftCache.java&p1=ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/cache/impl/SoftCache.java&r1=692345&r2=692465&rev=692465&view=diff
==============================================================================
--- 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/cache/impl/SoftCache.java
 (original)
+++ 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/cache/decorators/SoftCache.java
 Fri Sep  5 08:37:22 2008
@@ -1,39 +1,93 @@
-package org.apache.ibatis.cache.impl;
+package org.apache.ibatis.cache.decorators;
 
-import org.apache.ibatis.cache.impl.BaseCache;
+import org.apache.ibatis.cache.Cache;
 
-import javax.util.SoftHashMap;
-import java.util.Map;
+import java.lang.ref.*;
+import java.util.*;
+import java.util.concurrent.locks.ReadWriteLock;
 
 /**
- * Weak Reference cache implementation
+ * Soft Reference cache decorator
+ * Thanks to Dr. Heinz Kabutz for his guidance here.
  */
-public class SoftCache extends BaseCache {
+public class SoftCache implements Cache {
+  private final int numberOfHardLinks;
+  private final LinkedList hardLinksToAvoidGarbageCollection = new 
LinkedList();
+  private final ReferenceQueue queueOfGarbageCollectedEntries = new 
ReferenceQueue();
+  private final Cache delegate;
 
-  private Map cache = new SoftHashMap();
+  public SoftCache(Cache delegate) {
+    this(delegate,256);
+  }
+
+  public SoftCache(Cache delegate, int numberOfHardLinks) {
+    this.delegate = delegate;
+    this.numberOfHardLinks = numberOfHardLinks;
+  }
+
+  public String getId() {
+    return delegate.getId();
+  }
 
   public int getSize() {
-    return cache.size();
+    removeGarbageCollectedItems();
+    return delegate.getSize();
   }
 
   public void putObject(Object key, Object value) {
-    cache.put(key, value);
+    removeGarbageCollectedItems();
+    delegate.putObject(key, new SoftEntry(key, value, 
queueOfGarbageCollectedEntries));
   }
 
   public Object getObject(Object key) {
-    return cache.get(key);
+    Object result = null;
+    SoftReference softReference = (SoftReference) delegate.getObject(key);
+    if (softReference != null) {
+      result = softReference.get();
+      if (result == null) {
+        delegate.removeObject(key);
+      } else {
+        hardLinksToAvoidGarbageCollection.addFirst(result);
+        if (hardLinksToAvoidGarbageCollection.size() > numberOfHardLinks) {
+          hardLinksToAvoidGarbageCollection.removeLast();
+        }
+      }
+    }
+    return result;
   }
 
   public boolean hasKey(Object key) {
-    return cache.containsKey(key);
+    return delegate.hasKey(key);
   }
 
   public Object removeObject(Object key) {
-    return cache.remove(key);
+    removeGarbageCollectedItems();
+    return delegate.removeObject(key);
   }
 
   public void clear() {
-    cache.clear();
+    hardLinksToAvoidGarbageCollection.clear();
+    removeGarbageCollectedItems();
+    delegate.clear();
+  }
+
+  public ReadWriteLock getReadWriteLock() {
+    return delegate.getReadWriteLock();
+  }
+
+  private void removeGarbageCollectedItems() {
+    SoftEntry sv;
+    while ((sv = (SoftEntry) queueOfGarbageCollectedEntries.poll()) != null) {
+      delegate.removeObject(sv.key);
+    }
+  }
+
+  private static class SoftEntry extends SoftReference {
+    private final Object key;
+    private SoftEntry(Object key, Object value, ReferenceQueue 
garbageCollectionQueue) {
+      super(value, garbageCollectionQueue);
+      this.key = key;
+    }
   }
 
 }
\ No newline at end of file

Copied: 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/cache/decorators/WeakCache.java
 (from r692345, 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/cache/impl/WeakCache.java)
URL: 
http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/cache/decorators/WeakCache.java?p2=ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/cache/decorators/WeakCache.java&p1=ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/cache/impl/WeakCache.java&r1=692345&r2=692465&rev=692465&view=diff
==============================================================================
--- 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/cache/impl/WeakCache.java
 (original)
+++ 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/cache/decorators/WeakCache.java
 Fri Sep  5 08:37:22 2008
@@ -1,38 +1,94 @@
-package org.apache.ibatis.cache.impl;
+package org.apache.ibatis.cache.decorators;
 
 import org.apache.ibatis.cache.impl.BaseCache;
+import org.apache.ibatis.cache.Cache;
 
 import java.util.*;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.lang.ref.*;
 
 /**
- * Weak Reference cache implementation
+ * Weak Reference cache decorator
+ * Thanks to Dr. Heinz Kabutz for his guidance here.
  */
 public class WeakCache extends BaseCache {
+  private final int numberOfHardLinks;
+  private final LinkedList hardLinksToAvoidGarbageCollection = new 
LinkedList();
+  private final ReferenceQueue queueOfGarbageCollectedEntries = new 
ReferenceQueue();
+  private final Cache delegate;
 
-  private Map cache = new WeakHashMap();
+  public WeakCache(Cache delegate) {
+    this(delegate,256);
+  }
+
+  public WeakCache(Cache delegate, int numberOfHardLinks) {
+    this.delegate = delegate;
+    this.numberOfHardLinks = numberOfHardLinks;
+  }
+
+  public String getId() {
+    return delegate.getId();
+  }
 
   public int getSize() {
-    return cache.size();
+    removeGarbageCollectedItems();
+    return delegate.getSize();
   }
 
   public void putObject(Object key, Object value) {
-    cache.put(key, value);
+    removeGarbageCollectedItems();
+    delegate.putObject(key, new WeakEntry(key, value, 
queueOfGarbageCollectedEntries));
   }
 
   public Object getObject(Object key) {
-    return cache.get(key);
+    Object result = null;
+    WeakReference weakReference = (WeakReference) delegate.getObject(key);
+    if (weakReference != null) {
+      result = weakReference.get();
+      if (result == null) {
+        delegate.removeObject(key);
+      } else {
+        hardLinksToAvoidGarbageCollection.addFirst(result);
+        if (hardLinksToAvoidGarbageCollection.size() > numberOfHardLinks) {
+          hardLinksToAvoidGarbageCollection.removeLast();
+        }
+      }
+    }
+    return result;
   }
 
   public boolean hasKey(Object key) {
-    return cache.containsKey(key);
+    return delegate.hasKey(key);
   }
 
   public Object removeObject(Object key) {
-    return cache.remove(key);
+    removeGarbageCollectedItems();
+    return delegate.removeObject(key);
   }
 
   public void clear() {
-    cache.clear();
+    hardLinksToAvoidGarbageCollection.clear();
+    removeGarbageCollectedItems();
+    delegate.clear();
+  }
+
+  public ReadWriteLock getReadWriteLock() {
+    return delegate.getReadWriteLock();
+  }
+
+  private void removeGarbageCollectedItems() {
+    WeakEntry sv;
+    while ((sv = (WeakEntry) queueOfGarbageCollectedEntries.poll()) != null) {
+      delegate.removeObject(sv.key);
+    }
+  }
+
+  private static class WeakEntry extends WeakReference {
+    private final Object key;
+    private WeakEntry(Object key, Object value, ReferenceQueue 
garbageCollectionQueue) {
+      super(value, garbageCollectionQueue);
+      this.key = key;
+    }
   }
 
 }

Modified: 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/cache/impl/FifoCache.java
URL: 
http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/cache/impl/FifoCache.java?rev=692465&r1=692464&r2=692465&view=diff
==============================================================================
--- 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/cache/impl/FifoCache.java
 (original)
+++ 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/cache/impl/FifoCache.java
 Fri Sep  5 08:37:22 2008
@@ -9,7 +9,7 @@
  */
 public class FifoCache extends BaseCache {
 
-  private int size = 256;
+  private int size = 1024;
   private Map cache = new HashMap();
   private List keyList = new LinkedList();
 

Modified: 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/cache/impl/LruCache.java
URL: 
http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/cache/impl/LruCache.java?rev=692465&r1=692464&r2=692465&view=diff
==============================================================================
--- 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/cache/impl/LruCache.java
 (original)
+++ 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/cache/impl/LruCache.java
 Fri Sep  5 08:37:22 2008
@@ -9,7 +9,7 @@
  */
 public class LruCache extends BaseCache {
 
-  private int size = 256;
+  private int size = 1024;
   private Map cache = new HashMap();
   private List keyList = new LinkedList();
 

Modified: 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/cache/SoftCacheTest.java
URL: 
http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/cache/SoftCacheTest.java?rev=692465&r1=692464&r2=692465&view=diff
==============================================================================
--- 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/cache/SoftCacheTest.java
 (original)
+++ 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/cache/SoftCacheTest.java
 Fri Sep  5 08:37:22 2008
@@ -1,29 +1,28 @@
 package org.apache.ibatis.cache;
 
-import org.apache.ibatis.cache.decorators.SerializedCache;
-import org.apache.ibatis.cache.impl.SoftCache;
+import org.apache.ibatis.cache.decorators.*;
+import org.apache.ibatis.cache.impl.*;
 import org.junit.*;
 
 public class SoftCacheTest {
 
-  @Test @Ignore("Until we can find a reliable way to test it on all machines.")
+  @Test //@Ignore("Until we can find a reliable way to test it on all 
machines.")
   public void shouldDemonstrateObjectsBeingCollectedAsNeeded() throws 
Exception {
-    SoftCache cache = new SoftCache();
+    SoftCache cache = new SoftCache(new PerpetualCache());
     int n = 100000;
     for (int i = 0; i < n; i++) {
       byte[] array = new byte[5001]; //waste a bunch of memory
       array[5000] = 1;
       cache.putObject(i, array);
-
       Object value = cache.getObject(i);
-      //Assert.assertTrue(value == null || value.equals(String.valueOf(i)));
     }
+    System.out.println(cache.getSize());
     Assert.assertTrue(cache.getSize() < n);
   }
 
   @Test
   public void shouldDemonstrateCopiesAreEqual() {
-    Cache cache = new SoftCache();
+    Cache cache = new SoftCache(new PerpetualCache());
     cache = new SerializedCache(cache);
     for (int i = 0; i < 1000; i++) {
       cache.putObject(i, i);
@@ -34,7 +33,7 @@
 
   @Test
   public void shouldRemoveItemOnDemand() {
-    Cache cache = new SoftCache();
+    Cache cache = new SoftCache(new PerpetualCache());
     cache.putObject(0, 0);
     Assert.assertNotNull(cache.getObject(0));
     cache.removeObject(0);
@@ -43,7 +42,7 @@
 
   @Test
   public void shouldFlushAllItemsOnDemand() {
-    Cache cache = new SoftCache();
+    Cache cache = new SoftCache(new PerpetualCache());
     for (int i = 0; i < 5; i++) {
       cache.putObject(i, i);
     }

Modified: 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/cache/WeakCacheTest.java
URL: 
http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/cache/WeakCacheTest.java?rev=692465&r1=692464&r2=692465&view=diff
==============================================================================
--- 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/cache/WeakCacheTest.java
 (original)
+++ 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/cache/WeakCacheTest.java
 Fri Sep  5 08:37:22 2008
@@ -1,14 +1,14 @@
 package org.apache.ibatis.cache;
 
-import org.apache.ibatis.cache.decorators.SerializedCache;
-import org.apache.ibatis.cache.impl.WeakCache;
+import org.apache.ibatis.cache.decorators.*;
+import org.apache.ibatis.cache.impl.*;
 import org.junit.*;
 
 public class WeakCacheTest {
 
   @Test
   public void shouldDemonstrateObjectsBeingCollectedAsNeeded() {
-    WeakCache cache = new WeakCache();
+    WeakCache cache = new WeakCache(new PerpetualCache());
     for (int i = 0; i < 1000000; i++) {
       cache.putObject(i, i);
     }
@@ -17,7 +17,7 @@
 
   @Test
   public void shouldDemonstrateCopiesAreEqual() {
-    Cache cache = new WeakCache();
+    Cache cache = new WeakCache(new PerpetualCache());
     cache = new SerializedCache(cache);
     for (int i = 0; i < 1000; i++) {
       cache.putObject(i, i);
@@ -28,7 +28,7 @@
 
   @Test
   public void shouldRemoveItemOnDemand() {
-    Cache cache = new WeakCache();
+    WeakCache cache = new WeakCache(new PerpetualCache());
     cache.putObject(0, 0);
     Assert.assertNotNull(cache.getObject(0));
     cache.removeObject(0);
@@ -37,7 +37,7 @@
 
   @Test
   public void shouldFlushAllItemsOnDemand() {
-    Cache cache = new WeakCache();
+    WeakCache cache = new WeakCache(new PerpetualCache());
     for (int i = 0; i < 5; i++) {
       cache.putObject(i, i);
     }


Reply via email to