JohnnyK
JohnnyK

Reputation: 1102

Get Hazelcast to stop deserializing objects when using an EntryProcessor

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

Answers (1)

wildnez
wildnez

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

Related Questions