Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ExperimentManager/HiveJobClient.cs @ 5675

Last change on this file since 5675 was 5675, checked in by cneumuel, 12 years ago

#1233

  • improved treeview for hive jobs
File size: 25.8 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 System.Linq;
26using HeuristicLab.Clients.Hive.Jobs;
27using HeuristicLab.Collections;
28using HeuristicLab.Common;
29using HeuristicLab.Core;
30using HeuristicLab.Optimization;
31using HeuristicLab.PluginInfrastructure;
32
33namespace HeuristicLab.Clients.Hive {
34
35  [Item("Hive Job", "Represents a hive job.")]
36  public class HiveJob : NamedItem, IItemTree {
37    private static object locker = new object();
38
39    public override Image ItemImage {
40      get {
41        if (job.Id == Guid.Empty) { // not yet uploaded
42          return HeuristicLab.Common.Resources.VSImageLibrary.Event;
43        } else {
44          if (job.State == JobState.Waiting) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutablePrepared;
45          else if (job.State == JobState.Calculating) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutableStarted;
46          else if (job.State == JobState.Transferring) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutableStarted;
47          else if (job.State == JobState.Aborted) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutableStopped;
48          else if (job.State == JobState.Failed) return HeuristicLab.Common.Resources.VSImageLibrary.Error;
49          else if (job.State == JobState.Finished) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutableStopped;
50          else return HeuristicLab.Common.Resources.VSImageLibrary.Event;
51        }
52      }
53    }
54
55    private Job job;
56    public Job Job {
57      get { return job; }
58      set {
59        if (job != value) {
60          job = value;
61          OnJobChanged();
62          OnToStringChanged();
63          OnItemImageChanged();
64        }
65      }
66    }
67
68    private OptimizerJob optimizerJob;
69    public OptimizerJob OptimizerJob {
70      get { return optimizerJob; }
71      private set {
72        if (optimizerJob != null && syncJobsWithOptimizers) {
73          this.childHiveJobs.Clear();
74        }
75        if (optimizerJob != value) {
76          DergisterOptimizerEvents();
77          optimizerJob = value;
78          if (optimizerJob.ExecutionState == ExecutionState.Stopped) {
79            IsFinishedOptimizerDownloaded = true;
80          }
81          RegisterOptimizerEvents();
82          OnOptimizerJobChanged();
83        }
84      }
85    }
86
87    private ItemList<HiveJob> childHiveJobs;
88    public ReadOnlyItemList<HiveJob> ChildHiveJobs {
89      get { return childHiveJobs.AsReadOnly(); }
90    }
91
92    private bool isFinishedOptimizerDownloaded;
93    public bool IsFinishedOptimizerDownloaded {
94      get { return isFinishedOptimizerDownloaded; }
95      set {
96        if (isFinishedOptimizerDownloaded != value) {
97          isFinishedOptimizerDownloaded = value;
98          OnIsFinishedOptimizerDownloadedChanged();
99        }
100      }
101    }
102
103    private bool syncJobsWithOptimizers = true;
104
105    public HiveJob() {
106      this.Job = new Job() {
107        CoresNeeded = 1,
108        MemoryNeeded = 0
109      };
110      job.SetState(JobState.Offline);
111      this.childHiveJobs = new ItemList<HiveJob>();
112      syncJobsWithOptimizers = true;
113      RegisterChildHiveJobEvents();
114    }
115
116    public HiveJob(OptimizerJob optimizerJob, bool autoCreateChildHiveJobs)
117      : this() {
118      this.syncJobsWithOptimizers = autoCreateChildHiveJobs;
119      this.OptimizerJob = optimizerJob;
120      this.syncJobsWithOptimizers = true;
121    }
122
123    public HiveJob(IOptimizer optimizer)
124      : this() {
125      this.OptimizerJob = new OptimizerJob(optimizer);
126    }
127
128    public HiveJob(Job job, JobData jobData, bool autoCreateChildHiveJobs) {
129      this.syncJobsWithOptimizers = autoCreateChildHiveJobs;
130      this.Job = job;
131      try {
132        this.OptimizerJob = PersistenceUtil.Deserialize<OptimizerJob>(jobData.Data);
133      }
134      catch {
135        this.OptimizerJob = null;
136      }
137      this.childHiveJobs = new ItemList<HiveJob>();
138      this.syncJobsWithOptimizers = true;
139      RegisterChildHiveJobEvents();
140    }
141
142    protected HiveJob(HiveJob original, Cloner cloner)
143      : base(original, cloner) {
144      this.Job = cloner.Clone(original.job);
145      this.OptimizerJob = cloner.Clone(original.OptimizerJob);
146    }
147    public override IDeepCloneable Clone(Cloner cloner) {
148      return new HiveJob(this, cloner);
149    }
150
151    /// <summary>
152    /// if this.Optimizer is an experiment
153    ///   Uses the child-optimizers of this.HiveJob and creates HiveJob-childs
154    /// if this.Optimizer is a batchrun
155    ///   Creates a number of child-jobs according to repetitions
156    /// </summary>
157    private void UpdateChildHiveJobs() {
158      if (Job != null && syncJobsWithOptimizers) {
159        if (OptimizerJob.Optimizer is Optimization.Experiment) {
160          Optimization.Experiment experiment = (Optimization.Experiment)OptimizerJob.Optimizer;
161          foreach (IOptimizer childOpt in experiment.Optimizers) {
162            this.childHiveJobs.Add(new HiveJob(childOpt));
163          }
164        } else if (OptimizerJob.Optimizer is Optimization.BatchRun) {
165          Optimization.BatchRun batchRun = OptimizerJob.OptimizerAsBatchRun;
166          if (batchRun.Optimizer != null) {
167            while (this.childHiveJobs.Count < batchRun.Repetitions) {
168              this.childHiveJobs.Add(new HiveJob(batchRun.Optimizer));
169            }
170            while (this.childHiveJobs.Count > batchRun.Repetitions) {
171              this.childHiveJobs.Remove(this.childHiveJobs.Last());
172            }
173          }
174        }
175      }
176    }
177
178    private void RegisterOptimizerEvents() {
179      if (OptimizerJob != null) {
180        if (OptimizerJob.Optimizer is Optimization.Experiment) {
181          Optimization.Experiment experiment = OptimizerJob.OptimizerAsExperiment;
182          experiment.Optimizers.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsAdded);
183          experiment.Optimizers.ItemsReplaced += new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsReplaced);
184          experiment.Optimizers.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsRemoved);
185          experiment.Optimizers.CollectionReset += new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_CollectionReset);
186        } else if (OptimizerJob.Optimizer is Optimization.BatchRun) {
187          Optimization.BatchRun batchRun = OptimizerJob.OptimizerAsBatchRun;
188          batchRun.RepetitionsChanged += new EventHandler(batchRun_RepetitionsChanged);
189          batchRun.OptimizerChanged += new EventHandler(batchRun_OptimizerChanged);
190        }
191        OptimizerJob.ComputeInParallelChanged += new EventHandler(OptimizerJob_ComputeInParallelChanged);
192        OptimizerJob.ToStringChanged += new EventHandler(OptimizerJob_ToStringChanged);
193      }
194    }
195    private void DergisterOptimizerEvents() {
196      if (OptimizerJob != null) {
197        if (OptimizerJob.Optimizer is Optimization.Experiment) {
198          Optimization.Experiment experiment = OptimizerJob.OptimizerAsExperiment;
199          experiment.Optimizers.ItemsAdded -= new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsAdded);
200          experiment.Optimizers.ItemsReplaced -= new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsReplaced);
201          experiment.Optimizers.ItemsRemoved -= new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsRemoved);
202          experiment.Optimizers.CollectionReset -= new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_CollectionReset);
203        } else if (OptimizerJob.Optimizer is Optimization.BatchRun) {
204          Optimization.BatchRun batchRun = OptimizerJob.OptimizerAsBatchRun;
205          batchRun.RepetitionsChanged -= new EventHandler(batchRun_RepetitionsChanged);
206          batchRun.OptimizerChanged -= new EventHandler(batchRun_OptimizerChanged);
207        }
208        OptimizerJob.ComputeInParallelChanged -= new EventHandler(OptimizerJob_ComputeInParallelChanged);
209        OptimizerJob.ToStringChanged -= new EventHandler(OptimizerJob_ToStringChanged);
210      }
211    }
212
213    private void RegisterChildHiveJobEvents() {
214      this.childHiveJobs.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<HiveJob>>(OnItemsAdded);
215      this.childHiveJobs.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<HiveJob>>(OnItemsRemoved);
216      this.childHiveJobs.CollectionReset += new CollectionItemsChangedEventHandler<IndexedItem<HiveJob>>(OnCollectionReset);
217    }
218    private void DeregisterChildHiveJobEvents() {
219      this.childHiveJobs.ItemsAdded -= new CollectionItemsChangedEventHandler<IndexedItem<HiveJob>>(OnItemsAdded);
220      this.childHiveJobs.ItemsRemoved -= new CollectionItemsChangedEventHandler<IndexedItem<HiveJob>>(OnItemsRemoved);
221      this.childHiveJobs.CollectionReset -= new CollectionItemsChangedEventHandler<IndexedItem<HiveJob>>(OnCollectionReset);
222    }
223
224    private void batchRun_OptimizerChanged(object sender, EventArgs e) {
225      if (syncJobsWithOptimizers) {
226        this.childHiveJobs.Clear();
227        UpdateChildHiveJobs();
228      }
229    }
230
231    private void batchRun_RepetitionsChanged(object sender, EventArgs e) {
232      if (syncJobsWithOptimizers) {
233        UpdateChildHiveJobs();
234      }
235    }
236
237    private void OptimizerJob_ToStringChanged(object sender, EventArgs e) {
238      this.OnToStringChanged();
239    }
240
241    private void Optimizers_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<IOptimizer>> e) {
242      if (syncJobsWithOptimizers && this.OptimizerJob.ComputeInParallel) {
243        foreach (var item in e.Items) {
244          if (GetChildByOptimizer(item.Value) == null && item.Value.Name != "Placeholder") {
245            this.childHiveJobs.Add(new HiveJob(item.Value));
246          }
247        }
248      }
249    }
250    private void Optimizers_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<IOptimizer>> e) {
251      if (syncJobsWithOptimizers && this.OptimizerJob.ComputeInParallel) {
252        foreach (var item in e.OldItems) {
253          this.childHiveJobs.Remove(this.GetChildByOptimizer(item.Value));
254        }
255        foreach (var item in e.Items) {
256          if (GetChildByOptimizer(item.Value) == null && item.Value.Name != "Placeholder") {
257            this.childHiveJobs.Add(new HiveJob(item.Value));
258          }
259        }
260      }
261    }
262    private void Optimizers_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<IOptimizer>> e) {
263      if (syncJobsWithOptimizers && this.OptimizerJob.ComputeInParallel) {
264        foreach (var item in e.Items) {
265          this.childHiveJobs.Remove(this.GetChildByOptimizer(item.Value));
266        }
267      }
268    }
269    private void Optimizers_CollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedItem<IOptimizer>> e) {
270      if (syncJobsWithOptimizers && this.OptimizerJob.ComputeInParallel) {
271        foreach (var item in e.Items) {
272          this.childHiveJobs.Remove(this.GetChildByOptimizer(item.Value));
273        }
274      }
275    }
276
277    private void OptimizerJob_ComputeInParallelChanged(object sender, EventArgs e) {
278      if (OptimizerJob != null && syncJobsWithOptimizers) {
279        if (OptimizerJob.ComputeInParallel) {
280          // child-hive jobs are not yet created, so create them according to the child-optimizers
281          this.UpdateChildHiveJobs();
282        } else {
283          // child-hive jobs need to be deleted
284          this.childHiveJobs.Clear();
285        }
286      }
287    }
288
289    public void AddChildHiveJob(HiveJob hiveJob) {
290      this.childHiveJobs.Add(hiveJob);
291      syncJobsWithOptimizers = false;
292      if (this.OptimizerJob != null && hiveJob.OptimizerJob != null) {
293        if (this.OptimizerJob.Optimizer is Optimization.Experiment) {
294          if (!this.OptimizerJob.OptimizerAsExperiment.Optimizers.Contains(hiveJob.OptimizerJob.Optimizer)) {
295            UpdateOptimizerInExperiment(this.OptimizerJob.OptimizerAsExperiment, hiveJob.OptimizerJob);
296          }
297        } else if (this.OptimizerJob.Optimizer is Optimization.BatchRun) {
298          UpdateOptimizerInBatchRun(this.OptimizerJob.OptimizerAsBatchRun, hiveJob.OptimizerJob);
299        }
300      }
301      syncJobsWithOptimizers = true;
302    }
303
304    /// <summary>
305    /// if this.Optimizer is Experiment
306    ///   replace the child-optimizer in the experiment
307    /// if this.Optimizer is BatchRun
308    ///   add the runs from the optimizerJob to the batchrun and replace the Optimizer
309    /// </summary>
310    public void UpdateChildOptimizer(OptimizerJob optimizerJob, Guid childJobId) {
311      syncJobsWithOptimizers = false; // don't sync with optimizers during this method
312      bool childIsFinishedOptimizerDownloaded = false;
313
314      if (this.OptimizerJob != null && this.OptimizerJob.Optimizer != null) {
315        if (this.OptimizerJob.Optimizer is Optimization.Experiment) {
316          UpdateOptimizerInExperiment(this.OptimizerJob.OptimizerAsExperiment, optimizerJob);
317          childIsFinishedOptimizerDownloaded = true;
318        } else if (this.OptimizerJob.Optimizer is Optimization.BatchRun) {
319          UpdateOptimizerInBatchRun(this.OptimizerJob.OptimizerAsBatchRun, optimizerJob);
320          if (this.OptimizerJob.OptimizerAsBatchRun.Repetitions == this.OptimizerJob.Optimizer.Runs.Count) {
321            childIsFinishedOptimizerDownloaded = true;
322          }
323        } else {
324          childIsFinishedOptimizerDownloaded = optimizerJob.Optimizer.ExecutionState == ExecutionState.Stopped;
325        }
326      }
327
328      HiveJob child = this.ChildHiveJobs.Single(j => j.Job.Id == childJobId);
329      if (!optimizerJob.ComputeInParallel) {
330        child.syncJobsWithOptimizers = false;
331        child.OptimizerJob = optimizerJob;
332        child.syncJobsWithOptimizers = true;
333      }
334      if (childIsFinishedOptimizerDownloaded) {
335        child.IsFinishedOptimizerDownloaded = true;
336      }
337      syncJobsWithOptimizers = true;
338    }
339
340    /// <summary>
341    /// Adds the runs from the optimizerJob to the batchrun and replaces the Optimizer
342    /// Sideeffect: the optimizerJob.Optimizer will be prepared (scopes are deleted and executionstate will be reset)
343    /// </summary>
344    private void UpdateOptimizerInBatchRun(BatchRun batchRun, OptimizerJob optimizerJob) {
345      if (batchRun.Optimizer == null) {
346        batchRun.Optimizer = (IOptimizer)optimizerJob.Optimizer; // only set the first optimizer as Optimizer. if every time the Optimizer would be set, the runs would be cleared each time
347      }
348      foreach (IRun run in optimizerJob.Optimizer.Runs) {
349        if (!batchRun.Runs.Contains(run))
350          batchRun.Runs.Add(run);
351      }
352    }
353
354    /// <summary>
355    /// replace the child-optimizer in the experiment
356    /// Sideeffect: the optimizerJob.Optimizer will be prepared (scopes are deleted and executionstate will be reset)
357    /// </summary>
358    private void UpdateOptimizerInExperiment(Optimization.Experiment experiment, OptimizerJob optimizerJob) {
359      if (optimizerJob.IndexInParentOptimizerList < 0)
360        throw new IndexOutOfRangeException("IndexInParentOptimizerList must be equal or greater than zero! The Job is invalid and the optimizer-tree cannot be reassembled.");
361
362      while (experiment.Optimizers.Count < optimizerJob.IndexInParentOptimizerList) {
363        experiment.Optimizers.Add(new UserDefinedAlgorithm("Placeholder")); // add dummy-entries to Optimizers so that its possible to insert the optimizerJob at the correct position
364      }
365      if (experiment.Optimizers.Count < optimizerJob.IndexInParentOptimizerList + 1) {
366        experiment.Optimizers.Add(optimizerJob.Optimizer);
367      } else {
368        // if ComputeInParallel==true, don't replace the optimizer (except it is still a Placeholder)
369        // this is because Jobs with ComputeInParallel get submitted to hive with their child-optimizers deleted
370        if (!optimizerJob.ComputeInParallel || experiment.Optimizers[optimizerJob.IndexInParentOptimizerList].Name == "Placeholder") {
371          experiment.Optimizers[optimizerJob.IndexInParentOptimizerList] = optimizerJob.Optimizer;
372        }
373      }
374    }
375
376    /// <summary>
377    /// Sets the IndexInParentOptimizerList property of the OptimizerJob
378    /// according to the position in the OptimizerList of the parentHiveJob.Job
379    /// Recursively updates all the child-jobs as well
380    /// </summary>
381    internal void SetIndexInParentOptimizerList(HiveJob parentHiveJob) {
382      if (parentHiveJob != null) {
383        if (parentHiveJob.OptimizerJob.Optimizer is Optimization.Experiment) {
384          this.OptimizerJob.IndexInParentOptimizerList = parentHiveJob.OptimizerJob.OptimizerAsExperiment.Optimizers.IndexOf(this.OptimizerJob.Optimizer);
385        } else if (parentHiveJob.OptimizerJob.Optimizer is Optimization.BatchRun) {
386          this.OptimizerJob.IndexInParentOptimizerList = 0;
387        } else {
388          throw new NotSupportedException("Only Experiment and BatchRuns are supported");
389        }
390      }
391      foreach (HiveJob child in childHiveJobs) {
392        child.SetIndexInParentOptimizerList(this);
393      }
394    }
395
396    public override string ToString() {
397      if (optimizerJob != null) {
398        return optimizerJob.ToString();
399      } else {
400        return base.ToString();
401      }
402    }
403
404    public void UpdateFromLightweightJob(LightweightJob lightweightJob) {
405      if (lightweightJob != null) {
406        job.Id = lightweightJob.Id;
407        job.Id = lightweightJob.Id;
408        job.ExecutionTime = lightweightJob.ExecutionTime;
409        job.State = lightweightJob.State;
410        job.StateLog = new List<StateLog>(lightweightJob.StateLog);
411        // what about parentJob
412        OnJobStateChanged();
413        OnToStringChanged();
414        OnItemImageChanged();
415      }
416    }
417
418    /// <summary>
419    /// Creates a JobData object containing the Job and the IJob-Object as byte[]
420    /// </summary>
421    /// <param name="withoutChildOptimizers">
422    ///   if true the Child-Optimizers will not be serialized (if the job contains an Experiment)
423    /// </param>
424    public JobData GetAsJobData(bool withoutChildOptimizers, out List<IPluginDescription> plugins) {
425      plugins = new List<IPluginDescription>();
426      if (this.optimizerJob == null || this.optimizerJob.Optimizer == null)
427        return null;
428
429      IEnumerable<Type> usedTypes;
430      byte[] jobByteArray;
431      if (withoutChildOptimizers && this.OptimizerJob.Optimizer is Optimization.Experiment) {
432        OptimizerJob clonedJob = (OptimizerJob)this.OptimizerJob.Clone(); // use a cloned job, so that the childHiveJob don't get confused
433        clonedJob.OptimizerAsExperiment.Optimizers.Clear();
434        jobByteArray = PersistenceUtil.Serialize(clonedJob, out usedTypes);
435      } else if (withoutChildOptimizers && this.OptimizerJob.Optimizer is Optimization.BatchRun) {
436        OptimizerJob clonedJob = (OptimizerJob)this.OptimizerJob.Clone();
437        clonedJob.OptimizerAsBatchRun.Optimizer = null;
438        jobByteArray = PersistenceUtil.Serialize(clonedJob, out usedTypes);
439      } else if (this.OptimizerJob.Optimizer is IAlgorithm) {
440        ((IAlgorithm)this.OptimizerJob.Optimizer).StoreAlgorithmInEachRun = false; // avoid storing the algorithm in runs to reduce size
441        jobByteArray = PersistenceUtil.Serialize(this.OptimizerJob, out usedTypes);
442      } else {
443        jobByteArray = PersistenceUtil.Serialize(this.OptimizerJob, out usedTypes);
444      }
445
446      JobData jobData = new JobData() {
447        JobId = job.Id,
448        Data = jobByteArray
449      };
450
451      CollectDeclaringPlugins(plugins, usedTypes);
452
453      return jobData;
454    }
455
456    private void CollectDeclaringPlugins(List<IPluginDescription> plugins, IEnumerable<Type> usedTypes) {
457      foreach (Type type in usedTypes) {
458        var plugin = ApplicationManager.Manager.GetDeclaringPlugin(type);
459        if (plugin != null && !plugins.Contains(plugin)) {
460          plugins.Add(plugin);
461          CollectPluginDependencies(plugins, plugin);
462        }
463      }
464    }
465
466    private void CollectPluginDependencies(List<IPluginDescription> plugins, IPluginDescription plugin) {
467      if (plugin == null) return;
468      foreach (var dependency in plugin.Dependencies) {
469        if (!plugins.Contains(dependency)) {
470          plugins.Add(dependency);
471          CollectPluginDependencies(plugins, dependency);
472        }
473      }
474    }
475
476    #region Events
477    public event EventHandler JobChanged;
478    private void OnJobChanged() {
479      LogMessage("JobChanged");
480      EventHandler handler = JobChanged;
481      if (handler != null) handler(this, EventArgs.Empty);
482    }
483
484    public event EventHandler JobStateChanged;
485    private void OnJobStateChanged() {
486      LogMessage("JobStateChanged (State: " + this.Job.State + ", ExecutionTime: " + this.Job.ExecutionTime.ToString() + ")");
487      EventHandler handler = JobStateChanged;
488      if (handler != null) handler(this, EventArgs.Empty);
489    }
490
491    public event EventHandler OptimizerJobChanged;
492    private void OnOptimizerJobChanged() {
493      OptimizerJob_ComputeInParallelChanged(this, EventArgs.Empty);
494      var handler = JobChanged;
495      if (handler != null) handler(this, EventArgs.Empty);
496    }
497
498    public event EventHandler IsFinishedOptimizerDownloadedChanged;
499    private void OnIsFinishedOptimizerDownloadedChanged() {
500      var handler = IsFinishedOptimizerDownloadedChanged;
501      if (handler != null) handler(this, EventArgs.Empty);
502    }
503    #endregion
504
505    public void LogMessage(string message) {
506      lock (locker) {
507        if (optimizerJob != null) {
508          optimizerJob.Log.LogMessage(message);
509        }
510      }
511    }
512
513    /// <summary>
514    /// Returns a list of HiveJobs including this and all its child-jobs recursively
515    /// </summary>
516    public IEnumerable<HiveJob> GetAllHiveJobs() {
517      List<HiveJob> jobs = new List<HiveJob>();
518      jobs.Add(this);
519      foreach (HiveJob child in this.ChildHiveJobs) {
520        jobs.AddRange(child.GetAllHiveJobs());
521      }
522      return jobs;
523    }
524
525    public HiveJob GetParentByJobId(Guid jobId) {
526      if (this.ChildHiveJobs.SingleOrDefault(j => j.job.Id == jobId) != null)
527        return this;
528      foreach (HiveJob child in this.childHiveJobs) {
529        HiveJob result = child.GetParentByJobId(jobId);
530        if (result != null)
531          return result;
532      }
533      return null;
534    }
535
536
537    public HiveJob GetChildByOptimizerJob(OptimizerJob optimizerJob) {
538      foreach (var child in ChildHiveJobs) {
539        if (child.OptimizerJob == optimizerJob)
540          return child;
541      }
542      return null;
543    }
544
545
546    public HiveJob GetChildByOptimizer(IOptimizer optimizer) {
547      foreach (var child in ChildHiveJobs) {
548        if (child.OptimizerJob.Optimizer == optimizer)
549          return child;
550      }
551      return null;
552    }
553
554    /// <summary>
555    /// Searches for an HiveJob object with the correct jobId recursively
556    /// </summary>
557    public HiveJob GetHiveJobByJobId(Guid jobId) {
558      if (this.Job.Id == jobId) {
559        return this;
560      } else {
561        foreach (HiveJob child in this.ChildHiveJobs) {
562          HiveJob result = child.GetHiveJobByJobId(jobId);
563          if (result != null)
564            return result;
565        }
566      }
567      return null;
568    }
569
570
571    public void RemoveByJobId(Guid jobId) {
572      IEnumerable<HiveJob> jobs = ChildHiveJobs.Where(j => j.Job.Id == jobId).ToList(); // if Guid.Empty needs to be removed, there could be more than one with this jobId
573      foreach (HiveJob j in jobs) {
574        this.childHiveJobs.Remove(j);
575      }
576      foreach (HiveJob child in ChildHiveJobs) {
577        child.RemoveByJobId(jobId);
578      }
579    }
580
581    public IEnumerable<IItemTree> GetChildItems() {
582      return this.childHiveJobs;
583    }
584
585    #region INotifyObservableCollectionItemsChanged<IItemTree> Members
586
587    public event CollectionItemsChangedEventHandler<IItemTree> CollectionReset;
588    private void OnCollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedItem<HiveJob>> e) {
589      var handler = CollectionReset;
590      if (handler != null) handler(this, ToCollectionItemsChangedEventArgs(e));
591    }
592
593    public event CollectionItemsChangedEventHandler<IItemTree> ItemsAdded;
594    private void OnItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<HiveJob>> e) {
595      var handler = ItemsAdded;
596      if (handler != null) handler(this, ToCollectionItemsChangedEventArgs(e));
597    }
598
599    public event CollectionItemsChangedEventHandler<IItemTree> ItemsRemoved;
600    private void OnItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<HiveJob>> e) {
601      var handler = ItemsRemoved;
602      if (handler != null) handler(this, ToCollectionItemsChangedEventArgs(e));
603    }
604
605    private static CollectionItemsChangedEventArgs<IItemTree> ToCollectionItemsChangedEventArgs(CollectionItemsChangedEventArgs<IndexedItem<HiveJob>> e) {
606      return new CollectionItemsChangedEventArgs<IItemTree>(e.Items.Select(x => x.Value), e.OldItems == null ? null : e.OldItems.Select(x => x.Value));
607    }
608    #endregion
609  }
610}
Note: See TracBrowser for help on using the repository browser.