package org.infinispan.commands.functional;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import org.infinispan.commons.api.functional.EntryView;
/**
* Helper class for marshalling, also hiding implementations of {@link Mutation} from the interface.
*/
final class Mutations {
private Mutations() {}
// No need to occupy externalizer ids when we have a limited set of options
static <K, V, R> void writeTo(ObjectOutput output, Mutation<K, V, R> mutation) throws IOException {
byte type = mutation.type();
output.writeByte(type);
switch (type) {
case ReadWrite.TYPE:
output.writeObject(((ReadWrite<K, V, ?>) mutation).f);
break;
case ReadWriteWithValue.TYPE:
output.writeObject(((ReadWriteWithValue<K, V, R>) mutation).value);
output.writeObject(((ReadWriteWithValue<K, V, R>) mutation).f);
break;
case Write.TYPE:
output.writeObject(((Write<K, V>) mutation).f);
break;
case WriteWithValue.TYPE:
output.writeObject(((WriteWithValue<K, V>) mutation).value);
output.writeObject(((WriteWithValue<K, V>) mutation).f);
break;
}
}
static <K, V> Mutation<K, V, ?> readFrom(ObjectInput input) throws IOException, ClassNotFoundException {
switch (input.readByte()) {
case ReadWrite.TYPE:
return new ReadWrite<>((Function<EntryView.ReadWriteEntryView<K, V>, ?>) input.readObject());
case ReadWriteWithValue.TYPE:
return new ReadWriteWithValue<>((V) input.readObject(), (BiFunction<V, EntryView.ReadWriteEntryView<K, V>, ?>) input.readObject());
case Write.TYPE:
return new Write<K, V>((Consumer<EntryView.WriteEntryView<V>>) input.readObject());
case WriteWithValue.TYPE:
return new WriteWithValue<K, V>((V) input.readObject(), (BiConsumer<V, EntryView.WriteEntryView<V>>) input.readObject());
default:
throw new IllegalStateException("Unknown type of mutation, broken input?");
}
}
static class ReadWrite<K, V, R> implements Mutation<K, V, R> {
static final byte TYPE = 0;
private final Function<EntryView.ReadWriteEntryView<K, V>, R> f;
public ReadWrite(Function<EntryView.ReadWriteEntryView<K, V>, R> f) {
this.f = f;
}
@Override
public byte type() {
return TYPE;
}
@Override
public R apply(EntryView.ReadWriteEntryView<K, V> view) {
return f.apply(view);
}
}
static class ReadWriteWithValue<K, V, R> implements Mutation<K, V, R> {
static final byte TYPE = 1;
private final V value;
private final BiFunction<V, EntryView.ReadWriteEntryView<K, V>, R> f;
public ReadWriteWithValue(V value, BiFunction<V, EntryView.ReadWriteEntryView<K, V>, R> f) {
this.value = value;
this.f = f;
}
@Override
public byte type() {
return TYPE;
}
@Override
public R apply(EntryView.ReadWriteEntryView<K, V> view) {
return f.apply(value, view);
}
}
static class Write<K, V> implements Mutation<K, V, Void> {
static final byte TYPE = 2;
private final Consumer<EntryView.WriteEntryView<V>> f;
public Write(Consumer<EntryView.WriteEntryView<V>> f) {
this.f = f;
}
@Override
public byte type() {
return TYPE;
}
@Override
public Void apply(EntryView.ReadWriteEntryView<K, V> view) {
f.accept(view);
return null;
}
}
static class WriteWithValue<K, V> implements Mutation<K, V, Void> {
static final byte TYPE = 3;
private final V value;
private final BiConsumer<V, EntryView.WriteEntryView<V>> f;
public WriteWithValue(V value, BiConsumer<V, EntryView.WriteEntryView<V>> f) {
this.value = value;
this.f = f;
}
@Override
public byte type() {
return TYPE;
}
@Override
public Void apply(EntryView.ReadWriteEntryView<K, V> view) {
f.accept(value, view);
return null;
}
}
}