/* * Copyright Terracotta, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ 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) throws MessageCodecException { return new byte[] { (byte) message.getOperation().ordinal(), (byte) message.getHoldType().ordinal() }; } @Override public LockOperation decodeMessage(byte[] bytes) throws MessageCodecException { return new LockOperation(Operation.values()[bytes[0]], HoldType.values()[bytes[1]]); } @Override public byte[] encodeResponse(LockTransition response) throws MessageCodecException { 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; } }