[infinispan-commits] Infinispan SVN: r1739 - in trunk/core/src: main/java/org/infinispan/marshall/exts and 4 other directories.
infinispan-commits at lists.jboss.org
infinispan-commits at lists.jboss.org
Wed May 5 10:26:08 EDT 2010
Author: galder.zamarreno at jboss.com
Date: 2010-05-05 10:26:06 -0400 (Wed, 05 May 2010)
New Revision: 1739
Added:
trunk/core/src/test/java/org/infinispan/loaders/file/ClusterFileCacheStoreFunctionalTest.java
Modified:
trunk/core/src/main/java/org/infinispan/atomic/AtomicHashMap.java
trunk/core/src/main/java/org/infinispan/atomic/AtomicHashMapProxy.java
trunk/core/src/main/java/org/infinispan/atomic/AtomicMapLookup.java
trunk/core/src/main/java/org/infinispan/marshall/exts/ReplicableCommandExternalizer.java
trunk/core/src/test/java/org/infinispan/atomic/AtomicHashMapConcurrencyTest.java
trunk/core/src/test/java/org/infinispan/atomic/ClusteredAPITest.java
trunk/core/src/test/java/org/infinispan/loaders/BaseCacheStoreFunctionalTest.java
trunk/core/src/test/java/org/infinispan/marshall/VersionAwareMarshallerTest.java
Log:
[ISPN-419] (Transactional AtomicHashMap modifications are lost when persisting) Fixed by making sure deltas are only used for repl/dist and when storing to cache store taking the underlying map of the atomic hash map and marshalling that. Added a test to verify that merging works correctly in a clustered env as well.
Modified: trunk/core/src/main/java/org/infinispan/atomic/AtomicHashMap.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/atomic/AtomicHashMap.java 2010-05-05 13:02:55 UTC (rev 1738)
+++ trunk/core/src/main/java/org/infinispan/atomic/AtomicHashMap.java 2010-05-05 14:26:06 UTC (rev 1739)
@@ -58,17 +58,18 @@
* Construction only allowed through this factory method. This factory is intended for use internally by the
* CacheDelegate. User code should use {@link org.infinispan.atomic.AtomicMapLookup#getAtomicMap(Cache, Object)}.
*/
- public static AtomicHashMap newInstance(Cache cache, Object cacheKey) {
- AtomicHashMap value = new AtomicHashMap();
- Object oldValue = cache.putIfAbsent(cacheKey, value);
- if (oldValue != null) value = (AtomicHashMap) oldValue;
- return value;
+ public static AtomicHashMap newInstance() {
+ return new AtomicHashMap();
}
- public AtomicHashMap() {
+ AtomicHashMap() {
delegate = new FastCopyHashMap<K, V>();
}
+ private AtomicHashMap(FastCopyHashMap<K, V> delegate) {
+ this.delegate = delegate;
+ }
+
public AtomicHashMap(boolean isCopy) {
this();
copied = isCopy;
@@ -191,15 +192,13 @@
public static class Externalizer implements org.infinispan.marshall.Externalizer {
public void writeObject(ObjectOutput output, Object subject) throws IOException {
- DeltaAware dw = (DeltaAware) subject;
- output.writeObject(dw.delta());
+ AtomicHashMap map = (AtomicHashMap) subject;
+ output.writeObject(map.delegate);
}
public Object readObject(ObjectInput input) throws IOException, ClassNotFoundException {
- Delta d = (Delta) input.readObject();
- DeltaAware dw = new AtomicHashMap();
- dw = d.merge(dw);
- return dw;
+ FastCopyHashMap delegate = (FastCopyHashMap) input.readObject();
+ return new AtomicHashMap(delegate);
}
}
}
Modified: trunk/core/src/main/java/org/infinispan/atomic/AtomicHashMapProxy.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/atomic/AtomicHashMapProxy.java 2010-05-05 13:02:55 UTC (rev 1738)
+++ trunk/core/src/main/java/org/infinispan/atomic/AtomicHashMapProxy.java 2010-05-05 14:26:06 UTC (rev 1739)
@@ -32,6 +32,7 @@
import org.infinispan.util.logging.LogFactory;
import java.util.Collection;
+import java.util.Collections;
import java.util.Map;
import java.util.Set;
@@ -93,35 +94,43 @@
// readers
public Set<K> keySet() {
- return getDeltaMapForRead().keySet();
+ AtomicHashMap<K, V> map = getDeltaMapForRead();
+ return map == null ? Collections.EMPTY_SET : map.keySet();
}
public Collection<V> values() {
- return getDeltaMapForRead().values();
+ AtomicHashMap<K, V> map = getDeltaMapForRead();
+ return map == null ? Collections.EMPTY_SET : map.values();
}
public Set<Entry<K, V>> entrySet() {
- return getDeltaMapForRead().entrySet();
+ AtomicHashMap<K, V> map = getDeltaMapForRead();
+ return map == null ? Collections.EMPTY_SET : map.entrySet();
}
public int size() {
- return getDeltaMapForRead().size();
+ AtomicHashMap<K, V> map = getDeltaMapForRead();
+ return map == null ? 0 : map.size();
}
public boolean isEmpty() {
- return getDeltaMapForRead().isEmpty();
+ AtomicHashMap<K, V> map = getDeltaMapForRead();
+ return map == null ? true : map.isEmpty();
}
public boolean containsKey(Object key) {
- return getDeltaMapForRead().containsKey(key);
+ AtomicHashMap<K, V> map = getDeltaMapForRead();
+ return map == null ? false : map.containsKey(key);
}
public boolean containsValue(Object value) {
- return getDeltaMapForRead().containsValue(value);
+ AtomicHashMap<K, V> map = getDeltaMapForRead();
+ return map == null ? false : map.containsValue(value);
}
public V get(Object key) {
- return getDeltaMapForRead().get(key);
+ AtomicHashMap<K, V> map = getDeltaMapForRead();
+ return map == null ? null : map.get(key);
}
// writers
Modified: trunk/core/src/main/java/org/infinispan/atomic/AtomicMapLookup.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/atomic/AtomicMapLookup.java 2010-05-05 13:02:55 UTC (rev 1738)
+++ trunk/core/src/main/java/org/infinispan/atomic/AtomicMapLookup.java 2010-05-05 14:26:06 UTC (rev 1739)
@@ -21,7 +21,7 @@
@SuppressWarnings("unchecked")
public static <MK, K, V> AtomicMap<K, V> getAtomicMap(Cache<?, ?> cache, MK key) {
Object value = cache.get(key);
- if (value == null) value = AtomicHashMap.newInstance(cache, key);
+ if (value == null) value = AtomicHashMap.newInstance();
AtomicHashMap<K, V> castValue = (AtomicHashMap<K, V>) value;
return castValue.getProxy(cache, key, cache.getAdvancedCache().getBatchContainer(), cache.getAdvancedCache().getInvocationContextContainer());
}
Modified: trunk/core/src/main/java/org/infinispan/marshall/exts/ReplicableCommandExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/exts/ReplicableCommandExternalizer.java 2010-05-05 13:02:55 UTC (rev 1738)
+++ trunk/core/src/main/java/org/infinispan/marshall/exts/ReplicableCommandExternalizer.java 2010-05-05 14:26:06 UTC (rev 1739)
@@ -21,6 +21,7 @@
*/
package org.infinispan.marshall.exts;
+import org.infinispan.atomic.DeltaAware;
import org.infinispan.commands.RemoteCommandsFactory;
import org.infinispan.commands.ReplicableCommand;
import org.infinispan.marshall.Externalizer;
@@ -51,7 +52,14 @@
UnsignedNumeric.writeUnsignedInt(output,numArgs);
for (int i = 0; i < numArgs; i++) {
- output.writeObject(args[i]);
+ Object arg = args[i];
+ if (arg instanceof DeltaAware) {
+ // Only write deltas so that replication can be more efficient
+ DeltaAware dw = (DeltaAware) arg;
+ output.writeObject(dw.delta());
+ } else {
+ output.writeObject(arg);
+ }
}
}
@@ -61,6 +69,9 @@
Object[] args = null;
if (numArgs > 0) {
args = new Object[numArgs];
+ // For DeltaAware instances, nothing special to be done here.
+ // Do not merge here since the cache contents are required.
+ // Instead, merge in PutKeyValueCommand.perform
for (int i = 0; i < numArgs; i++) args[i] = input.readObject();
}
return cmdFactory.fromStream((byte) methodId, args);
Modified: trunk/core/src/test/java/org/infinispan/atomic/AtomicHashMapConcurrencyTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/atomic/AtomicHashMapConcurrencyTest.java 2010-05-05 13:02:55 UTC (rev 1738)
+++ trunk/core/src/test/java/org/infinispan/atomic/AtomicHashMapConcurrencyTest.java 2010-05-05 14:26:06 UTC (rev 1739)
@@ -57,7 +57,8 @@
public void testConcurrentCreate() throws Exception {
tm.begin();
- AtomicMapLookup.getAtomicMap(cache, KEY);
+ AtomicMap<String, String> map = AtomicMapLookup.getAtomicMap(cache, KEY);
+ map.put("blah", "blah");
OtherThread ot = new OtherThread();
ot.start();
Object response = ot.response.take();
@@ -77,6 +78,7 @@
public void testReadAfterTxStarted() throws Exception {
AtomicMap<Integer, String> atomicMap = AtomicMapLookup.getAtomicMap(cache, KEY);
+ cache.putIfAbsent(KEY, AtomicHashMap.newInstance());
atomicMap.put(1, "existing");
tm.begin();
atomicMap.put(1, "newVal");
@@ -107,6 +109,7 @@
try {
tm.begin();
AtomicMap<Integer, String> atomicMap = AtomicMapLookup.getAtomicMap(cache, KEY);
+ if (cache.get(KEY) == null) cache.putIfAbsent(KEY, AtomicHashMap.newInstance());
boolean notCommited = true;
while (notCommited) {
Operation op = toExecute.take();
Modified: trunk/core/src/test/java/org/infinispan/atomic/ClusteredAPITest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/atomic/ClusteredAPITest.java 2010-05-05 13:02:55 UTC (rev 1738)
+++ trunk/core/src/test/java/org/infinispan/atomic/ClusteredAPITest.java 2010-05-05 14:26:06 UTC (rev 1739)
@@ -1,23 +1,21 @@
package org.infinispan.atomic;
-import static org.infinispan.atomic.AtomicHashMapTestAssertions.assertIsEmpty;
-import static org.infinispan.atomic.AtomicHashMapTestAssertions.assertIsEmptyMap;
-
import org.infinispan.Cache;
import org.infinispan.config.Configuration;
import org.infinispan.test.MultipleCacheManagersTest;
import org.infinispan.test.TestingUtil;
import org.testng.annotations.Test;
+import static org.infinispan.atomic.AtomicHashMapTestAssertions.*;
+import java.lang.reflect.Method;
+
@Test(groups = "functional", testName = "atomic.ClusteredAPITest")
public class ClusteredAPITest extends MultipleCacheManagersTest {
protected void createCacheManagers() throws Throwable {
Configuration c = getDefaultClusteredConfig(Configuration.CacheMode.REPL_SYNC, true);
c.setInvocationBatchingEnabled(true);
-
createClusteredCaches(2, "atomic", c);
-
}
public void testReplicationCommit() throws Exception {
@@ -40,6 +38,72 @@
assert AtomicMapLookup.getAtomicMap(cache2, "map").containsKey("blah");
}
+ public void testMultipleReplicationCommit(Method m) throws Exception {
+ Cache<String, Object> cache1 = cache(0, "atomic");
+ Cache<String, Object> cache2 = cache(1, "atomic");
+
+ AtomicMap<String, String> map = AtomicMapLookup.getAtomicMap(cache1, "map");
+ TestingUtil.getTransactionManager(cache1).begin();
+ map.put("existing", "existing");
+ map.put("blah", "blah");
+ TestingUtil.getTransactionManager(cache1).commit();
+
+ assert map.size() == 2;
+ assert map.get("blah").equals("blah");
+ assert map.containsKey("blah");
+ assert map.get("existing").equals("existing");
+ assert map.containsKey("existing");
+
+ assert AtomicMapLookup.getAtomicMap(cache2, "map").size() == 2;
+ assert AtomicMapLookup.getAtomicMap(cache2, "map").get("blah").equals("blah");
+ assert AtomicMapLookup.getAtomicMap(cache2, "map").containsKey("blah");
+ assert AtomicMapLookup.getAtomicMap(cache2, "map").get("existing").equals("existing");
+ assert AtomicMapLookup.getAtomicMap(cache2, "map").containsKey("existing");
+
+ map = AtomicMapLookup.getAtomicMap(cache1, "map");
+ TestingUtil.getTransactionManager(cache1).begin();
+ String newKey = "k-" + m.getName();
+ String newValue = "v-" + m.getName();
+ map.put(newKey, newValue);
+ TestingUtil.getTransactionManager(cache1).commit();
+
+ assert map.size() == 3;
+ assert map.get("blah").equals("blah");
+ assert map.containsKey("blah");
+ assert map.get("existing").equals("existing");
+ assert map.containsKey("existing");
+ assert map.get(newKey).equals(newValue);
+ assert map.containsKey(newKey);
+
+ assert AtomicMapLookup.getAtomicMap(cache2, "map").size() == 3;
+ assert AtomicMapLookup.getAtomicMap(cache2, "map").get("blah").equals("blah");
+ assert AtomicMapLookup.getAtomicMap(cache2, "map").containsKey("blah");
+ assert AtomicMapLookup.getAtomicMap(cache2, "map").get("existing").equals("existing");
+ assert AtomicMapLookup.getAtomicMap(cache2, "map").containsKey("existing");
+ assert AtomicMapLookup.getAtomicMap(cache2, "map").get(newKey).equals(newValue);
+ assert AtomicMapLookup.getAtomicMap(cache2, "map").containsKey(newKey);
+ }
+
+
+ public void testReplicationCommitCreateMapInTransaction(Method m) throws Exception {
+ Cache<String, Object> cache1 = cache(0, "atomic");
+ Cache<String, Object> cache2 = cache(1, "atomic");
+
+ TestingUtil.getTransactionManager(cache1).begin();
+ AtomicMap<String, String> map = AtomicMapLookup.getAtomicMap(cache1, m.getName());
+ map.put("a", "b");
+ TestingUtil.getTransactionManager(cache1).commit();
+
+ assert map.size() == 1;
+ assert map.get("a").equals("b");
+ assert map.containsKey("a");
+
+ assert AtomicMapLookup.getAtomicMap(cache2, m.getName()).size() == 1;
+ assert AtomicMapLookup.getAtomicMap(cache2, m.getName()).get("a").equals("b");
+ assert AtomicMapLookup.getAtomicMap(cache2, m.getName()).containsKey("a");
+ }
+
+
public void testReplicationRollback() throws Exception {
Cache<String, Object> cache1 = cache(0, "atomic");
Cache<String, Object> cache2 = cache(1, "atomic");
Modified: trunk/core/src/test/java/org/infinispan/loaders/BaseCacheStoreFunctionalTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/loaders/BaseCacheStoreFunctionalTest.java 2010-05-05 13:02:55 UTC (rev 1738)
+++ trunk/core/src/test/java/org/infinispan/loaders/BaseCacheStoreFunctionalTest.java 2010-05-05 14:26:06 UTC (rev 1739)
@@ -146,28 +146,28 @@
}
}
-// public void testRestoreTransactionalAtomicMap(Method m) throws Exception{
-// Configuration cfg = new Configuration();
-// cfg.getCacheLoaderManagerConfig().addCacheLoaderConfig(csConfig);
-// CacheManager localCacheManager = TestCacheManagerFactory.createCacheManager(cfg, true);
-// try {
-// Cache<String, Object> cache = localCacheManager.getCache();
-// TransactionManager tm = cache.getAdvancedCache().getTransactionManager();
-// tm.begin();
-// final AtomicMap<String, String> map = AtomicMapLookup.getAtomicMap(cache, m.getName());
-// map.put("a", "b");
-// tm.commit();
-//
-// //evict from memory
-// cache.evict(m.getName());
-//
-// // now re-retrieve the map and make sure we see the diffs
-// assert AtomicMapLookup.getAtomicMap(cache, m.getName()).get("a").equals("b");
-// } finally {
-// TestingUtil.killCacheManagers(localCacheManager);
-// }
-// }
+ public void testRestoreTransactionalAtomicMap(Method m) throws Exception {
+ Configuration cfg = new Configuration();
+ cfg.getCacheLoaderManagerConfig().addCacheLoaderConfig(csConfig);
+ CacheManager localCacheManager = TestCacheManagerFactory.createCacheManager(cfg, true);
+ try {
+ Cache<String, Object> cache = localCacheManager.getCache();
+ TransactionManager tm = cache.getAdvancedCache().getTransactionManager();
+ tm.begin();
+ final AtomicMap<String, String> map = AtomicMapLookup.getAtomicMap(cache, m.getName());
+ map.put("a", "b");
+ tm.commit();
+ //evict from memory
+ cache.evict(m.getName());
+
+ // now re-retrieve the map and make sure we see the diffs
+ assert AtomicMapLookup.getAtomicMap(cache, m.getName()).get("a").equals("b");
+ } finally {
+ TestingUtil.killCacheManagers(localCacheManager);
+ }
+ }
+
private void assertCacheEntry(Cache cache, String key, String value, long lifespanMillis, long maxIdleMillis) {
DataContainer dc = cache.getAdvancedCache().getDataContainer();
InternalCacheEntry ice = dc.get(key);
Added: trunk/core/src/test/java/org/infinispan/loaders/file/ClusterFileCacheStoreFunctionalTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/loaders/file/ClusterFileCacheStoreFunctionalTest.java (rev 0)
+++ trunk/core/src/test/java/org/infinispan/loaders/file/ClusterFileCacheStoreFunctionalTest.java 2010-05-05 14:26:06 UTC (rev 1739)
@@ -0,0 +1,97 @@
+package org.infinispan.loaders.file;
+
+import org.infinispan.Cache;
+import org.infinispan.atomic.AtomicMap;
+import org.infinispan.atomic.AtomicMapLookup;
+import org.infinispan.config.CacheLoaderManagerConfig;
+import org.infinispan.config.Configuration;
+import org.infinispan.config.GlobalConfiguration;
+import org.infinispan.loaders.CacheStoreConfig;
+import org.infinispan.manager.CacheManager;
+import org.infinispan.test.MultipleCacheManagersTest;
+import org.infinispan.test.TestingUtil;
+import org.infinispan.test.fwk.TestCacheManagerFactory;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Optional;
+import org.testng.annotations.Parameters;
+import org.testng.annotations.Test;
+
+import javax.transaction.TransactionManager;
+import java.io.File;
+import java.lang.reflect.Method;
+
+/**
+ * // TODO: Document this
+ *
+ * @author Galder Zamarreño
+ * @since // TODO
+ */
+ at Test(groups = "unit", testName = "loaders.file.ClusterFileCacheStoreFunctionalTest")
+public class ClusterFileCacheStoreFunctionalTest extends MultipleCacheManagersTest {
+
+ private String tmpDirectory;
+
+ private Cache cache1, cache2;
+
+ @BeforeClass
+ @Parameters({"basedir"})
+ protected void setUpTempDir(@Optional(value = "/tmp") String basedir) {
+ tmpDirectory = TestingUtil.tmpDirectory(basedir, this);
+ }
+
+ @AfterClass(alwaysRun = true)
+ protected void clearTempDir() {
+ TestingUtil.recursiveFileRemove(tmpDirectory);
+ new File(tmpDirectory).mkdirs();
+ }
+
+ @Override
+ protected void createCacheManagers() throws Throwable {
+ CacheManager cacheManager1 = TestCacheManagerFactory.createCacheManager(GlobalConfiguration.getClusteredDefault(), new Configuration(), true);
+ CacheManager cacheManager2 = TestCacheManagerFactory.createCacheManager(GlobalConfiguration.getClusteredDefault(), new Configuration(), true);
+ registerCacheManager(cacheManager1, cacheManager2);
+
+ Configuration config1 = getDefaultClusteredConfig(Configuration.CacheMode.REPL_SYNC);
+ CacheLoaderManagerConfig clMngrConfig = new CacheLoaderManagerConfig();
+ clMngrConfig.addCacheLoaderConfig(createCacheStoreConfig(1));
+ config1.setCacheLoaderManagerConfig(clMngrConfig);
+
+ Configuration config2 = getDefaultClusteredConfig(Configuration.CacheMode.REPL_SYNC);
+ CacheLoaderManagerConfig clMngrConfig2 = new CacheLoaderManagerConfig();
+ clMngrConfig2.addCacheLoaderConfig(createCacheStoreConfig(2));
+ config2.setCacheLoaderManagerConfig(clMngrConfig2);
+
+ cacheManager1.defineConfiguration("clusteredFileCacheStore", config1);
+ cacheManager2.defineConfiguration("clusteredFileCacheStore", config2);
+ cache1 = cache(0, "clusteredFileCacheStore");
+ cache2 = cache(1, "clusteredFileCacheStore");
+ }
+
+ public void testRestoreTransactionalAtomicMap(Method m) throws Exception{
+ TransactionManager tm = cache1.getAdvancedCache().getTransactionManager();
+ tm.begin();
+ final AtomicMap<String, String> map = AtomicMapLookup.getAtomicMap(cache1, m.getName());
+ map.put("a", "b");
+ tm.commit();
+
+ //evict from memory
+ cache1.evict(m.getName());
+
+ // now re-retrieve the map and make sure we see the diffs
+ assert AtomicMapLookup.getAtomicMap(cache1, m.getName()).get("a").equals("b");
+ assert AtomicMapLookup.getAtomicMap(cache2, m.getName()).get("a").equals("b");
+
+ cache2.evict(m.getName());
+ assert AtomicMapLookup.getAtomicMap(cache1, m.getName()).get("a").equals("b");
+ assert AtomicMapLookup.getAtomicMap(cache2, m.getName()).get("a").equals("b");
+ }
+
+ protected CacheStoreConfig createCacheStoreConfig(int index) throws Exception {
+ FileCacheStoreConfig cfg = new FileCacheStoreConfig();
+ cfg.setLocation(tmpDirectory + "/" + index);
+ cfg.setPurgeSynchronously(true); // for more accurate unit testing
+ return cfg;
+ }
+
+}
Modified: trunk/core/src/test/java/org/infinispan/marshall/VersionAwareMarshallerTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/marshall/VersionAwareMarshallerTest.java 2010-05-05 13:02:55 UTC (rev 1738)
+++ trunk/core/src/test/java/org/infinispan/marshall/VersionAwareMarshallerTest.java 2010-05-05 14:26:06 UTC (rev 1739)
@@ -23,10 +23,7 @@
package org.infinispan.marshall;
import org.infinispan.atomic.AtomicHashMap;
-import org.infinispan.atomic.AtomicHashMapDelta;
-import org.infinispan.atomic.NullDelta;
import org.infinispan.commands.RemoteCommandsFactory;
-import org.infinispan.commands.ReplicableCommand;
import org.infinispan.commands.control.StateTransferControlCommand;
import org.infinispan.commands.read.GetKeyValueCommand;
import org.infinispan.commands.remote.ClusteredGetCommand;
@@ -349,7 +346,7 @@
}
public void testAtomicHashMap() throws Exception {
- AtomicHashMap<String, String> m = new AtomicHashMap<String, String>();
+ AtomicHashMap<String, String> m = AtomicHashMap.newInstance();
m.initForWriting();
m.put("k1", "v1");
m.put("k1", "v2");
@@ -362,13 +359,13 @@
}
assert m.size() == 1;
- m = new AtomicHashMap();
+ m = AtomicHashMap.newInstance();
assert m.isEmpty();
bytes = marshaller.objectToByteBuffer(m);
m = (AtomicHashMap<String, String>) marshaller.objectFromByteBuffer(bytes);
assert m.isEmpty();
- m = new AtomicHashMap<String, String>();
+ m = AtomicHashMap.newInstance();
m.initForWriting();
m.put("k1", "v1");
m.put("k2", "v2");
@@ -382,7 +379,7 @@
}
assert m.size() == 2;
- m = new AtomicHashMap<String, String>();
+ m = AtomicHashMap.newInstance();
m.initForWriting();
m.put("k5", "v1");
m.put("k5", "v2");
More information about the infinispan-commits
mailing list