[infinispan-commits] Infinispan SVN: r608 - in trunk/core/src: main/java/org/infinispan/marshall and 4 other directories.

infinispan-commits at lists.jboss.org infinispan-commits at lists.jboss.org
Thu Jul 23 06:34:32 EDT 2009


Author: galder.zamarreno at jboss.com
Date: 2009-07-23 06:34:31 -0400 (Thu, 23 Jul 2009)
New Revision: 608

Modified:
   trunk/core/src/main/java/org/infinispan/atomic/AtomicHashMapDelta.java
   trunk/core/src/main/java/org/infinispan/atomic/ClearOperation.java
   trunk/core/src/main/java/org/infinispan/atomic/Delta.java
   trunk/core/src/main/java/org/infinispan/atomic/NullDelta.java
   trunk/core/src/main/java/org/infinispan/atomic/Operation.java
   trunk/core/src/main/java/org/infinispan/atomic/PutOperation.java
   trunk/core/src/main/java/org/infinispan/atomic/RemoveOperation.java
   trunk/core/src/main/java/org/infinispan/marshall/Ids.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/ConstantObjectTable.java
   trunk/core/src/main/java/org/infinispan/util/FastCopyHashMap.java
   trunk/core/src/test/java/org/infinispan/atomic/AtomicHashMapTest.java
   trunk/core/src/test/java/org/infinispan/marshall/jboss/JBossMarshallerTest.java
Log:
[ISPN-136] (Implement Externalizer for Delta) Atomic operations and deltas are now serialized via Externalizer implementations.

Modified: trunk/core/src/main/java/org/infinispan/atomic/AtomicHashMapDelta.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/atomic/AtomicHashMapDelta.java	2009-07-22 12:24:59 UTC (rev 607)
+++ trunk/core/src/main/java/org/infinispan/atomic/AtomicHashMapDelta.java	2009-07-23 10:34:31 UTC (rev 608)
@@ -24,6 +24,8 @@
 import org.infinispan.atomic.Delta;
 import org.infinispan.atomic.DeltaAware;
 import org.infinispan.atomic.Operation;
+import org.infinispan.marshall.Ids;
+import org.infinispan.marshall.Marshallable;
 import org.infinispan.util.logging.Log;
 import org.infinispan.util.logging.LogFactory;
 
@@ -39,6 +41,7 @@
  * @author Manik Surtani (<a href="mailto:manik AT jboss DOT org">manik AT jboss DOT org</a>)
  * @since 4.0
  */
+ at Marshallable(externalizer = AtomicHashMapDelta.Externalizer.class, id = Ids.ATOMIC_HASH_MAP_DELTA)
 public class AtomicHashMapDelta implements Delta {
    private static final Log log = LogFactory.getLog(AtomicHashMapDelta.class);
    private static final boolean trace = log.isTraceEnabled();
@@ -65,16 +68,6 @@
       changelog.add(o);
    }
 
-   public void writeExternal(ObjectOutput out) throws IOException {
-      if (trace) log.trace("Serializing changelog " + changelog);
-      out.writeObject(changelog);
-   }
-
-   public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-      changelog = (List<Operation>) in.readObject();
-      if (trace) log.trace("Deserialized changelog " + changelog);
-   }
-
    @Override
    public String toString() {
       return "AtomicHashMapDelta{" +
@@ -85,4 +78,19 @@
    public int getChangeLogSize() {
       return changelog == null ? 0 : changelog.size();
    }
+   
+   public static class Externalizer implements org.infinispan.marshall.Externalizer {
+      public void writeObject(ObjectOutput output, Object object) throws IOException {
+         AtomicHashMapDelta delta = (AtomicHashMapDelta) object;        
+         if (trace) log.trace("Serializing changelog " + delta.changelog);
+         output.writeObject(delta.changelog);
+      }
+
+      public Object readObject(ObjectInput input) throws IOException, ClassNotFoundException {
+         AtomicHashMapDelta delta = new AtomicHashMapDelta();
+         delta.changelog = (List<Operation>) input.readObject();
+         if (trace) log.trace("Deserialized changelog " + delta.changelog);
+         return delta;
+      }
+   }
 }
\ No newline at end of file

Modified: trunk/core/src/main/java/org/infinispan/atomic/ClearOperation.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/atomic/ClearOperation.java	2009-07-22 12:24:59 UTC (rev 607)
+++ trunk/core/src/main/java/org/infinispan/atomic/ClearOperation.java	2009-07-23 10:34:31 UTC (rev 608)
@@ -21,15 +21,29 @@
  */
 package org.infinispan.atomic;
 
+import org.infinispan.marshall.Ids;
+import org.infinispan.marshall.Marshallable;
 import org.infinispan.util.FastCopyHashMap;
 
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
 import java.util.Map;
 
-
+/**
+ * An atomic clear operation.
+ * <p/>
+ *
+ * @author (various)
+ * @param <K>
+ * @param <V>
+ * @since 4.0
+ */
+ at Marshallable(externalizer = ClearOperation.Externalizer.class, id = Ids.ATOMIC_CLEAR_OPERATION)
 public class ClearOperation<K, V> extends Operation<K, V> {
    FastCopyHashMap<K, V> originalEntries;
 
-   public ClearOperation() {
+   ClearOperation() {
    }
 
    ClearOperation(FastCopyHashMap<K, V> originalEntries) {
@@ -43,4 +57,14 @@
    public void replay(Map<K, V> delegate) {
       delegate.clear();
    }
+   
+   public static class Externalizer implements org.infinispan.marshall.Externalizer {
+      public void writeObject(ObjectOutput output, Object object) throws IOException {
+         // no-op;         
+      }
+
+      public Object readObject(ObjectInput input) throws IOException, ClassNotFoundException {
+         return new ClearOperation();
+      }
+   }
 }
\ No newline at end of file

Modified: trunk/core/src/main/java/org/infinispan/atomic/Delta.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/atomic/Delta.java	2009-07-22 12:24:59 UTC (rev 607)
+++ trunk/core/src/main/java/org/infinispan/atomic/Delta.java	2009-07-23 10:34:31 UTC (rev 608)
@@ -21,15 +21,13 @@
  */
 package org.infinispan.atomic;
 
-import java.io.Externalizable;
-
 /**
  * Represents changes made to a {@link DeltaAware} implementation.  Should be efficiently externalizable.
  *
  * @author Manik Surtani (<a href="mailto:manik AT jboss DOT org">manik AT jboss DOT org</a>)
  * @since 4.0
  */
-public interface Delta extends Externalizable {
+public interface Delta {
    /**
     * Merge the current set of deltas with a given {@link DeltaAware} instance, and return a coherent and complete
     * {@link DeltaAware} instance.  Implementations should be able to deal with null values passed in, or values of a

Modified: trunk/core/src/main/java/org/infinispan/atomic/NullDelta.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/atomic/NullDelta.java	2009-07-22 12:24:59 UTC (rev 607)
+++ trunk/core/src/main/java/org/infinispan/atomic/NullDelta.java	2009-07-23 10:34:31 UTC (rev 608)
@@ -23,27 +23,16 @@
 
 import org.infinispan.atomic.AtomicHashMap;
 
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-
 /**
  * Represents no changes.
  *
  * @author Manik Surtani (<a href="mailto:manik AT jboss DOT org">manik AT jboss DOT org</a>)
+ * @author Galder Zamarreño
  * @since 4.0
  */
-public class NullDelta implements Delta {
-   public static final NullDelta INSTANCE = new NullDelta();
+public enum NullDelta implements Delta {
+   INSTANCE;
 
-   public void writeExternal(ObjectOutput out) throws IOException {
-      // don't bother writing anything
-   }
-
-   public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-      // nothing to read
-   }
-
    public DeltaAware merge(DeltaAware other) {
       return (other != null && other instanceof AtomicHashMap) ? other : new AtomicHashMap();
    }

Modified: trunk/core/src/main/java/org/infinispan/atomic/Operation.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/atomic/Operation.java	2009-07-22 12:24:59 UTC (rev 607)
+++ trunk/core/src/main/java/org/infinispan/atomic/Operation.java	2009-07-23 10:34:31 UTC (rev 608)
@@ -21,22 +21,21 @@
  */
 package org.infinispan.atomic;
 
-import java.io.Externalizable;
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
 import java.util.Map;
 
-public abstract class Operation<K, V> implements Externalizable {
+/**
+ * An atomic operation.
+ * <p/>
+ *
+ * @author (various)
+ * @param <K>
+ * @param <V>
+ * @since 4.0
+ */
+public abstract class Operation<K, V> {
+   
    public abstract void replay(Map<K, V> delegate);
 
    public abstract void rollback(Map<K, V> delegate);
-
-   public void writeExternal(ObjectOutput out) throws IOException {
-      //no op
-   }
-
-   public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-      //no op
-   }
+   
 }

Modified: trunk/core/src/main/java/org/infinispan/atomic/PutOperation.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/atomic/PutOperation.java	2009-07-22 12:24:59 UTC (rev 607)
+++ trunk/core/src/main/java/org/infinispan/atomic/PutOperation.java	2009-07-23 10:34:31 UTC (rev 608)
@@ -26,7 +26,19 @@
 import java.io.ObjectOutput;
 import java.util.Map;
 
+import org.infinispan.marshall.Ids;
+import org.infinispan.marshall.Marshallable;
 
+/**
+ * An atomic put operation.
+ * <p/>
+ *
+ * @author (various)
+ * @param <K>
+ * @param <V>
+ * @since 4.0
+ */
+ at Marshallable(externalizer = PutOperation.Externalizer.class, id = Ids.ATOMIC_PUT_OPERATION)
 public class PutOperation<K, V> extends Operation<K, V> {
    private K key;
    private V oldValue;
@@ -52,16 +64,18 @@
       delegate.put(key, newValue);
    }
 
-   @Override
-   public void writeExternal(ObjectOutput out) throws IOException {
-      // don't bother writing out the old value since it will never be rolled back
-      out.writeObject(key);
-      out.writeObject(newValue);
-   }
+   public static class Externalizer implements org.infinispan.marshall.Externalizer {
+      public void writeObject(ObjectOutput output, Object object) throws IOException {
+         PutOperation put = (PutOperation) object;
+         output.writeObject(put.key);
+         output.writeObject(put.newValue);
+      }
 
-   @Override
-   public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-      key = (K) in.readObject();
-      newValue = (V) in.readObject();
+      public Object readObject(ObjectInput input) throws IOException, ClassNotFoundException {
+         PutOperation put = new PutOperation();
+         put.key = input.readObject();
+         put.newValue = input.readObject();         
+         return put;
+      }
    }
 }
\ No newline at end of file

Modified: trunk/core/src/main/java/org/infinispan/atomic/RemoveOperation.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/atomic/RemoveOperation.java	2009-07-22 12:24:59 UTC (rev 607)
+++ trunk/core/src/main/java/org/infinispan/atomic/RemoveOperation.java	2009-07-23 10:34:31 UTC (rev 608)
@@ -26,7 +26,19 @@
 import java.io.ObjectOutput;
 import java.util.Map;
 
+import org.infinispan.marshall.Ids;
+import org.infinispan.marshall.Marshallable;
 
+/**
+ * An atomic remove operation.
+ * <p/>
+ *
+ * @author (various)
+ * @param <K>
+ * @param <V>
+ * @since 4.0
+ */
+ at Marshallable(externalizer = RemoveOperation.Externalizer.class, id = Ids.ATOMIC_REMOVE_OPERATION)
 public class RemoveOperation<K, V> extends Operation<K, V> {
    private K key;
    private V oldValue;
@@ -46,14 +58,17 @@
    public void replay(Map<K, V> delegate) {
       delegate.remove(key);
    }
-
-   @Override
-   public void writeExternal(ObjectOutput out) throws IOException {
-      out.writeObject(key);
+   
+   public static class Externalizer implements org.infinispan.marshall.Externalizer {
+      public void writeObject(ObjectOutput output, Object object) throws IOException {
+         RemoveOperation remove = (RemoveOperation) object;
+         output.writeObject(remove.key);
+      }
+      
+      public Object readObject(ObjectInput input) throws IOException, ClassNotFoundException {
+         RemoveOperation remove = new RemoveOperation();
+         remove.key = input.readObject();
+         return remove;
+      }
    }
-
-   @Override
-   public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-      key = (K) in.readObject();
-   }
 }
\ No newline at end of file

Modified: trunk/core/src/main/java/org/infinispan/marshall/Ids.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/Ids.java	2009-07-22 12:24:59 UTC (rev 607)
+++ trunk/core/src/main/java/org/infinispan/marshall/Ids.java	2009-07-23 10:34:31 UTC (rev 608)
@@ -56,7 +56,7 @@
    static final byte TRANSIENT_MORTAL_VALUE = 17;
 
    // internal collections
-   static final byte FASTCOPY_HASHMAP = 18;
+   static final byte FASTCOPY_HASH_MAP = 18;
    static final byte IMMUTABLE_MAP = 19;
    static final byte ATOMIC_HASH_MAP = 20;
 
@@ -86,6 +86,10 @@
    static final byte TRANSACTION_LOG_ENTRY = 41; 
    static final byte BUCKET = 42;
    static final byte DEADLOCK_DETECTING_GLOBAL_TRANSACTION = 43;
+   static final byte ATOMIC_HASH_MAP_DELTA = 46;
+   static final byte ATOMIC_PUT_OPERATION = 47;
+   static final byte ATOMIC_REMOVE_OPERATION = 48;
+   static final byte ATOMIC_CLEAR_OPERATION = 49;
    
    /** ids for infinispan tree classes **/
 

Modified: trunk/core/src/main/java/org/infinispan/marshall/jboss/ConstantObjectTable.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/ConstantObjectTable.java	2009-07-22 12:24:59 UTC (rev 607)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/ConstantObjectTable.java	2009-07-23 10:34:31 UTC (rev 608)
@@ -23,8 +23,12 @@
 
 import org.infinispan.CacheException;
 import org.infinispan.atomic.AtomicHashMap;
+import org.infinispan.atomic.AtomicHashMapDelta;
+import org.infinispan.atomic.ClearOperation;
+import org.infinispan.atomic.PutOperation;
+import org.infinispan.atomic.RemoveOperation;
+import org.infinispan.commands.control.LockControlCommand;
 import org.infinispan.commands.RemoteCommandFactory;
-import org.infinispan.commands.control.LockControlCommand;
 import org.infinispan.commands.control.StateTransferControlCommand;
 import org.infinispan.commands.read.GetKeyValueCommand;
 import org.infinispan.commands.remote.ClusteredGetCommand;
@@ -150,9 +154,12 @@
 
       MARSHALLABLES.add(AtomicHashMap.class.getName());
       MARSHALLABLES.add(Bucket.class.getName());
-
       MARSHALLABLES.add("org.infinispan.tree.NodeKey");
       MARSHALLABLES.add("org.infinispan.tree.Fqn");
+      MARSHALLABLES.add(AtomicHashMapDelta.class.getName());
+      MARSHALLABLES.add(PutOperation.class.getName());
+      MARSHALLABLES.add(RemoveOperation.class.getName());
+      MARSHALLABLES.add(ClearOperation.class.getName());
    }
 
    /**
@@ -213,8 +220,6 @@
       } catch (Exception e) {
          throw new CacheException("Unable to instantiate Externalizer class", e);
       }
-
-
    }
 
    public void stop() {

Modified: trunk/core/src/main/java/org/infinispan/util/FastCopyHashMap.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/util/FastCopyHashMap.java	2009-07-22 12:24:59 UTC (rev 607)
+++ trunk/core/src/main/java/org/infinispan/util/FastCopyHashMap.java	2009-07-23 10:34:31 UTC (rev 608)
@@ -44,7 +44,7 @@
  * @author Jason T. Greene
  * @since 4.0
  */
- at Marshallable(externalizer = MapExternalizer.class, id = Ids.FASTCOPY_HASHMAP)
+ at Marshallable(externalizer = MapExternalizer.class, id = Ids.FASTCOPY_HASH_MAP)
 public class FastCopyHashMap<K, V> extends AbstractMap<K, V> implements Map<K, V>, Cloneable, Serializable {
    /**
     * Serialization ID

Modified: trunk/core/src/test/java/org/infinispan/atomic/AtomicHashMapTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/atomic/AtomicHashMapTest.java	2009-07-22 12:24:59 UTC (rev 607)
+++ trunk/core/src/test/java/org/infinispan/atomic/AtomicHashMapTest.java	2009-07-23 10:34:31 UTC (rev 608)
@@ -23,11 +23,9 @@
 
 package org.infinispan.atomic;
 
-import org.easymock.EasyMock;
 import org.testng.annotations.Test;
 
 import java.io.IOException;
-import java.io.ObjectOutput;
 
 @Test(groups = "unit", testName = "atomic.AtomicHashMapTest")
 public class AtomicHashMapTest {
@@ -35,10 +33,6 @@
       AtomicHashMap m = new AtomicHashMap();
       Delta d = m.delta();
       assert d instanceof NullDelta;
-      ObjectOutput out = EasyMock.createMock(ObjectOutput.class);
-      EasyMock.replay(out);
-      d.writeExternal(out);
-      EasyMock.verify(out);
 
       AtomicHashMap newMap = new AtomicHashMap();
       newMap.initForWriting();
@@ -59,10 +53,6 @@
       assert m.size() == 1;
       Delta d = m.delta();
       assert d instanceof NullDelta;
-      ObjectOutput out = EasyMock.createMock(ObjectOutput.class);
-      EasyMock.replay(out);
-      d.writeExternal(out);
-      EasyMock.verify(out);
 
       AtomicHashMap newMap = new AtomicHashMap();
       newMap.initForWriting();

Modified: trunk/core/src/test/java/org/infinispan/marshall/jboss/JBossMarshallerTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/marshall/jboss/JBossMarshallerTest.java	2009-07-22 12:24:59 UTC (rev 607)
+++ trunk/core/src/test/java/org/infinispan/marshall/jboss/JBossMarshallerTest.java	2009-07-23 10:34:31 UTC (rev 608)
@@ -22,6 +22,9 @@
 package org.infinispan.marshall.jboss;
 
 import org.infinispan.CacheException;
+import org.infinispan.atomic.AtomicHashMap;
+import org.infinispan.atomic.AtomicHashMapDelta;
+import org.infinispan.atomic.NullDelta;
 import org.infinispan.commands.RemoteCommandFactory;
 import org.infinispan.commands.ReplicableCommand;
 import org.infinispan.commands.control.StateTransferControlCommand;
@@ -80,7 +83,6 @@
 /**
  * JBossMarshallingMarshallerTest.
  * <p/>
- * TODO: AtomicHashMap missing.
  *
  * @author Galder Zamarreño
  * @since 4.0
@@ -362,17 +364,63 @@
       }
    }
 
-//   TODO: fix unit test, will be done as part of https://jira.jboss.org/jira/browse/ISPN-136   
-//   public void testAtomicHashMap() throws Exception {
-//      AtomicHashMap m = new AtomicHashMap();
-//      m.initForWriting();
-//      m.put("k1", "v1");
-//      m.put("k1", "v2");
-//      m.put("k1", "v3");
-//      byte[] bytes = marshaller.objectToByteBuffer(m);
-//      AtomicHashMapDelta d = (AtomicHashMapDelta) marshaller.objectFromByteBuffer(bytes);
-//      assert d.getChangeLogSize() == ((AtomicHashMapDelta) m.delta()).getChangeLogSize();
-//   }
+   public void testAtomicHashMap() throws Exception {
+      AtomicHashMap<String, String> m = new AtomicHashMap<String, String>();
+      m.initForWriting();
+      m.put("k1", "v1");
+      m.put("k1", "v2");
+      m.put("k1", "v3");
+      assert m.size() == 1;
+      byte[] bytes = marshaller.objectToByteBuffer(m);
+      AtomicHashMapDelta d = (AtomicHashMapDelta) marshaller.objectFromByteBuffer(bytes);
+      assert d.getChangeLogSize() == 3;
+      AtomicHashMap<String, String> merged = new AtomicHashMap<String, String>();
+      merged = (AtomicHashMap) d.merge(merged);
+      for (Map.Entry<String, String> entry : merged.entrySet()) {
+         assert m.get(entry.getKey()).equals(entry.getValue());
+      }
+      assert merged.size() == 1;
+      
+      m = new AtomicHashMap();
+      assert m.size() == 0;
+      bytes = marshaller.objectToByteBuffer(m);
+      NullDelta nulld = (NullDelta) marshaller.objectFromByteBuffer(bytes);
+      assert nulld == NullDelta.INSTANCE;
+      
+      m = new AtomicHashMap<String, String>();
+      m.initForWriting();
+      m.put("k1", "v1");
+      m.put("k2", "v2");
+      m.put("k3", "v3");
+      m.remove("k1");
+      assert m.size() == 2;
+      bytes = marshaller.objectToByteBuffer(m);
+      d = (AtomicHashMapDelta) marshaller.objectFromByteBuffer(bytes);
+      assert d.getChangeLogSize() == 4;
+      merged = new AtomicHashMap<String, String>();
+      merged = (AtomicHashMap) d.merge(merged);
+      for (Map.Entry<String, String> entry : merged.entrySet()) {
+         assert m.get(entry.getKey()).equals(entry.getValue());
+      }
+      assert merged.size() == 2;
+      
+      m = new AtomicHashMap<String, String>();
+      m.initForWriting();
+      m.put("k5", "v1");
+      m.put("k5", "v2");
+      m.put("k5", "v3");
+      m.clear();
+      assert m.size() == 0;
+      bytes = marshaller.objectToByteBuffer(m);
+      d = (AtomicHashMapDelta) marshaller.objectFromByteBuffer(bytes);
+      assert d.getChangeLogSize() == 4;
+      merged = new AtomicHashMap<String, String>();
+      merged = (AtomicHashMap) d.merge(merged);
+      for (Map.Entry<String, String> entry : merged.entrySet()) {
+         assert m.get(entry.getKey()).equals(entry.getValue());
+      }
+      assert merged.size() == 0;
+   }
 
    protected void marshallAndAssertEquality(Object writeObj) throws Exception {
       byte[] bytes = marshaller.objectToByteBuffer(writeObj);



More information about the infinispan-commits mailing list