Reputation: 1102
I'm using a Hazelcast IMap where I update values a lot using an EntryProcessor. At the same time, other threads are calling get(). I would like to avoid all unnecessary deserialization if possible. But it seems that it's still deserializing even when using a single node.
Is there any way to avoid this? I've set the in-memory format of both the Map and near cache to OBJECT. I also set cache-local-entries to true, but still no luck. I'm using Hazelcast 3.12.
Here's my sample code:
public class HazelcastSerializationTest {
static int readCount = 0;
private String mapName = "map1";
private HazelcastInstance createHazelcast() {
Config config = new Config("HazelcastSerializationTest");
config.addMapConfig(new MapConfig(mapName)
.setInMemoryFormat(InMemoryFormat.OBJECT)
.setNearCacheConfig(new NearCacheConfig(mapName)
.setInMemoryFormat(InMemoryFormat.OBJECT)
.setCacheLocalEntries(true)));
config.getNetworkConfig().getJoin()
.getMulticastConfig().setEnabled(false);
return Hazelcast.newHazelcastInstance(config);
}
@Test
public void testEntry() {
HazelcastInstance instance = createHazelcast();
IMap<Integer, DataObject> map = instance.getMap(mapName);
map.put(1, new DataObject(0));
for (int i = 0; i < 100; i++) {
map.executeOnKey(1, new NothingProcessor());
map.get(1);
}
assertEquals(2, readCount);
}
}
class NothingProcessor extends AbstractEntryProcessor<Integer, DataObject> {
@Override
public Object process(Map.Entry<Integer, DataObject> entry) {
entry.setValue(new DataObject(entry.getValue().getValue() + 1));
return null;
}
}
class DataObject implements Externalizable {
private int value;
public DataObject(int value) {
this.value = value;
}
public DataObject() { }
@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeInt(value);
}
@Override
public void readExternal(ObjectInput in) throws IOException {
HazelcastSerializationTest.readCount++;
value = in.readInt();
}
}
Am I missing something? I would expect this to just return the real object from the near cache. The deserialization seems unnecessary. I should also mention that in my scenario, the key and value objects are immutable.
Upvotes: 3
Views: 602
Reputation: 1098
When you update an entry through EntryProcessor then it also invalidates the value of the key in NearCache. So whenever you do a get()
on that key, the new value is fetched from the server and stored in NearCache. And fetching from server on a get()
= serialization + deserialisation, regardless of in-memory-format type.
Upvotes: 1