Interface EntryProcessor<K,V,R>

Type Parameters:
K - map entry key type
V - map entry value type
R - return type
All Superinterfaces:
Serializable
Functional Interface:
This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference.

@FunctionalInterface public interface EntryProcessor<K,V,R> extends Serializable
An EntryProcessor processes a Map.Entry. The EntryProcessor's process(Map.Entry) method is executed atomically. This obviates the need to explicitly lock as would be required with a ExecutorService.

Performance can be very high as the data is not moved off the Member partition. This avoids network cost and, if the storage format is InMemoryFormat.OBJECT, then there is no de-serialization or serialization cost.

EntryProcessors execute on the partition thread in a member. Multiple operations on the same partition are queued and executed sequentially.

While executing partition migrations are not allowed. Any migrations are queued on the partition thread.

An EntryProcessor may not be re-entrant i.e. it may not access the same Map. Limitation: you can only access data on the same partition.

Note that to modify an entry by using EntryProcessors you should explicitly call the Map.Entry.setValue(V) method of Map.Entry such as:

 
 Override
     public Object process(Map.Entry entry) {
        Value value = entry.getValue();
        // process and modify value
        // ...
        entry.setValue(value);
        return result;
    }
 
 
otherwise EntryProcessor does not guarantee that it will modify the entry.

EntryProcessor instances can be shared between threads. If an EntryProcessor instance contains mutable state, proper concurrency control needs to be provided to coordinate access to mutable state. Another option is to rely on ThreadLocals.

Since Hazelcast 4.1, an instance of ExtendedMapEntry is provided as argument in process(Map.Entry) method:

 
 class IncrementWithOptionalTtl implements EntryProcessor<Integer, Integer, Void> {
     private final long ttlSeconds;

     public IncrementWithOptionalTtl(long ttlSeconds) {
         this.ttlSeconds = ttlSeconds;
     }

     @Override
     public Void process(Map.Entry<Integer, Integer> e) {
         ExtendedMapEntry<Integer, Integer> entry = (ExtendedMapEntry<Integer, Integer>) e;
         int newValue = entry.getValue() + 1;
         if (ttlSeconds > 0) {
             entry.setValue(newValue, ttlSeconds, TimeUnit.SECONDS);
         } else {
             entry.setValue(newValue);
         }
         return null;
     }
 }
 
 
See Also:
  • Method Summary

    Modifier and Type
    Method
    Description
    default EntryProcessor<K,V,R>
    Get the entry processor to be applied to backup entries.
    process(Map.Entry<K,V> entry)
    Process the entry without worrying about concurrency.
  • Method Details

    • process

      R process(Map.Entry<K,V> entry)
      Process the entry without worrying about concurrency.

      Note that to modify an entry by using an EntryProcessor you should explicitly call setValue() method of Map.Entry, for example:

             @Override
              public Object process(Map.Entry entry) {
                Value value = entry.getValue();
                // process and modify value
                // ...
                entry.setValue(value);
                return result;
              }
       
      otherwise the EntryProcessor does not guarantee to modify the entry.

      The entry's value will be null, if the entry for the key doesn't exist. You can create new mapping by setting a non-null value or remove existing mapping entry by setting the value to null.

      Parameters:
      entry - entry to be processed
      Returns:
      a result that will be returned from the method taking the EntryProcessor, such as IMap.executeOnKey()
    • getBackupProcessor

      @Nullable default EntryProcessor<K,V,R> getBackupProcessor()
      Get the entry processor to be applied to backup entries.

      In case of a readonly execution, null can be returned to indicate that no backups should be made.

      Note that there is a possibility which an EntryProcessor can see that a key exists but its backup processor may not find it at run time due to an unsent backup of a previous operation (e.g. a previous put). In those situations, Hazelcast internally/eventually will sync those owner and backup partitions, so you will not lose any data. When coding a backup entry processor, you should take that case into account, otherwise NullPointerExceptions can be seen since Map.Entry.getValue() may return null.

      Returns:
      the backup entry processor