Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.infinispan.commands.write.ReplaceCommand Maven / Gradle / Ivy
package org.infinispan.commands.write;
import static org.infinispan.commons.util.Util.toStr;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import org.infinispan.commands.CommandInvocationId;
import org.infinispan.commands.MetadataAwareCommand;
import org.infinispan.commands.Visitor;
import org.infinispan.commons.marshall.MarshallUtil;
import org.infinispan.container.entries.MVCCEntry;
import org.infinispan.context.InvocationContext;
import org.infinispan.context.impl.FlagBitSets;
import org.infinispan.metadata.Metadata;
import org.infinispan.metadata.Metadatas;
import org.infinispan.notifications.cachelistener.CacheNotifier;
/**
* @author [email protected]
* @author Galder Zamarreño
* @since 4.0
*/
public class ReplaceCommand extends AbstractDataWriteCommand implements MetadataAwareCommand {
public static final byte COMMAND_ID = 11;
private Object oldValue;
private Object newValue;
private Metadata metadata;
private CacheNotifier notifier;
private boolean successful = true;
private ValueMatcher valueMatcher;
public ReplaceCommand() {
}
public ReplaceCommand(Object key, Object oldValue, Object newValue,
CacheNotifier notifier, Metadata metadata, long flagsBitSet,
CommandInvocationId commandInvocationId) {
super(key, flagsBitSet, commandInvocationId);
this.oldValue = oldValue;
this.newValue = newValue;
//noinspection unchecked
this.notifier = notifier;
this.metadata = metadata;
this.valueMatcher = oldValue != null ? ValueMatcher.MATCH_EXPECTED : ValueMatcher.MATCH_NON_NULL;
}
public void init(CacheNotifier notifier) {
//noinspection unchecked
this.notifier = notifier;
}
@Override
public Object acceptVisitor(InvocationContext ctx, Visitor visitor) throws Throwable {
return visitor.visitReplaceCommand(ctx, this);
}
@Override
public LoadType loadType() {
return LoadType.PRIMARY;
}
@Override
public Object perform(InvocationContext ctx) throws Throwable {
// It's not worth looking up the entry if we're never going to apply the change.
if (valueMatcher == ValueMatcher.MATCH_NEVER) {
successful = false;
return null;
}
//noinspection unchecked
MVCCEntry e = (MVCCEntry) ctx.lookupEntry(key);
// We need the null check as in non-tx caches we don't always wrap the entry on the origin
Object prevValue = e.getValue();
if (valueMatcher.matches(prevValue, oldValue, newValue)) {
e.setChanged(true);
Object old = e.setValue(newValue);
Metadatas.updateMetadata(e, metadata);
if (valueMatcher != ValueMatcher.MATCH_EXPECTED_OR_NEW) {
return returnValue(old, e.getMetadata(), true, ctx);
} else {
// Return the expected value when retrying
return returnValue(oldValue, e.getMetadata(), true, ctx);
}
}
return returnValue(null, null, false, ctx);
}
private Object returnValue(Object beingReplaced, Metadata previousMetadata, boolean successful,
InvocationContext ctx) {
this.successful = successful;
Object previousValue = oldValue == null ? beingReplaced : oldValue;
if (successful) {
notifier.notifyCacheEntryModified(key, newValue, metadata, previousValue, previousMetadata, true, ctx, this);
}
if (oldValue == null) {
return beingReplaced;
} else {
return successful;
}
}
@Override
public byte getCommandId() {
return COMMAND_ID;
}
@Override
public void writeTo(ObjectOutput output) throws IOException {
output.writeObject(key);
output.writeObject(oldValue);
output.writeObject(newValue);
output.writeObject(metadata);
MarshallUtil.marshallEnum(valueMatcher, output);
output.writeLong(FlagBitSets.copyWithoutRemotableFlags(getFlagsBitSet()));
CommandInvocationId.writeTo(output, commandInvocationId);
}
@Override
public void readFrom(ObjectInput input) throws IOException, ClassNotFoundException {
key = input.readObject();
oldValue = input.readObject();
newValue = input.readObject();
metadata = (Metadata) input.readObject();
valueMatcher = MarshallUtil.unmarshallEnum(input, ValueMatcher::valueOf);
setFlagsBitSet(input.readLong());
commandInvocationId = CommandInvocationId.readFrom(input);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
ReplaceCommand that = (ReplaceCommand) o;
if (metadata != null ? !metadata.equals(that.metadata) : that.metadata != null) return false;
if (newValue != null ? !newValue.equals(that.newValue) : that.newValue != null) return false;
return oldValue != null ? oldValue.equals(that.oldValue) : that.oldValue == null;
}
@Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + (oldValue != null ? oldValue.hashCode() : 0);
result = 31 * result + (newValue != null ? newValue.hashCode() : 0);
result = 31 * result + (metadata != null ? metadata.hashCode() : 0);
return result;
}
@Override
public boolean isSuccessful() {
return successful;
}
@Override
public boolean isConditional() {
return true;
}
@Override
public Metadata getMetadata() {
return metadata;
}
@Override
public void setMetadata(Metadata metadata) {
this.metadata = metadata;
}
public Object getOldValue() {
return oldValue;
}
public void setOldValue(Object oldValue) {
this.oldValue = oldValue;
}
public Object getNewValue() {
return newValue;
}
public void setNewValue(Object newValue) {
this.newValue = newValue;
}
@Override
public ValueMatcher getValueMatcher() {
return valueMatcher;
}
@Override
public void setValueMatcher(ValueMatcher valueMatcher) {
this.valueMatcher = valueMatcher;
}
@Override
public void fail() {
successful = false;
}
@Override
public final boolean isReturnValueExpected() {
return true;
}
@Override
public String toString() {
return "ReplaceCommand{" +
"key=" + toStr(key) +
", oldValue=" + toStr(oldValue) +
", newValue=" + toStr(newValue) +
", metadata=" + metadata +
", flags=" + printFlags() +
", commandInvocationId=" + CommandInvocationId.show(commandInvocationId) +
", successful=" + successful +
", valueMatcher=" + valueMatcher +
", topologyId=" + getTopologyId() +
'}';
}
@Override
public void initBackupWriteRpcCommand(BackupWriteRpcCommand command) {
command.setReplace(commandInvocationId, key, newValue, metadata, getFlagsBitSet(), getTopologyId());
}
}