@@ -50,18 +50,13 @@ internal class PCTScheduler : IScheduler
5050 /// <summary>
5151 /// List of prioritized operations.
5252 /// </summary>
53- private readonly List < AsyncOperation > PrioritizedOperations ;
54-
55- /// <summary>
56- /// Next execution point where the priority should be changed.
57- /// </summary>
58- private int _nextPriorityChangePoint ;
53+ private readonly List < AsyncOperation > PrioritizedOperations = new ( ) ;
5954
6055 /// <summary>
61- /// Number of switch points left (leq MaxPrioritySwitchPoints) .
56+ /// Set of priority change points .
6257 /// </summary>
63- private int _numSwitchPointsLeft ;
64-
58+ private readonly SortedSet < int > PriorityChangePoints = new ( ) ;
59+
6560 /// <summary>
6661 /// Initializes a new instance of the <see cref="PCTStrategy"/> class.
6762 /// </summary>
@@ -71,14 +66,11 @@ public PCTScheduler(int maxPrioritySwitchPoints, int scheduleLength, IRandomValu
7166 ScheduledSteps = 0 ;
7267 ScheduleLength = scheduleLength ;
7368 MaxPrioritySwitchPoints = maxPrioritySwitchPoints ;
74- PrioritizedOperations = new List < AsyncOperation > ( ) ;
75- double switchPointProbability = 0.1 ;
7669 if ( ScheduleLength != 0 )
7770 {
78- switchPointProbability = 1.0 * _numSwitchPointsLeft / ( ScheduleLength - ScheduledSteps + 1 ) ;
71+ PreparePriorityChangePoints ( ScheduleLength ) ;
7972 }
80- _nextPriorityChangePoint = Generator . Mutator . Utils . SampleGeometric ( switchPointProbability , random . NextDouble ( ) ) ;
81-
73+
8274 }
8375
8476 public virtual bool GetNextOperation ( AsyncOperation current , IEnumerable < AsyncOperation > ops ,
@@ -89,7 +81,7 @@ public virtual bool GetNextOperation(AsyncOperation current, IEnumerable<AsyncOp
8981 var enabledOperations = ops . Where ( op => op . Status is AsyncOperationStatus . Enabled ) . ToList ( ) ;
9082 if ( enabledOperations . Count == 0 )
9183 {
92- if ( _nextPriorityChangePoint == ScheduledSteps )
84+ if ( PriorityChangePoints . Contains ( ScheduledSteps ) )
9385 {
9486 MovePriorityChangePointForward ( ) ;
9587 }
@@ -98,19 +90,29 @@ public virtual bool GetNextOperation(AsyncOperation current, IEnumerable<AsyncOp
9890 }
9991
10092 var highestEnabledOp = GetPrioritizedOperation ( enabledOperations , current ) ;
101- if ( next is null )
102- {
103- next = highestEnabledOp ;
104- }
93+ next = highestEnabledOp ;
10594
10695 return true ;
10796 }
10897
98+ /// <summary>
99+ /// Moves the current priority change point forward. This is a useful
100+ /// optimization when a priority change point is assigned in either a
101+ /// sequential execution or a nondeterministic choice.
102+ /// </summary>
109103 private void MovePriorityChangePointForward ( )
110104 {
111- _nextPriorityChangePoint += 1 ;
112- Debug . WriteLine ( "<PCTLog> Moving priority change to '{0}'." , _nextPriorityChangePoint ) ;
105+ PriorityChangePoints . Remove ( ScheduledSteps ) ;
106+ var newPriorityChangePoint = ScheduledSteps + 1 ;
107+ while ( PriorityChangePoints . Contains ( newPriorityChangePoint ) )
108+ {
109+ newPriorityChangePoint ++ ;
110+ }
111+
112+ PriorityChangePoints . Add ( newPriorityChangePoint ) ;
113+ Debug . WriteLine ( "<PCTLog> Moving priority change to '{0}'." , newPriorityChangePoint ) ;
113114 }
115+
114116
115117 private AsyncOperation GetHighestPriorityEnabledOperation ( IEnumerable < AsyncOperation > choices )
116118 {
@@ -146,36 +148,21 @@ private AsyncOperation GetPrioritizedOperation(List<AsyncOperation> ops, AsyncOp
146148 }
147149
148150
149- var prioritizedSchedulable = GetHighestPriorityEnabledOperation ( ops ) ;
150- if ( _nextPriorityChangePoint == ScheduledSteps )
151+ if ( PriorityChangePoints . Contains ( ScheduledSteps ) )
151152 {
152153 if ( ops . Count == 1 )
153154 {
154155 MovePriorityChangePointForward ( ) ;
155156 }
156157 else
157158 {
158- PrioritizedOperations . Remove ( prioritizedSchedulable ) ;
159- PrioritizedOperations . Add ( prioritizedSchedulable ) ;
160- Debug . WriteLine ( "<PCTLog> Operation '{0}' changes to lowest priority." , prioritizedSchedulable ) ;
161-
162- _numSwitchPointsLeft -= 1 ;
163- // Update the next priority change point.
164- if ( _numSwitchPointsLeft > 0 )
165- {
166- double switchPointProbability = 0.1 ;
167- if ( ScheduleLength != 0 )
168- {
169- switchPointProbability = 1.0 * _numSwitchPointsLeft / ( ScheduleLength - ScheduledSteps + 1 ) ;
170- }
171-
172- _nextPriorityChangePoint =
173- Generator . Mutator . Utils . SampleGeometric ( switchPointProbability ,
174- _randomValueGenerator . NextDouble ( ) ) + ScheduledSteps ;
175- }
176-
159+ var priority = GetHighestPriorityEnabledOperation ( ops ) ;
160+ PrioritizedOperations . Remove ( priority ) ;
161+ PrioritizedOperations . Add ( priority ) ;
162+ Debug . WriteLine ( "<PCTLog> Operation '{0}' changes to lowest priority." , priority ) ;
177163 }
178164 }
165+ var prioritizedSchedulable = GetHighestPriorityEnabledOperation ( ops ) ;
179166
180167 if ( Debug . IsEnabled )
181168 {
@@ -209,18 +196,26 @@ public virtual bool PrepareForNextIteration()
209196 {
210197 ScheduleLength = Math . Max ( ScheduleLength , ScheduledSteps ) ;
211198 ScheduledSteps = 0 ;
212- _numSwitchPointsLeft = MaxPrioritySwitchPoints ;
213199
214200 PrioritizedOperations . Clear ( ) ;
215- double switchPointProbability = 0.1 ;
216- if ( ScheduleLength != 0 )
201+ PriorityChangePoints . Clear ( ) ;
202+ return true ;
203+ }
204+
205+ private void PreparePriorityChangePoints ( int step )
206+ {
207+ List < int > listOfInts = new List < int > ( ) ;
208+ for ( int i = 0 ; i < step ; i ++ )
217209 {
218- switchPointProbability = 1.0 * _numSwitchPointsLeft / ( ScheduleLength - ScheduledSteps + 1 ) ;
210+ listOfInts . Add ( i ) ;
219211 }
220212
221- _nextPriorityChangePoint =
222- Generator . Mutator . Utils . SampleGeometric ( switchPointProbability , _randomValueGenerator . NextDouble ( ) ) ;
223- return true ;
213+ for ( int i = 0 ; i < MaxPrioritySwitchPoints ; i ++ )
214+ {
215+ int index = _randomValueGenerator . Next ( listOfInts . Count ) ;
216+ PriorityChangePoints . Add ( listOfInts [ index ] ) ;
217+ listOfInts . RemoveAt ( index ) ;
218+ }
224219 }
225220
226221 public IScheduler Mutate ( )
0 commit comments