package org.ehcache.clustered.common.internal.lock;
import org.terracotta.entity.EntityMessage;
import org.terracotta.entity.EntityResponse;
import org.terracotta.entity.MessageCodec;
import org.terracotta.entity.MessageCodecException;
public class LockMessaging {
private static final MessageCodec<LockOperation, LockTransition> CODEC = new MessageCodec<LockOperation, LockTransition>() {
@Override
public byte[] encodeMessage(LockOperation message) {
return new byte[] {
(byte) message.getOperation().ordinal(),
(byte) message.getHoldType().ordinal()
};
}
@Override
public LockOperation decodeMessage(byte[] bytes) {
return new LockOperation(Operation.values()[bytes[0]], HoldType.values()[bytes[1]]);
}
@Override
public byte[] encodeResponse(LockTransition response) {
if (response.isAcquired()) {
return new byte[] {0x00};
} else if (response.isReleased()) {
return new byte[] {0x01};
} else {
return new byte[] {0x02};
}
}
@Override
public LockTransition decodeResponse(byte[] bytes) throws MessageCodecException {
switch (bytes[0]) {
case 0x00: return new LockTransition(true, false);
case 0x01: return new LockTransition(false, true);
case 0x02: return new LockTransition(false, false);
default: throw new MessageCodecException("Unexpected transition encoding", null);
}
}
};
public static MessageCodec<LockOperation, LockTransition> codec() {
return CODEC;
}
public static LockOperation tryLock(HoldType type) {
return new LockOperation(Operation.TRY_ACQUIRE, type);
}
public static LockOperation lock(HoldType type) {
return new LockOperation(Operation.ACQUIRE, type);
}
public static LockOperation unlock(HoldType type) {
return new LockOperation(Operation.RELEASE, type);
}
public static LockTransition acquired() {
return new LockTransition(true, false);
}
public static LockTransition released() {
return new LockTransition(false, true);
}
public static LockTransition empty() {
return new LockTransition(false, false);
}
public static class LockOperation implements EntityMessage {
private final Operation operation;
private final HoldType type;
LockOperation(Operation operation, HoldType type) {
this.operation = operation;
this.type = type;
}
public Operation getOperation() {
return operation;
}
public HoldType getHoldType() {
return type;
}
}
public static class LockTransition implements EntityResponse {
private final boolean acquired;
private final boolean released;
private LockTransition(boolean acquired, boolean released) {
this.acquired = acquired;
this.released = released;
}
public boolean isAcquired() {
return acquired;
}
public boolean isReleased() {
return released;
}
}
public enum HoldType {
WRITE, READ
}
public enum Operation {
ACQUIRE, TRY_ACQUIRE, RELEASE
}
}