[infinispan-commits] Infinispan SVN: r2615 - branches/4.2.x/core/src/main/java/org/infinispan/eviction and 4 other directories.

infinispan-commits at lists.jboss.org infinispan-commits at lists.jboss.org
Wed Oct 27 09:05:56 EDT 2010


Author: trustin
Date: 2010-10-27 09:05:55 -0400 (Wed, 27 Oct 2010)
New Revision: 2615

Modified:
   branches/4.2.x/core/src/main/java/org/infinispan/container/DefaultDataContainer.java
   branches/4.2.x/core/src/main/java/org/infinispan/eviction/EvictionManager.java
   branches/4.2.x/core/src/main/java/org/infinispan/eviction/EvictionManagerImpl.java
   branches/4.2.x/core/src/main/java/org/infinispan/util/concurrent/BoundedConcurrentHashMap.java
   trunk/core/src/main/java/org/infinispan/container/DefaultDataContainer.java
   trunk/core/src/main/java/org/infinispan/eviction/EvictionManager.java
   trunk/core/src/main/java/org/infinispan/eviction/EvictionManagerImpl.java
   trunk/core/src/main/java/org/infinispan/util/concurrent/BoundedConcurrentHashMap.java
Log:
Resolved issue: ISPN-719 BoundedConcurrentHashMap.EvictionListener should have a bulk entry listener method.
* Changed the signature of EvictionListener.onEntryEviction() to accept Map<K, V> instead of K and V.
* Extracted all piggybacked eviction notification code into notifyEvictionListener() method
Reordered some methods in BoundedConcurrentHashMap.Segment for an aestethic reason

Modified: branches/4.2.x/core/src/main/java/org/infinispan/container/DefaultDataContainer.java
===================================================================
--- branches/4.2.x/core/src/main/java/org/infinispan/container/DefaultDataContainer.java	2010-10-27 10:23:20 UTC (rev 2614)
+++ branches/4.2.x/core/src/main/java/org/infinispan/container/DefaultDataContainer.java	2010-10-27 13:05:55 UTC (rev 2615)
@@ -175,8 +175,8 @@
 
    private class DefaultEvictionListener implements EvictionListener<Object, InternalCacheEntry> {
       @Override
-      public void onEntryEviction(Object key, InternalCacheEntry value) {
-         evictionManager.onEntryEviction(key, value);
+      public void onEntryEviction(Map<Object, InternalCacheEntry> evicted) {
+         evictionManager.onEntryEviction(evicted);
       }
    }
 

Modified: branches/4.2.x/core/src/main/java/org/infinispan/eviction/EvictionManager.java
===================================================================
--- branches/4.2.x/core/src/main/java/org/infinispan/eviction/EvictionManager.java	2010-10-27 10:23:20 UTC (rev 2614)
+++ branches/4.2.x/core/src/main/java/org/infinispan/eviction/EvictionManager.java	2010-10-27 13:05:55 UTC (rev 2615)
@@ -1,5 +1,7 @@
 package org.infinispan.eviction;
 
+import java.util.Map;
+
 import net.jcip.annotations.ThreadSafe;
 
 import org.infinispan.container.entries.InternalCacheEntry;
@@ -34,5 +36,5 @@
     */
    boolean isEnabled();
 
-   void onEntryEviction(Object key, InternalCacheEntry value);
+   void onEntryEviction(Map<Object, InternalCacheEntry> evicted);
 }

Modified: branches/4.2.x/core/src/main/java/org/infinispan/eviction/EvictionManagerImpl.java
===================================================================
--- branches/4.2.x/core/src/main/java/org/infinispan/eviction/EvictionManagerImpl.java	2010-10-27 10:23:20 UTC (rev 2614)
+++ branches/4.2.x/core/src/main/java/org/infinispan/eviction/EvictionManagerImpl.java	2010-10-27 13:05:55 UTC (rev 2615)
@@ -1,6 +1,6 @@
 package org.infinispan.eviction;
 
-import java.util.concurrent.CountDownLatch;
+import java.util.Map;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.TimeUnit;
@@ -122,8 +122,9 @@
 
    @Stop(priority = 5)
    public void stop() {
-      if (evictionTask != null)
+      if (evictionTask != null) {
          evictionTask.cancel(true);
+      }
    }
 
    class ScheduledTask implements Runnable {
@@ -133,7 +134,14 @@
    }
 
    @Override
-   public void onEntryEviction(Object key, InternalCacheEntry value) {
+   public void onEntryEviction(Map<Object, InternalCacheEntry> evicted) {
+      // XXX: Note that this should be more efficient once ISPN-720 is resolved.
+      for (Map.Entry<Object, InternalCacheEntry> e: evicted.entrySet()) {
+         onEntryEviction(e.getKey(), e.getValue());
+      }
+   }
+
+   private void onEntryEviction(Object key, InternalCacheEntry value) {
       final Object entryValue = value.getValue();
       InvocationContext context = getInvocationContext();
       try {

Modified: branches/4.2.x/core/src/main/java/org/infinispan/util/concurrent/BoundedConcurrentHashMap.java
===================================================================
--- branches/4.2.x/core/src/main/java/org/infinispan/util/concurrent/BoundedConcurrentHashMap.java	2010-10-27 10:23:20 UTC (rev 2614)
+++ branches/4.2.x/core/src/main/java/org/infinispan/util/concurrent/BoundedConcurrentHashMap.java	2010-10-27 13:05:55 UTC (rev 2615)
@@ -31,6 +31,8 @@
  */
 
 package org.infinispan.util.concurrent;
+import static java.util.Collections.*;
+
 import java.io.IOException;
 import java.io.Serializable;
 import java.util.AbstractCollection;
@@ -314,12 +316,12 @@
    }
 
    public interface EvictionListener<K, V> {
-      void onEntryEviction(K key, V value);
+      void onEntryEviction(Map<K, V> evicted);
    }
 
    static class NullEvictionListener<K, V> implements EvictionListener<K, V> {
       @Override
-      public void onEntryEviction(K key, V value) {
+      public void onEntryEviction(Map<K, V> evicted) {
          // Do nothing.
       }
    }
@@ -866,12 +868,7 @@
             if (result != null) {
                if (eviction.onEntryHit(e)) {
                   Set<HashEntry<K, V>> evicted = attemptEviction(false);
-                  // piggyback listener invocation on callers thread outside lock
-                  if (evicted != null) {
-                     for (HashEntry<K, V> he : evicted) {
-                        evictionListener.onEntryEviction(he.key, he.value);
-                     }
-                  }
+                  notifyEvictionListener(evicted);
                }
             }
             return result;
@@ -879,25 +876,6 @@
          return null;
       }
 
-      private Set<HashEntry<K, V>> attemptEviction(boolean lockedAlready) {
-         Set<HashEntry<K, V>> evicted = null;
-         boolean obtainedLock = !lockedAlready ? tryLock() : true;
-         if (!obtainedLock && eviction.thresholdExpired()) {
-            lock();
-            obtainedLock = true;
-         }
-         if (obtainedLock) {
-            try {
-               evicted = eviction.execute();
-            } finally {
-               if (!lockedAlready) {
-                  unlock();
-               }
-            }
-         }
-         return evicted;
-      }
-
       boolean containsKey(Object key, int hash) {
          if (count != 0) { // read-volatile
             HashEntry<K,V> e = getFirst(hash);
@@ -950,12 +928,7 @@
             return replaced;
          } finally {
             unlock();
-            // piggyback listener invocation on callers thread outside lock
-            if (evicted != null) {
-               for (HashEntry<K, V> he : evicted) {
-                  evictionListener.onEntryEviction(he.key, he.value);
-               }
-            }
+            notifyEvictionListener(evicted);
          }
       }
 
@@ -979,12 +952,7 @@
             return oldValue;
          } finally {
             unlock();
-            // piggyback listener invocation on callers thread outside lock
-            if(evicted != null) {
-               for (HashEntry<K, V> he : evicted) {
-                  evictionListener.onEntryEviction(he.key, he.value);
-               }
-            }
+            notifyEvictionListener(evicted);
          }
       }
 
@@ -1040,12 +1008,7 @@
             return oldValue;
          } finally {
             unlock();
-            // piggyback listener invocation on callers thread outside lock
-            if(evicted != null) {
-               for (HashEntry<K, V> he : evicted) {
-                  evictionListener.onEntryEviction(he.key, he.value);
-               }
-            }
+            notifyEvictionListener(evicted);
          }
       }
 
@@ -1176,6 +1139,43 @@
             }
          }
       }
+
+      private Set<HashEntry<K, V>> attemptEviction(boolean lockedAlready) {
+         Set<HashEntry<K, V>> evicted = null;
+         boolean obtainedLock = !lockedAlready ? tryLock() : true;
+         if (!obtainedLock && eviction.thresholdExpired()) {
+            lock();
+            obtainedLock = true;
+         }
+         if (obtainedLock) {
+            try {
+               evicted = eviction.execute();
+            } finally {
+               if (!lockedAlready) {
+                  unlock();
+               }
+            }
+         }
+         return evicted;
+      }
+
+      private void notifyEvictionListener(Set<HashEntry<K, V>> evicted) {
+         // piggyback listener invocation on callers thread outside lock
+         if (evicted != null) {
+            Map<K, V> evictedCopy;
+            if (evicted.size() == 1) {
+               HashEntry<K, V> evictedEntry = evicted.iterator().next();
+               evictedCopy = singletonMap(evictedEntry.key, evictedEntry.value);
+            } else {
+               evictedCopy = new HashMap<K, V>(evicted.size());
+               for (HashEntry<K, V> he : evicted) {
+                  evictedCopy.put(he.key, he.value);
+               }
+               evictedCopy = unmodifiableMap(evictedCopy);
+            }
+            evictionListener.onEntryEviction(evictedCopy);
+         }
+      }
    }
 
 

Modified: trunk/core/src/main/java/org/infinispan/container/DefaultDataContainer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/container/DefaultDataContainer.java	2010-10-27 10:23:20 UTC (rev 2614)
+++ trunk/core/src/main/java/org/infinispan/container/DefaultDataContainer.java	2010-10-27 13:05:55 UTC (rev 2615)
@@ -175,8 +175,8 @@
 
    private class DefaultEvictionListener implements EvictionListener<Object, InternalCacheEntry> {
       @Override
-      public void onEntryEviction(Object key, InternalCacheEntry value) {
-         evictionManager.onEntryEviction(key, value);
+      public void onEntryEviction(Map<Object, InternalCacheEntry> evicted) {
+         evictionManager.onEntryEviction(evicted);
       }
    }
 

Modified: trunk/core/src/main/java/org/infinispan/eviction/EvictionManager.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/eviction/EvictionManager.java	2010-10-27 10:23:20 UTC (rev 2614)
+++ trunk/core/src/main/java/org/infinispan/eviction/EvictionManager.java	2010-10-27 13:05:55 UTC (rev 2615)
@@ -1,5 +1,7 @@
 package org.infinispan.eviction;
 
+import java.util.Map;
+
 import net.jcip.annotations.ThreadSafe;
 
 import org.infinispan.container.entries.InternalCacheEntry;
@@ -34,5 +36,5 @@
     */
    boolean isEnabled();
 
-   void onEntryEviction(Object key, InternalCacheEntry value);
+   void onEntryEviction(Map<Object, InternalCacheEntry> evicted);
 }

Modified: trunk/core/src/main/java/org/infinispan/eviction/EvictionManagerImpl.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/eviction/EvictionManagerImpl.java	2010-10-27 10:23:20 UTC (rev 2614)
+++ trunk/core/src/main/java/org/infinispan/eviction/EvictionManagerImpl.java	2010-10-27 13:05:55 UTC (rev 2615)
@@ -1,6 +1,6 @@
 package org.infinispan.eviction;
 
-import java.util.concurrent.CountDownLatch;
+import java.util.Map;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.TimeUnit;
@@ -122,8 +122,9 @@
 
    @Stop(priority = 5)
    public void stop() {
-      if (evictionTask != null)
+      if (evictionTask != null) {
          evictionTask.cancel(true);
+      }
    }
 
    class ScheduledTask implements Runnable {
@@ -133,7 +134,14 @@
    }
 
    @Override
-   public void onEntryEviction(Object key, InternalCacheEntry value) {
+   public void onEntryEviction(Map<Object, InternalCacheEntry> evicted) {
+      // XXX: Note that this should be more efficient once ISPN-720 is resolved.
+      for (Map.Entry<Object, InternalCacheEntry> e: evicted.entrySet()) {
+         onEntryEviction(e.getKey(), e.getValue());
+      }
+   }
+
+   private void onEntryEviction(Object key, InternalCacheEntry value) {
       final Object entryValue = value.getValue();
       InvocationContext context = getInvocationContext();
       try {

Modified: trunk/core/src/main/java/org/infinispan/util/concurrent/BoundedConcurrentHashMap.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/util/concurrent/BoundedConcurrentHashMap.java	2010-10-27 10:23:20 UTC (rev 2614)
+++ trunk/core/src/main/java/org/infinispan/util/concurrent/BoundedConcurrentHashMap.java	2010-10-27 13:05:55 UTC (rev 2615)
@@ -31,6 +31,8 @@
  */
 
 package org.infinispan.util.concurrent;
+import static java.util.Collections.*;
+
 import java.io.IOException;
 import java.io.Serializable;
 import java.util.AbstractCollection;
@@ -314,12 +316,12 @@
    }
 
    public interface EvictionListener<K, V> {
-      void onEntryEviction(K key, V value);
+      void onEntryEviction(Map<K, V> evicted);
    }
 
    static class NullEvictionListener<K, V> implements EvictionListener<K, V> {
       @Override
-      public void onEntryEviction(K key, V value) {
+      public void onEntryEviction(Map<K, V> evicted) {
          // Do nothing.
       }
    }
@@ -866,12 +868,7 @@
             if (result != null) {
                if (eviction.onEntryHit(e)) {
                   Set<HashEntry<K, V>> evicted = attemptEviction(false);
-                  // piggyback listener invocation on callers thread outside lock
-                  if (evicted != null) {
-                     for (HashEntry<K, V> he : evicted) {
-                        evictionListener.onEntryEviction(he.key, he.value);
-                     }
-                  }
+                  notifyEvictionListener(evicted);
                }
             }
             return result;
@@ -879,25 +876,6 @@
          return null;
       }
 
-      private Set<HashEntry<K, V>> attemptEviction(boolean lockedAlready) {
-         Set<HashEntry<K, V>> evicted = null;
-         boolean obtainedLock = !lockedAlready ? tryLock() : true;
-         if (!obtainedLock && eviction.thresholdExpired()) {
-            lock();
-            obtainedLock = true;
-         }
-         if (obtainedLock) {
-            try {
-               evicted = eviction.execute();
-            } finally {
-               if (!lockedAlready) {
-                  unlock();
-               }
-            }
-         }
-         return evicted;
-      }
-
       boolean containsKey(Object key, int hash) {
          if (count != 0) { // read-volatile
             HashEntry<K,V> e = getFirst(hash);
@@ -950,12 +928,7 @@
             return replaced;
          } finally {
             unlock();
-            // piggyback listener invocation on callers thread outside lock
-            if (evicted != null) {
-               for (HashEntry<K, V> he : evicted) {
-                  evictionListener.onEntryEviction(he.key, he.value);
-               }
-            }
+            notifyEvictionListener(evicted);
          }
       }
 
@@ -979,12 +952,7 @@
             return oldValue;
          } finally {
             unlock();
-            // piggyback listener invocation on callers thread outside lock
-            if(evicted != null) {
-               for (HashEntry<K, V> he : evicted) {
-                  evictionListener.onEntryEviction(he.key, he.value);
-               }
-            }
+            notifyEvictionListener(evicted);
          }
       }
 
@@ -1040,12 +1008,7 @@
             return oldValue;
          } finally {
             unlock();
-            // piggyback listener invocation on callers thread outside lock
-            if(evicted != null) {
-               for (HashEntry<K, V> he : evicted) {
-                  evictionListener.onEntryEviction(he.key, he.value);
-               }
-            }
+            notifyEvictionListener(evicted);
          }
       }
 
@@ -1176,6 +1139,43 @@
             }
          }
       }
+
+      private Set<HashEntry<K, V>> attemptEviction(boolean lockedAlready) {
+         Set<HashEntry<K, V>> evicted = null;
+         boolean obtainedLock = !lockedAlready ? tryLock() : true;
+         if (!obtainedLock && eviction.thresholdExpired()) {
+            lock();
+            obtainedLock = true;
+         }
+         if (obtainedLock) {
+            try {
+               evicted = eviction.execute();
+            } finally {
+               if (!lockedAlready) {
+                  unlock();
+               }
+            }
+         }
+         return evicted;
+      }
+
+      private void notifyEvictionListener(Set<HashEntry<K, V>> evicted) {
+         // piggyback listener invocation on callers thread outside lock
+         if (evicted != null) {
+            Map<K, V> evictedCopy;
+            if (evicted.size() == 1) {
+               HashEntry<K, V> evictedEntry = evicted.iterator().next();
+               evictedCopy = singletonMap(evictedEntry.key, evictedEntry.value);
+            } else {
+               evictedCopy = new HashMap<K, V>(evicted.size());
+               for (HashEntry<K, V> he : evicted) {
+                  evictedCopy.put(he.key, he.value);
+               }
+               evictedCopy = unmodifiableMap(evictedCopy);
+            }
+            evictionListener.onEntryEviction(evictedCopy);
+         }
+      }
    }
 
 



More information about the infinispan-commits mailing list