package rocks.inspectit.shared.cs.storage.nio;
import java.util.concurrent.FutureTask;
import java.util.concurrent.atomic.AtomicInteger;
import rocks.inspectit.shared.cs.storage.nio.read.ReadingCompletionHandler;
import rocks.inspectit.shared.cs.storage.nio.write.WritingCompletionHandler;
/**
* Completion runnable that know if the IO operation was successful.
*
* @author Ivan Senic
*
*/
public abstract class WriteReadCompletionRunnable implements Runnable {
/**
* Size that was tried to be read/written.
*/
private long attemptedWriteReadSize;
/**
* Position at which it was tried to be read/written.
*/
private long attemptedWriteReadPosition;
/**
* How much times a {@link #markSuccess()} and {@link #markFailed()} has to be called so that
* this runnable will be run.
*/
private int completeMarks;
/**
* Track of the number of success marks.
*/
private AtomicInteger successMarks = new AtomicInteger(0);
/**
* Track of the number of failed marks.
*/
private AtomicInteger failedMarks = new AtomicInteger(0);
/**
* Default constructor. Sets {@link #completeMarks} to 1.
*/
public WriteReadCompletionRunnable() {
this(1);
}
/**
* Constructor that sets the number of {@link #completeMarks}.
*
* @param completeMarks
* How much times a {@link #markSuccess()} and {@link #markFailed()} has to be called
* so that this runnable will be run.
*/
public WriteReadCompletionRunnable(int completeMarks) {
this.completeMarks = completeMarks;
}
/**
* Marks as success.
*/
public void markSuccess() {
successMarks.incrementAndGet();
}
/**
* Marks as failed.
*/
public void markFailed() {
failedMarks.incrementAndGet();
}
/**
* Denotes if the number of reported succeeded and failed operations is same as the number of
* expected marks.
*
* @return True if the {@link #run()} can be executed.
*/
public boolean isFinished() {
return (successMarks.get() + failedMarks.get()) == completeMarks;
}
/**
* Denotes if the write/read operation was completed successfully.
* <p>
* Note that this will always be correctly set before {@link #run()} is executed on the
* {@link WritingCompletionHandler} or {@link ReadingCompletionHandler}, thus it can be used in
* run to determine if the IO operation failed.
*
* @return If the write/read operation was completed successfully.
*/
public boolean isCompleted() {
return successMarks.get() == completeMarks;
}
/**
* Denotes if the write/read operation failed.
* <p>
* Note that this will always be correctly set before {@link #run()} is executed on the
* {@link WritingCompletionHandler} or {@link ReadingCompletionHandler}, thus it can be used in
* run to determine if the IO operation failed.
*
* @return If the write/read operation failed.
*/
public boolean isFailed() {
return failedMarks.get() > 0;
}
/**
* Gets {@link #attemptedWriteReadSize}.
*
* @return {@link #attemptedWriteReadSize}
*/
public long getAttemptedWriteReadSize() {
return attemptedWriteReadSize;
}
/**
* Sets {@link #attemptedWriteReadSize}.
*
* @param attemptedWriteReadSize
* New value for {@link #attemptedWriteReadSize}
*/
public void setAttemptedWriteReadSize(long attemptedWriteReadSize) {
this.attemptedWriteReadSize = attemptedWriteReadSize;
}
/**
* Gets {@link #attemptedWriteReadPosition}.
*
* @return {@link #attemptedWriteReadPosition}
*/
public long getAttemptedWriteReadPosition() {
return attemptedWriteReadPosition;
}
/**
* Sets {@link #attemptedWriteReadPosition}.
*
* @param attemptedWriteReadPosition
* New value for {@link #attemptedWriteReadPosition}
*/
public void setAttemptedWriteReadPosition(long attemptedWriteReadPosition) {
this.attemptedWriteReadPosition = attemptedWriteReadPosition;
}
/**
* Runnable future for the {@link WriteReadCompletionRunnable}.
*
* @author Ivan Senic
*
*/
public class RunnableFuture extends FutureTask<Void> {
/**
* Default constructor.
*/
public RunnableFuture() {
super(WriteReadCompletionRunnable.this, null);
}
/**
* Returns {@link WriteReadCompletionRunnable} future is associeated with.
*
* @return Returns {@link WriteReadCompletionRunnable}.
*/
public WriteReadCompletionRunnable getWriteReadCompletionRunnable() {
return WriteReadCompletionRunnable.this;
}
}
}