[infinispan-commits] Infinispan SVN: r830 - in trunk/core/src: test/java/org/infinispan/container and 1 other directory.

infinispan-commits at lists.jboss.org infinispan-commits at lists.jboss.org
Thu Sep 17 06:23:12 EDT 2009


Author: galder.zamarreno at jboss.com
Date: 2009-09-17 06:23:11 -0400 (Thu, 17 Sep 2009)
New Revision: 830

Modified:
   trunk/core/src/main/java/org/infinispan/container/SpinLockBasedLRUDataContainer.java
   trunk/core/src/test/java/org/infinispan/container/SpinLockBasedLRUDataContainerTest.java
Log:
Put now updates links of existing node updates, hence TODO has been removed.

Modified: trunk/core/src/main/java/org/infinispan/container/SpinLockBasedLRUDataContainer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/container/SpinLockBasedLRUDataContainer.java	2009-09-17 07:40:24 UTC (rev 829)
+++ trunk/core/src/main/java/org/infinispan/container/SpinLockBasedLRUDataContainer.java	2009-09-17 10:23:11 UTC (rev 830)
@@ -1,7 +1,9 @@
 package org.infinispan.container;
 
 import net.jcip.annotations.ThreadSafe;
+
 import org.infinispan.container.entries.InternalCacheEntry;
+import org.infinispan.container.entries.InternalEntryFactory;
 
 /**
  * A data container that exposes an iterator that is ordered based on least recently used (visited) entries first.
@@ -12,6 +14,7 @@
  * <p/>
  *
  * @author Manik Surtani
+ * @author Galder Zamarreño
  * @since 4.0
  */
 @ThreadSafe
@@ -35,9 +38,58 @@
 
       return ice;
    }
+   
+   @Override
+   public void put(Object k, Object v, long lifespan, long maxIdle) {
+      // do a normal put first.
+      int h = hash(k.hashCode());
+      Segment s = segmentFor(h);
+      s.lock();
+      LinkedEntry le = null;
+      Aux before = null, after = null;
+      boolean newEntry = false;
+      try {
+         le = s.get(k, h);
+         InternalCacheEntry ice = le == null ? null : le.entry;
+         if (ice == null) {
+            newEntry = true;
+            ice = InternalEntryFactory.create(k, v, lifespan, maxIdle);
+            // only update linking if this is a new entry
+            le = new LinkedEntry();
+            le.lock();
+            after = new Aux();
+            after.lock();
+            le.next = after;
+            after.next = dummyEntry;
+         } else {
+            ice.setValue(v);
+            ice = ice.setLifespan(lifespan).setMaxIdle(maxIdle);
+            updateLinks(le);
+         }
 
-   // TODO make sure even a put() on an existing entry updates links  
+         le.entry = ice;
+         s.locklessPut(k, h, le);
 
+         if (newEntry) {
+            dummyEntry.lock();
+            (before = dummyEntry.prev).lock();
+            before.next = le;
+            le.prev = before;
+            dummyEntry.prev = after;
+         }
+      } finally {
+         if (newEntry) {
+            if (le != null) {
+               before.unlock();
+               dummyEntry.unlock();
+               after.unlock();
+               le.unlock();
+            }
+         }
+         s.unlock();
+      }
+   }
+
    /**
     * Updates links on this entry, moving it to the end of the linked list
     *

Modified: trunk/core/src/test/java/org/infinispan/container/SpinLockBasedLRUDataContainerTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/container/SpinLockBasedLRUDataContainerTest.java	2009-09-17 07:40:24 UTC (rev 829)
+++ trunk/core/src/test/java/org/infinispan/container/SpinLockBasedLRUDataContainerTest.java	2009-09-17 10:23:11 UTC (rev 830)
@@ -44,4 +44,37 @@
          i++;
       }
    }
+   
+   public void testOrderingUpdateExisting() {
+      for (int i = 0; i < 10; i++) dc.put(i, "value", -1, -1);
+      
+      // update 1st key
+      dc.put(0, "new-value", -1, -1);
+      int i = 0;
+      for (InternalCacheEntry ice : dc) {
+         Integer key = (Integer) ice.getKey();
+         assert key.equals((i + 1) % 10) : "Not equals, key=" + key + " and index=" + (i + 1) % 10;
+         i++;
+      }
+      
+
+      // update key in the middle
+      dc.put(5, "new-value", -1, -1);
+      Integer[] expected = new Integer[]{1, 2, 3, 4, 6, 7, 8, 9, 0, 5};
+      i = 0;
+      for (InternalCacheEntry ice : dc) {
+         Integer key = (Integer) ice.getKey();
+         assert key.equals(expected[i]) : "Not equals, key=" + key + " and expected=" + expected[i];
+         i++;
+      }
+      
+      // update last key
+      dc.put(5, "yet-another-new-value", -1, -1);
+      i = 0;
+      for (InternalCacheEntry ice : dc) {
+         Integer key = (Integer) ice.getKey();
+         assert key.equals(expected[i]) : "Not equals, key=" + key + " and expected=" + expected[i];
+         i++;
+      }
+   }
 }



More information about the infinispan-commits mailing list