summaryrefslogtreecommitdiff
path: root/src/main/java/events/implementations/VSVectorClockMonitor.java
blob: 05a15f5bbdeacd2c8ae9f272472823a109aee810 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package events.implementations;

import java.util.ArrayList;
import java.util.List;

import core.VSInternalProcess;
import core.time.VSVectorTime;

/**
 * A monitor that tracks vector clock changes and triggers events when
 * vector timestamp conditions are met. This monitor is integrated into
 * the process's vector clock update mechanism rather than being time-based.
 *
 * @author Paul C. Buetow
 */
public class VSVectorClockMonitor {
    
    private List<VSTimestampTriggeredEvent> vectorEvents;
    private VSInternalProcess process;
    private VSVectorTime lastCheckedVector;
    
    /**
     * Constructor
     */
    public VSVectorClockMonitor(VSInternalProcess process) {
        this.process = process;
        this.vectorEvents = new ArrayList<>();
        this.lastCheckedVector = null;
    }
    
    /**
     * Add a vector timestamp event to monitor
     */
    public void addVectorEvent(VSTimestampTriggeredEvent event) {
        if (event.getTimestampType() == VSTimestampTriggeredEvent.TimestampType.VECTOR && 
            !vectorEvents.contains(event)) {
            vectorEvents.add(event);
        }
    }
    
    /**
     * Remove a vector timestamp event from monitoring
     */
    public void removeVectorEvent(VSTimestampTriggeredEvent event) {
        vectorEvents.remove(event);
    }
    
    /**
     * Check all vector events when the vector clock changes.
     * This should be called whenever the process's vector clock is updated.
     */
    public void checkVectorEvents() {
        if (vectorEvents.isEmpty()) {
            return;
        }
        
        VSVectorTime currentVector = process.getVectorTime();
        
        // Only check if vector clock actually changed
        if (currentVector == null || vectorClockEquals(currentVector, lastCheckedVector)) {
            return;
        }
        
        List<VSTimestampTriggeredEvent> triggeredEvents = new ArrayList<>();
        
        for (VSTimestampTriggeredEvent event : vectorEvents) {
            if (!event.hasTriggered()) {
                // Initialize event if needed
                if (event.getProcess() == null) {
                    event.init(process);
                }
                
                // Check condition
                if (event.checkCondition(process)) {
                    event.onStart(); // This will trigger the event
                    triggeredEvents.add(event);
                    
                    process.log("Vector timestamp event triggered: " + event.toString());
                }
            }
        }
        
        // Remove triggered events
        vectorEvents.removeAll(triggeredEvents);
        
        // Update last checked vector
        lastCheckedVector = currentVector != null ? currentVector.getCopy() : null;
    }
    
    /**
     * Check if two vector clocks are equal
     */
    private boolean vectorClockEquals(VSVectorTime v1, VSVectorTime v2) {
        if (v1 == null && v2 == null) {
            return true;
        }
        if (v1 == null || v2 == null) {
            return false;
        }
        
        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;
    }
    
    /**
     * Get the number of vector events being monitored
     */
    public int getVectorEventCount() {
        return vectorEvents.size();
    }
    
    /**
     * Clear all vector events
     */
    public void clearVectorEvents() {
        vectorEvents.clear();
        lastCheckedVector = null;
    }
    
    /**
     * Get a copy of the monitored events list
     */
    public List<VSTimestampTriggeredEvent> getVectorEvents() {
        return new ArrayList<>(vectorEvents);
    }
}