Free cookie consent management tool by TermsFeed Policy Generator

source: branches/NET40/sources/HeuristicLab.Optimization/3.3/BatchRun.cs @ 5138

Last change on this file since 5138 was 4722, checked in by swagner, 14 years ago

Merged cloning refactoring branch back into trunk (#922)

File size: 15.3 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Drawing;
25using HeuristicLab.Collections;
26using HeuristicLab.Common;
27using HeuristicLab.Core;
28using HeuristicLab.Data;
29using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
30
31namespace HeuristicLab.Optimization {
32  /// <summary>
33  /// A run in which an algorithm is executed a given number of times.
34  /// </summary>
35  [Item("Batch Run", "A run in which an algorithm is executed a given number of times.")]
36  [Creatable("Testing & Analysis")]
37  [StorableClass]
38  public sealed class BatchRun : NamedItem, IOptimizer, IStorableContent {
39    public string Filename { get; set; }
40
41    public override Image ItemImage {
42      get {
43        if (ExecutionState == ExecutionState.Prepared) return HeuristicLab.Common.Resources.VS2008ImageLibrary.ExecutablePrepared;
44        else if (ExecutionState == ExecutionState.Started) return HeuristicLab.Common.Resources.VS2008ImageLibrary.ExecutableStarted;
45        else if (ExecutionState == ExecutionState.Paused) return HeuristicLab.Common.Resources.VS2008ImageLibrary.ExecutablePaused;
46        else if (ExecutionState == ExecutionState.Stopped) return HeuristicLab.Common.Resources.VS2008ImageLibrary.ExecutableStopped;
47        else return HeuristicLab.Common.Resources.VS2008ImageLibrary.Event;
48      }
49    }
50
51    [Storable]
52    private ExecutionState executionState;
53    public ExecutionState ExecutionState {
54      get { return executionState; }
55      private set {
56        if (executionState != value) {
57          executionState = value;
58          OnExecutionStateChanged();
59          OnItemImageChanged();
60        }
61      }
62    }
63
64    [Storable]
65    private TimeSpan executionTime;
66    public TimeSpan ExecutionTime {
67      get {
68        if ((Algorithm != null) && (Algorithm.ExecutionState != ExecutionState.Stopped))
69          return executionTime + Algorithm.ExecutionTime;
70        else
71          return executionTime;
72      }
73      private set {
74        executionTime = value;
75        OnExecutionTimeChanged();
76      }
77    }
78
79    [Storable]
80    private IAlgorithm algorithm;
81    public IAlgorithm Algorithm {
82      get { return algorithm; }
83      set {
84        if (algorithm != value) {
85          if (algorithm != null) {
86            DeregisterAlgorithmEvents();
87            IEnumerable<IRun> runs = algorithm.Runs;
88            algorithm = null; //necessary to avoid removing the runs from the old algorithm
89            Runs.RemoveRange(runs);
90          }
91          algorithm = value;
92          if (algorithm != null) {
93            RegisterAlgorithmEvents();
94            Runs.AddRange(algorithm.Runs);
95          }
96          OnAlgorithmChanged();
97          Prepare();
98        }
99      }
100    }
101
102    [Storable]
103    private int repetitions;
104    public int Repetitions {
105      get { return repetitions; }
106      set {
107        if (repetitions != value) {
108          repetitions = value;
109          OnRepetitionsChanged();
110          if ((Algorithm != null) && (Algorithm.ExecutionState == ExecutionState.Stopped))
111            Prepare();
112        }
113      }
114    }
115    [Storable]
116    private int repetitionsCounter;
117
118    [Storable]
119    private RunCollection runs;
120    public RunCollection Runs {
121      get { return runs; }
122      private set {
123        if (value == null) throw new ArgumentNullException();
124        if (runs != value) {
125          if (runs != null) DeregisterRunsEvents();
126          runs = value;
127          if (runs != null) RegisterRunsEvents();
128        }
129      }
130    }
131
132    private bool stopPending;
133
134    public BatchRun()
135      : base() {
136      name = ItemName;
137      description = ItemDescription;
138      executionState = ExecutionState.Stopped;
139      executionTime = TimeSpan.Zero;
140      repetitions = 10;
141      repetitionsCounter = 0;
142      Runs = new RunCollection();
143      stopPending = false;
144    }
145    public BatchRun(string name)
146      : base(name) {
147      description = ItemDescription;
148      executionState = ExecutionState.Stopped;
149      executionTime = TimeSpan.Zero;
150      repetitions = 10;
151      repetitionsCounter = 0;
152      Runs = new RunCollection();
153      stopPending = false;
154    }
155    public BatchRun(string name, string description)
156      : base(name, description) {
157      executionState = ExecutionState.Stopped;
158      executionTime = TimeSpan.Zero;
159      repetitions = 10;
160      repetitionsCounter = 0;
161      Runs = new RunCollection();
162      stopPending = false;
163    }
164    [StorableConstructor]
165    private BatchRun(bool deserializing)
166      : base(deserializing) {
167      stopPending = false;
168    }
169    [StorableHook(HookType.AfterDeserialization)]
170    private void AfterDeserialization() {
171      Initialize();
172    }
173
174    private BatchRun(BatchRun original, Cloner cloner)
175      : base(original, cloner) {
176      executionState = original.executionState;
177      executionTime = original.executionTime;
178      algorithm = cloner.Clone(original.algorithm);
179      repetitions = original.repetitions;
180      repetitionsCounter = original.repetitionsCounter;
181      runs = cloner.Clone(original.runs);
182      stopPending = original.stopPending;
183      Initialize();
184    }
185    public override IDeepCloneable Clone(Cloner cloner) {
186      if (ExecutionState == ExecutionState.Started) throw new InvalidOperationException(string.Format("Clone not allowed in execution state \"{0}\".", ExecutionState));
187      return new BatchRun(this, cloner);
188    }
189
190    private void Initialize() {
191      if (algorithm != null) RegisterAlgorithmEvents();
192      if (runs != null) RegisterRunsEvents();
193    }
194
195    public void Prepare() {
196      Prepare(false);
197    }
198    public void Prepare(bool clearRuns) {
199      if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused) && (ExecutionState != ExecutionState.Stopped))
200        throw new InvalidOperationException(string.Format("Prepare not allowed in execution state \"{0}\".", ExecutionState));
201      if (Algorithm != null) {
202        repetitionsCounter = 0;
203        if (clearRuns) runs.Clear();
204        Algorithm.Prepare(clearRuns);
205      }
206    }
207    public void Start() {
208      if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused))
209        throw new InvalidOperationException(string.Format("Start not allowed in execution state \"{0}\".", ExecutionState));
210      if (Algorithm != null) Algorithm.Start();
211    }
212    public void Pause() {
213      if (ExecutionState != ExecutionState.Started)
214        throw new InvalidOperationException(string.Format("Pause not allowed in execution state \"{0}\".", ExecutionState));
215      if ((Algorithm != null) && (Algorithm.ExecutionState == ExecutionState.Started))
216        Algorithm.Pause();
217    }
218    public void Stop() {
219      if ((ExecutionState != ExecutionState.Started) && (ExecutionState != ExecutionState.Paused))
220        throw new InvalidOperationException(string.Format("Stop not allowed in execution state \"{0}\".", ExecutionState));
221      stopPending = true;
222      if ((Algorithm != null) &&
223          ((Algorithm.ExecutionState == ExecutionState.Started) || (Algorithm.ExecutionState == ExecutionState.Paused)))
224        Algorithm.Stop();
225    }
226
227    #region Events
228    public event EventHandler ExecutionStateChanged;
229    private void OnExecutionStateChanged() {
230      EventHandler handler = ExecutionStateChanged;
231      if (handler != null) handler(this, EventArgs.Empty);
232    }
233    public event EventHandler ExecutionTimeChanged;
234    private void OnExecutionTimeChanged() {
235      EventHandler handler = ExecutionTimeChanged;
236      if (handler != null) handler(this, EventArgs.Empty);
237    }
238    public event EventHandler AlgorithmChanged;
239    private void OnAlgorithmChanged() {
240      EventHandler handler = AlgorithmChanged;
241      if (handler != null) handler(this, EventArgs.Empty);
242    }
243    public event EventHandler RepetitionsChanged;
244    private void OnRepetitionsChanged() {
245      EventHandler handler = RepetitionsChanged;
246      if (handler != null) handler(this, EventArgs.Empty);
247    }
248    public event EventHandler Prepared;
249    private void OnPrepared() {
250      ExecutionState = ExecutionState.Prepared;
251      EventHandler handler = Prepared;
252      if (handler != null) handler(this, EventArgs.Empty);
253    }
254    public event EventHandler Started;
255    private void OnStarted() {
256      ExecutionState = ExecutionState.Started;
257      EventHandler handler = Started;
258      if (handler != null) handler(this, EventArgs.Empty);
259    }
260    public event EventHandler Paused;
261    private void OnPaused() {
262      ExecutionState = ExecutionState.Paused;
263      EventHandler handler = Paused;
264      if (handler != null) handler(this, EventArgs.Empty);
265    }
266    public event EventHandler Stopped;
267    private void OnStopped() {
268      ExecutionState = ExecutionState.Stopped;
269      EventHandler handler = Stopped;
270      if (handler != null) handler(this, EventArgs.Empty);
271    }
272    public event EventHandler<EventArgs<Exception>> ExceptionOccurred;
273    private void OnExceptionOccurred(Exception exception) {
274      EventHandler<EventArgs<Exception>> handler = ExceptionOccurred;
275      if (handler != null) handler(this, new EventArgs<Exception>(exception));
276    }
277
278    private void RegisterAlgorithmEvents() {
279      algorithm.ExceptionOccurred += new EventHandler<EventArgs<Exception>>(Algorithm_ExceptionOccurred);
280      algorithm.ExecutionTimeChanged += new EventHandler(Algorithm_ExecutionTimeChanged);
281      algorithm.Paused += new EventHandler(Algorithm_Paused);
282      algorithm.Prepared += new EventHandler(Algorithm_Prepared);
283      algorithm.Started += new EventHandler(Algorithm_Started);
284      algorithm.Stopped += new EventHandler(Algorithm_Stopped);
285      algorithm.Runs.CollectionReset += new CollectionItemsChangedEventHandler<IRun>(Algorithm_Runs_CollectionReset);
286      algorithm.Runs.ItemsAdded += new CollectionItemsChangedEventHandler<IRun>(Algorithm_Runs_ItemsAdded);
287      algorithm.Runs.ItemsRemoved += new CollectionItemsChangedEventHandler<IRun>(Algorithm_Runs_ItemsRemoved);
288    }
289    private void DeregisterAlgorithmEvents() {
290      algorithm.ExceptionOccurred -= new EventHandler<EventArgs<Exception>>(Algorithm_ExceptionOccurred);
291      algorithm.ExecutionTimeChanged -= new EventHandler(Algorithm_ExecutionTimeChanged);
292      algorithm.Paused -= new EventHandler(Algorithm_Paused);
293      algorithm.Prepared -= new EventHandler(Algorithm_Prepared);
294      algorithm.Started -= new EventHandler(Algorithm_Started);
295      algorithm.Stopped -= new EventHandler(Algorithm_Stopped);
296      algorithm.Runs.CollectionReset -= new CollectionItemsChangedEventHandler<IRun>(Algorithm_Runs_CollectionReset);
297      algorithm.Runs.ItemsAdded -= new CollectionItemsChangedEventHandler<IRun>(Algorithm_Runs_ItemsAdded);
298      algorithm.Runs.ItemsRemoved -= new CollectionItemsChangedEventHandler<IRun>(Algorithm_Runs_ItemsRemoved);
299    }
300    private void Algorithm_ExceptionOccurred(object sender, EventArgs<Exception> e) {
301      OnExceptionOccurred(e.Value);
302    }
303    private void Algorithm_ExecutionTimeChanged(object sender, EventArgs e) {
304      OnExecutionTimeChanged();
305    }
306    private void Algorithm_Paused(object sender, EventArgs e) {
307      OnPaused();
308    }
309    private void Algorithm_Prepared(object sender, EventArgs e) {
310      if ((ExecutionState == ExecutionState.Paused) || (ExecutionState == ExecutionState.Stopped))
311        OnPrepared();
312    }
313    private void Algorithm_Started(object sender, EventArgs e) {
314      stopPending = false;
315      if (ExecutionState != ExecutionState.Started)
316        OnStarted();
317    }
318    private void Algorithm_Stopped(object sender, EventArgs e) {
319      repetitionsCounter++;
320
321      if (!stopPending && (repetitionsCounter < repetitions)) {
322        Algorithm.Prepare();
323        Algorithm.Start();
324      } else {
325        OnStopped();
326      }
327    }
328    private void Algorithm_Runs_CollectionReset(object sender, CollectionItemsChangedEventArgs<IRun> e) {
329      Runs.RemoveRange(e.OldItems);
330      Runs.AddRange(e.Items);
331    }
332    private void Algorithm_Runs_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IRun> e) {
333      Runs.AddRange(e.Items);
334    }
335    private void Algorithm_Runs_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IRun> e) {
336      Runs.RemoveRange(e.Items);
337    }
338
339    private void RegisterRunsEvents() {
340      runs.CollectionReset += new CollectionItemsChangedEventHandler<IRun>(Runs_CollectionReset);
341      runs.ItemsAdded += new CollectionItemsChangedEventHandler<IRun>(Runs_ItemsAdded);
342      runs.ItemsRemoved += new CollectionItemsChangedEventHandler<IRun>(Runs_ItemsRemoved);
343    }
344
345    private void DeregisterRunsEvents() {
346      runs.CollectionReset -= new CollectionItemsChangedEventHandler<IRun>(Runs_CollectionReset);
347      runs.ItemsAdded -= new CollectionItemsChangedEventHandler<IRun>(Runs_ItemsAdded);
348      runs.ItemsRemoved -= new CollectionItemsChangedEventHandler<IRun>(Runs_ItemsRemoved);
349    }
350    private void Runs_CollectionReset(object sender, CollectionItemsChangedEventArgs<IRun> e) {
351      foreach (IRun run in e.OldItems) {
352        IItem item;
353        run.Results.TryGetValue("Execution Time", out item);
354        TimeSpanValue executionTime = item as TimeSpanValue;
355        if (executionTime != null) ExecutionTime -= executionTime.Value;
356      }
357      if (Algorithm != null) Algorithm.Runs.RemoveRange(e.OldItems);
358      foreach (IRun run in e.Items) {
359        IItem item;
360        run.Results.TryGetValue("Execution Time", out item);
361        TimeSpanValue executionTime = item as TimeSpanValue;
362        if (executionTime != null) ExecutionTime += executionTime.Value;
363      }
364    }
365    private void Runs_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IRun> e) {
366      foreach (IRun run in e.Items) {
367        IItem item;
368        run.Results.TryGetValue("Execution Time", out item);
369        TimeSpanValue executionTime = item as TimeSpanValue;
370        if (executionTime != null) ExecutionTime += executionTime.Value;
371      }
372    }
373    private void Runs_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IRun> e) {
374      foreach (IRun run in e.Items) {
375        IItem item;
376        run.Results.TryGetValue("Execution Time", out item);
377        TimeSpanValue executionTime = item as TimeSpanValue;
378        if (executionTime != null) ExecutionTime -= executionTime.Value;
379      }
380      if (Algorithm != null) Algorithm.Runs.RemoveRange(e.Items);
381    }
382    #endregion
383  }
384}
Note: See TracBrowser for help on using the repository browser.