
com.tangosol.internal.util.processor.BinaryProcessors Maven / Gradle / Ivy
/*
* Copyright (c) 2019, 2020, Oracle and/or its affiliates.
*
* Licensed under the Universal Permissive License v 1.0 as shown at
* http://oss.oracle.com/licenses/upl.
*/
package com.tangosol.internal.util.processor;
import com.tangosol.io.ExternalizableLite;
import com.tangosol.io.ReadBuffer;
import com.tangosol.io.pof.PofReader;
import com.tangosol.io.pof.PofWriter;
import com.tangosol.io.pof.PortableObject;
import com.tangosol.net.GuardSupport;
import com.tangosol.net.Guardian;
import com.tangosol.util.Binary;
import com.tangosol.util.BinaryEntry;
import com.tangosol.util.ExternalizableHelper;
import com.tangosol.util.InvocableMap;
import com.tangosol.util.InvocableMap.EntryProcessor;
import com.tangosol.util.LiteMap;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
* A utility class of {@link EntryProcessor} classes that use {@link Binary}
* keys and values to avoid needless deserialization.
*
* @author Mahesh Kannan 2019.11.01
* @author Jonathan Knight 2019.11.07
* @since 14.1.2
*/
public final class BinaryProcessors
{
// ----- constructors ---------------------------------------------------
/**
* Utility class must not have public constructor.
*/
private BinaryProcessors()
{
}
/**
* Obtain an instance of the {@link BinaryGetProcessor}.
*
* @return an instance of the {@link BinaryGetProcessor}
*/
public static InvocableMap.EntryProcessor get()
{
return BinaryGetProcessor.INSTANCE;
}
/**
* Obtain an instance of the {@link BinaryPutProcessor}.
*
* @param value the serialized value to put into the cache
* @param ttl the expiry value for the entry
*
* @return an instance of the {@link BinaryPutProcessor}
*/
public static InvocableMap.EntryProcessor put(Binary value, long ttl)
{
return new BinaryPutProcessor(value, ttl);
}
/**
* Obtain an instance of the {@link BinaryPutAllProcessor}.
*
* @param map the {@link Map} of {@link Binary} keys and values to add to the cache
*
* @return an instance of the {@link BinaryPutProcessor}
*/
public static InvocableMap.EntryProcessor putAll(Map map)
{
return new BinaryPutAllProcessor(map);
}
/**
* Obtain an instance of the {@link BinaryPutIfAbsentProcessor}.
*
* @param value the serialized value to put into the cache
* @param ttl the expiry value for the entry
*
* @return an instance of the {@link BinaryPutIfAbsentProcessor}
*/
public static InvocableMap.EntryProcessor putIfAbsent(Binary value, long ttl)
{
return new BinaryPutIfAbsentProcessor(value, ttl);
}
// ----- class: BaseProcessor -------------------------------------------
/**
* A base {@link com.tangosol.util.InvocableMap.EntryProcessor}.
*
* @param the type of the {@link com.tangosol.util.InvocableMap.EntryProcessor}'s result
*/
public abstract static class BaseProcessor
implements EntryProcessor,
ExternalizableLite, PortableObject
{
// ----- ExternalizableLite interface -------------------------------
@Override
public void readExternal(DataInput dataInput) throws IOException
{
}
@Override
public void writeExternal(DataOutput dataOutput) throws IOException
{
}
@Override
public void readExternal(PofReader pofReader) throws IOException
{
}
@Override
public void writeExternal(PofWriter pofWriter) throws IOException
{
}
}
// ----- class: BinaryProcessorWithValue --------------------------------
/**
* An {@link com.tangosol.util.InvocableMap.EntryProcessor} that contains a value.
*
* @param the return type of this {@link EntryProcessor}
*/
public abstract static class BinaryProcessorWithValue
extends BaseProcessor
{
// ----- constructors -----------------------------------------------
/**
* Default constructor for serialization.
*/
protected BinaryProcessorWithValue()
{
}
/**
* Create a {@link BinaryProcessorWithValue}.
*
* @param value the {@link com.tangosol.util.Binary} value to set as the
* cache entry value
*/
protected BinaryProcessorWithValue(Binary value)
{
this.m_binValue = value;
}
// ----- helper methods ---------------------------------------------
/**
* Return the {@link Binary} value.
*
* @return the {@link Binary} value
*/
protected Binary getValue()
{
return m_binValue;
}
// ----- ExternalizableLite interface -------------------------------
@Override
public void readExternal(DataInput in) throws IOException
{
m_binValue = ExternalizableHelper.readObject(in);
}
@Override
public void writeExternal(DataOutput out) throws IOException
{
ExternalizableHelper.writeObject(out, m_binValue);
}
@Override
public void readExternal(PofReader pofReader) throws IOException
{
m_binValue = pofReader.readBinary(2);
}
@Override
public void writeExternal(PofWriter pofWriter) throws IOException
{
pofWriter.writeBinary(2, m_binValue);
}
// ----- data members -----------------------------------------------
/**
* The {@link com.tangosol.util.Binary} that is used by this
* {@link com.tangosol.util.InvocableMap.EntryProcessor}.
*/
protected Binary m_binValue;
}
// ----- class: BinaryContainsValueProcessor ----------------------------
/**
* An {@link com.tangosol.util.InvocableMap.EntryProcessor} that checks if the mapping for the
* key exists in the cache.
*/
public static class BinaryContainsValueProcessor
extends BinaryProcessorWithValue
{
// ----- constructors -----------------------------------------------
/**
* Default constructor for serialization.
*/
@SuppressWarnings("unused")
public BinaryContainsValueProcessor()
{
}
/**
* Create a {@link BinaryContainsValueProcessor}.
*
* @param value the {@link com.tangosol.util.Binary} value to check
*/
public BinaryContainsValueProcessor(Binary value)
{
super(value);
}
// ----- Processor interface ----------------------------------------
@Override
public Boolean process(InvocableMap.Entry entry)
{
if (entry.isPresent())
{
Binary bin = ((BinaryEntry) entry).getBinaryValue();
ReadBuffer buffer = ExternalizableHelper.getUndecorated((ReadBuffer) bin);
return getValue().equals(buffer.toBinary());
}
return false;
}
}
// ----- class: BinarySyntheticRemoveBlindProcessor ---------------------
/**
* An {@link com.tangosol.util.InvocableMap.EntryProcessor} that removes a cache entry
* without de-serializing keys or values and returns no
* result.
*/
public static class BinarySyntheticRemoveBlindProcessor
extends BaseProcessor
{
// ----- Processor interface ----------------------------------------
@Override
public Void process(InvocableMap.Entry entry)
{
if (entry.isPresent())
{
entry.remove(true);
}
return null;
}
// ----- EntryProcessor methods -------------------------------------
@Override
public Map processAll(Set extends InvocableMap.Entry> entries)
{
Guardian.GuardContext ctxGuard = GuardSupport.getThreadContext();
long cMillis = ctxGuard == null ? 0L : ctxGuard.getTimeoutMillis();
Iterator extends InvocableMap.Entry> iter = entries.iterator();
while (iter.hasNext())
{
InvocableMap.Entry entry = iter.next();
process(entry);
iter.remove();
if (ctxGuard != null)
{
ctxGuard.heartbeat(cMillis);
}
}
return Collections.emptyMap();
}
// ----- constants --------------------------------------------------
/**
* Singleton RemoveBlindProcessor.
*/
public static final BinarySyntheticRemoveBlindProcessor INSTANCE = new BinarySyntheticRemoveBlindProcessor();
}
// ----- class: BinaryPutProcessor --------------------------------------
/**
* An {@link com.tangosol.util.InvocableMap.EntryProcessor} that updates the mapping
* of a key to a value in a cache.
*/
public static class BinaryPutProcessor
extends BaseProcessor
{
// ----- constructors -----------------------------------------------
/**
* Default constructor for serialization.
*/
public BinaryPutProcessor()
{
}
/**
* Create a {@link BinaryPutProcessor}.
*
* @param value the {@link com.tangosol.util.Binary} value to set as the
* cache entry value
* @param cTtl the expiry value for the entry
*/
BinaryPutProcessor(Binary value, long cTtl)
{
this.m_binValue = value;
this.m_cTtl = cTtl;
}
// ----- Processor interface ----------------------------------------
@Override
public Binary process(InvocableMap.Entry entry)
{
BinaryEntry binaryEntry = (BinaryEntry) entry;
Binary result = null;
if (entry.isPresent())
{
result = binaryEntry.getBinaryValue();
}
binaryEntry.updateBinaryValue(m_binValue);
binaryEntry.expire(m_cTtl);
return result;
}
// ----- ExternalizableLite interface -------------------------------
@Override
public void readExternal(DataInput in) throws IOException
{
m_binValue = ExternalizableHelper.readObject(in);
m_cTtl = in.readLong();
}
@Override
public void writeExternal(DataOutput out) throws IOException
{
ExternalizableHelper.writeObject(out, m_binValue);
out.writeLong(m_cTtl);
}
@Override
public void readExternal(PofReader in) throws IOException
{
m_binValue = in.readBinary(0);
m_cTtl = in.readLong(1);
}
@Override
public void writeExternal(PofWriter out) throws IOException
{
out.writeBinary(0, m_binValue);
out.writeLong(1, m_cTtl);
}
// ----- helper methods ---------------------------------------------
/**
* Return the {@link Binary} value.
*
* @return the {@link Binary} value
*/
protected Binary getValue()
{
return m_binValue;
}
/**
* Return the {@code TTL}.
*
* @return the {@code TTL}
*/
protected long getTtl()
{
return m_cTtl;
}
// ----- data members -----------------------------------------------
/**
* The {@link Binary} value to map to the entry.
*/
protected Binary m_binValue;
/**
* The expiry value for the entry.
*/
protected long m_cTtl;
}
// ----- class: BinaryPutAllProcessor -----------------------------------
/**
* An {@link com.tangosol.util.InvocableMap.EntryProcessor} that updates the mapping
* of a number of key to values in a cache.
*/
public static class BinaryPutAllProcessor
extends BaseProcessor
{
// ----- constructors -----------------------------------------------
/**
* Default constructor for serialization.
*/
@SuppressWarnings("unused")
public BinaryPutAllProcessor()
{
this(new HashMap<>());
}
/**
* Create a {@link BinaryPutAllProcessor}.
*
* @param map the {@link Map} of {@link Binary} key and values to add to the cache
*/
BinaryPutAllProcessor(Map map)
{
this.m_map = map;
}
// ----- Processor interface ----------------------------------------
@Override
public Binary process(InvocableMap.Entry entry)
{
BinaryEntry binaryEntry = (BinaryEntry) entry;
Binary binary = m_map.get(binaryEntry.getBinaryKey());
if (binary == null)
{
entry.setValue(null);
}
else
{
binaryEntry.updateBinaryValue(binary);
}
return null;
}
// ----- EntryProcessor methods -------------------------------------
@Override
public Map processAll(Set extends InvocableMap.Entry> entries)
{
Guardian.GuardContext ctxGuard = GuardSupport.getThreadContext();
long cMillis = ctxGuard == null ? 0L : ctxGuard.getTimeoutMillis();
Iterator extends InvocableMap.Entry> iterator = entries.iterator();
while (iterator.hasNext())
{
InvocableMap.Entry entry = iterator.next();
this.process(entry);
iterator.remove();
if (ctxGuard != null)
{
ctxGuard.heartbeat(cMillis);
}
}
return new LiteMap<>();
}
// ----- ExternalizableLite interface -------------------------------
@Override
public void readExternal(DataInput in) throws IOException
{
ExternalizableHelper.readMap(in, this.m_map, null);
}
@Override
public void writeExternal(DataOutput out) throws IOException
{
ExternalizableHelper.writeMap(out, this.m_map);
}
@Override
public void readExternal(PofReader in) throws IOException
{
this.m_map = in.readMap(0, new HashMap<>());
}
@Override
public void writeExternal(PofWriter out) throws IOException
{
out.writeMap(0, this.m_map, Binary.class, Binary.class);
}
// ----- helper methods ---------------------------------------------
/**
* Returns the map of keys and values that were/are to be stored.
*
* @return the map of keys and values that were/are to be stored
*/
Map getMap()
{
return m_map;
}
// ----- data members ----------------------------------------------0
/**
* The {@link Binary} value to map to the entry.
*/
protected Map m_map;
}
// ----- class: BinaryPutIfAbsentProcessor ------------------------------
/**
* An {@link com.tangosol.util.InvocableMap.EntryProcessor} that puts the specified value in the cache
* only if there is no existing mapping for the key.
*/
public static class BinaryPutIfAbsentProcessor
extends BinaryPutProcessor
{
// ----- constructors -----------------------------------------------
/**
* Default constructor for serialization.
*/
@SuppressWarnings("unused")
public BinaryPutIfAbsentProcessor()
{
}
/**
* Create a {@link BinaryPutIfAbsentProcessor}.
*
* @param value the {@link com.tangosol.util.Binary} value to set as the
* cache entry value
* @param cTtl the expiry value for the entry
*/
BinaryPutIfAbsentProcessor(Binary value, long cTtl)
{
super(value, cTtl);
}
// ----- Processor interface ----------------------------------------
@Override
public Binary process(InvocableMap.Entry entry)
{
if (entry.isPresent())
{
return ((BinaryEntry) entry).getBinaryValue();
}
else
{
return super.process(entry);
}
}
}
// ----- class: BinaryGetProcessor --------------------------------------
/**
* An {@link com.tangosol.util.InvocableMap.EntryProcessor} that obtains the {@link com.tangosol.util.Binary}
* value mapped to a given key in a cache.
*/
public static class BinaryGetProcessor
extends BaseProcessor
{
// ----- Processor interface ----------------------------------------
@Override
public Binary process(InvocableMap.Entry entry)
{
Binary prevValue = null;
if (entry.isPresent())
{
prevValue = ((BinaryEntry) entry).getBinaryValue();
}
return prevValue;
}
// ----- EntryProcessor methods -------------------------------------
@Override
public Map processAll(Set extends InvocableMap.Entry> setEntries)
{
Map mapResults = new LiteMap<>();
Guardian.GuardContext ctxGuard = GuardSupport.getThreadContext();
long cMillis = ctxGuard == null ? 0L : ctxGuard.getTimeoutMillis();
Iterator extends InvocableMap.Entry> iter = setEntries.iterator();
while (iter.hasNext())
{
InvocableMap.Entry entry = iter.next();
if (entry.isPresent())
{
mapResults.put(((BinaryEntry) entry).getBinaryKey(), this.process(entry));
}
iter.remove();
if (ctxGuard != null)
{
ctxGuard.heartbeat(cMillis);
}
}
return mapResults;
}
// ----- constants --------------------------------------------------
/**
* The singleton {@link BinaryGetProcessor}.
*/
public static final BinaryGetProcessor INSTANCE = new BinaryGetProcessor();
}
// ----- class: BinaryRemoveProcessor -----------------------------------
/**
* An {@link com.tangosol.util.InvocableMap.EntryProcessor} that obtains the {@link com.tangosol.util.Binary}
* value mapped to a given key in a cache.
*/
public static class BinaryRemoveProcessor
extends BaseProcessor
{
// ----- Processor interface ----------------------------------------
@Override
public Binary process(InvocableMap.Entry entry)
{
Binary prevValue = null;
if (entry.isPresent())
{
prevValue = ((BinaryEntry) entry).getBinaryValue();
entry.remove(false);
}
return prevValue;
}
// ----- constants --------------------------------------------------
/**
* The singleton {@link BinaryRemoveProcessor}.
*/
public static final BinaryRemoveProcessor INSTANCE = new BinaryRemoveProcessor();
}
// ----- class: BinaryReplaceProcessor ----------------------------------
/**
* An {@link com.tangosol.util.InvocableMap.EntryProcessor} that replaces an existing mapping in a cache.
*/
public static class BinaryReplaceProcessor
extends BinaryProcessorWithValue
{
// ----- constructors -----------------------------------------------
/**
* Default constructor for serialization.
*/
@SuppressWarnings("unused")
public BinaryReplaceProcessor()
{
}
/**
* Create a {@link BinaryReplaceProcessor}.
*
* @param value the {@link Binary} value to set as the
* cache entry value
*/
public BinaryReplaceProcessor(Binary value)
{
super(value);
}
// ----- Processor interface ----------------------------------------
@Override
public Binary process(InvocableMap.Entry entry)
{
Binary result = null;
if (entry.isPresent())
{
result = ((BinaryEntry) entry).getBinaryValue();
((BinaryEntry) entry).updateBinaryValue(getValue());
}
return result;
}
}
// ----- class: BinaryReplaceMappingProcessor ---------------------------
/**
* An {@link com.tangosol.util.InvocableMap.EntryProcessor} that replaces a specific existing mapping in a cache.
*/
public static class BinaryReplaceMappingProcessor
extends BinaryProcessorWithValue
{
// ----- constructors -----------------------------------------------
/**
* Default constructor for serialization.
*/
@SuppressWarnings("unused")
public BinaryReplaceMappingProcessor()
{
}
/**
* Create a {@link BinaryReplaceMappingProcessor}.
*
* @param previousValue the {@link com.tangosol.util.Binary} value of the existing mapping
* @param newValue the {@link com.tangosol.util.Binary} value of the new mapping
*/
public BinaryReplaceMappingProcessor(Binary previousValue, Binary newValue)
{
super(previousValue);
this.m_binNewValue = newValue;
}
// ----- static factory methods -------------------------------------
/**
* Create an instance of {@link BinaryReplaceMappingProcessor}.
*
* @param previousValue the {@link com.tangosol.util.Binary} value of the existing mapping
* @param newValue the {@link com.tangosol.util.Binary} value of the new mapping
*
* @return an instance of {@link BinaryReplaceMappingProcessor}
*/
public static BinaryReplaceMappingProcessor create(Binary previousValue, Binary newValue)
{
return new BinaryReplaceMappingProcessor(previousValue, newValue);
}
// ----- Processor interface ----------------------------------------
@Override
public Boolean process(InvocableMap.Entry entry)
{
boolean result = false;
if (entry.isPresent())
{
Binary prevValue = ((BinaryEntry) entry).getBinaryValue();
if (prevValue.equals(getValue()))
{
((BinaryEntry) entry).updateBinaryValue(m_binNewValue);
result = true;
}
}
return result;
}
// ----- helper methods ---------------------------------------------
/**
* Return the new {@link Binary} value.
*
* @return the new {@link Binary} value
*/
protected Binary getNewValue()
{
return m_binNewValue;
}
// ----- ExternalizableLite interface -------------------------------
@Override
public void readExternal(DataInput in) throws IOException
{
super.readExternal(in);
m_binNewValue = ExternalizableHelper.readObject(in);
}
@Override
public void writeExternal(DataOutput out) throws IOException
{
super.writeExternal(out);
ExternalizableHelper.writeObject(out, m_binNewValue);
}
@Override
public void readExternal(PofReader pofReader) throws IOException
{
super.readExternal(pofReader);
m_binNewValue = pofReader.readBinary(5);
}
@Override
public void writeExternal(PofWriter pofWriter) throws IOException
{
super.writeExternal(pofWriter);
pofWriter.writeBinary(5, m_binNewValue);
}
// ----- data members -----------------------------------------------
/**
* New {@link Binary} value.
*/
protected Binary m_binNewValue;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy