diff options
Diffstat (limited to 'src/main/java/events/implementations/VSTimestampTriggeredEvent.java')
| -rw-r--r-- | src/main/java/events/implementations/VSTimestampTriggeredEvent.java | 264 |
1 files changed, 264 insertions, 0 deletions
diff --git a/src/main/java/events/implementations/VSTimestampTriggeredEvent.java b/src/main/java/events/implementations/VSTimestampTriggeredEvent.java new file mode 100644 index 0000000..16d552d --- /dev/null +++ b/src/main/java/events/implementations/VSTimestampTriggeredEvent.java @@ -0,0 +1,264 @@ +package events.implementations; + +import core.VSInternalProcess; +import core.time.VSLamportTime; +import core.time.VSVectorTime; +import events.VSAbstractEvent; +import events.VSCopyableEvent; + +/** + * Abstract base class for timestamp-triggered events that fire when specific + * Lamport or vector clock conditions are met. + * + * @author Paul C. Buetow + */ +public abstract class VSTimestampTriggeredEvent extends VSAbstractEvent implements VSCopyableEvent { + + public enum TimestampType { + LAMPORT, + VECTOR + } + + public enum ComparisonOperator { + EQUAL, + GREATER_THAN, + LESS_THAN, + GREATER_EQUAL, + LESS_EQUAL + } + + protected TimestampType timestampType; + protected ComparisonOperator operator; + protected boolean hasTriggered; + + protected long targetLamportTime; + protected VSVectorTime targetVectorTime; + + /** + * Constructor for Lamport timestamp events + */ + public VSTimestampTriggeredEvent(long targetLamport, ComparisonOperator op) { + this.timestampType = TimestampType.LAMPORT; + this.targetLamportTime = targetLamport; + this.operator = op; + this.hasTriggered = false; + } + + /** + * Constructor for Vector timestamp events + */ + public VSTimestampTriggeredEvent(VSVectorTime targetVector, ComparisonOperator op) { + this.timestampType = TimestampType.VECTOR; + this.targetVectorTime = targetVector.getCopy(); + this.operator = op; + this.hasTriggered = false; + } + + /** + * Default constructor for serialization + */ + public VSTimestampTriggeredEvent() { + this.hasTriggered = false; + } + + @Override + public void onInit() { + setClassname(getClass().getName()); + } + + @Override + public void onStart() { + if (hasTriggered) { + return; + } + + VSInternalProcess internalProcess = (VSInternalProcess) process; + boolean conditionMet = false; + + if (timestampType == TimestampType.LAMPORT) { + conditionMet = checkLamportCondition(internalProcess); + } else if (timestampType == TimestampType.VECTOR) { + conditionMet = checkVectorCondition(internalProcess); + } + + if (conditionMet) { + hasTriggered = true; + onTimestampReached(); + } + } + + /** + * Check timestamp condition without triggering the event. + * Used by monitoring systems to test conditions. + */ + public boolean checkCondition(VSInternalProcess process) { + if (hasTriggered) { + return false; + } + + if (timestampType == TimestampType.LAMPORT) { + return checkLamportCondition(process); + } else if (timestampType == TimestampType.VECTOR) { + return checkVectorCondition(process); + } + + return false; + } + + /** + * Check if Lamport timestamp condition is met + */ + protected boolean checkLamportCondition(VSInternalProcess process) { + long currentLamport = process.getLamportTime(); + + switch (operator) { + case EQUAL: + return currentLamport == targetLamportTime; + case GREATER_THAN: + return currentLamport > targetLamportTime; + case LESS_THAN: + return currentLamport < targetLamportTime; + case GREATER_EQUAL: + return currentLamport >= targetLamportTime; + case LESS_EQUAL: + return currentLamport <= targetLamportTime; + default: + return false; + } + } + + /** + * Check if Vector timestamp condition is met + */ + protected boolean checkVectorCondition(VSInternalProcess process) { + VSVectorTime currentVector = process.getVectorTime(); + + if (currentVector == null || targetVectorTime == null) { + return false; + } + + switch (operator) { + case EQUAL: + return vectorTimesEqual(currentVector, targetVectorTime); + case GREATER_THAN: + return vectorTimeGreater(currentVector, targetVectorTime, false); + case LESS_THAN: + return vectorTimeGreater(targetVectorTime, currentVector, false); + case GREATER_EQUAL: + return vectorTimeGreater(currentVector, targetVectorTime, true); + case LESS_EQUAL: + return vectorTimeGreater(targetVectorTime, currentVector, true); + default: + return false; + } + } + + /** + * Check if two vector times are equal + */ + protected boolean vectorTimesEqual(VSVectorTime v1, VSVectorTime v2) { + int maxSize = Math.max(v1.size(), v2.size()); + + for (int i = 0; i < maxSize; i++) { + long val1 = i < v1.size() ? v1.get(i) : 0; + long val2 = i < v2.size() ? v2.get(i) : 0; + + if (val1 != val2) { + return false; + } + } + + return true; + } + + /** + * Check if v1 > v2 (or >= if allowEqual is true) using vector clock ordering + */ + protected boolean vectorTimeGreater(VSVectorTime v1, VSVectorTime v2, boolean allowEqual) { + int maxSize = Math.max(v1.size(), v2.size()); + boolean hasGreater = false; + + for (int i = 0; i < maxSize; i++) { + long val1 = i < v1.size() ? v1.get(i) : 0; + long val2 = i < v2.size() ? v2.get(i) : 0; + + if (val1 < val2) { + return false; + } else if (val1 > val2) { + hasGreater = true; + } + } + + return hasGreater || (allowEqual && vectorTimesEqual(v1, v2)); + } + + /** + * This method is called when the timestamp condition is met. + * Subclasses should override this to define the actual behavior. + */ + protected abstract void onTimestampReached(); + + @Override + protected String createShortname(String savedShortname) { + return "TimestampTrigger"; + } + + @Override + public void initCopy(VSAbstractEvent copy) { + if (copy instanceof VSTimestampTriggeredEvent) { + VSTimestampTriggeredEvent copyEvent = (VSTimestampTriggeredEvent) copy; + copyEvent.timestampType = this.timestampType; + copyEvent.operator = this.operator; + copyEvent.targetLamportTime = this.targetLamportTime; + copyEvent.hasTriggered = this.hasTriggered; + + if (this.targetVectorTime != null) { + copyEvent.targetVectorTime = this.targetVectorTime.getCopy(); + } + } + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(" [TimestampTrigger: "); + + if (timestampType == TimestampType.LAMPORT) { + sb.append("Lamport ").append(operator).append(" ").append(targetLamportTime); + } else { + sb.append("Vector ").append(operator).append(" ").append(targetVectorTime); + } + + if (hasTriggered) { + sb.append(" (TRIGGERED)"); + } + + sb.append("]"); + return sb.toString(); + } + + // Getters and setters + public TimestampType getTimestampType() { + return timestampType; + } + + public ComparisonOperator getOperator() { + return operator; + } + + public long getTargetLamportTime() { + return targetLamportTime; + } + + public VSVectorTime getTargetVectorTime() { + return targetVectorTime != null ? targetVectorTime.getCopy() : null; + } + + public boolean hasTriggered() { + return hasTriggered; + } + + public void reset() { + hasTriggered = false; + } +}
\ No newline at end of file |
