Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/HiveExperiment/HiveJobClient.cs @ 4796

Last change on this file since 4796 was 4796, checked in by cneumuel, 13 years ago

#1233 applied new cloning mechanism

File size: 23.0 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.Collections;
27using HeuristicLab.Common;
28using HeuristicLab.Core;
29using HeuristicLab.Optimization;
30using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
31using HeuristicLab.Services.Hive.Common.DataTransfer;
32using HeuristicLab.Clients.Hive.Jobs;
33
34namespace HeuristicLab.Clients.Hive {
35
36  public class HiveJob : Item {
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.VS2008ImageLibrary.Event;
43        } else {
44          if (job.JobState == JobState.Waiting) return HeuristicLab.Common.Resources.VS2008ImageLibrary.ExecutablePrepared;
45          else if (job.JobState == JobState.WaitingForChildJobs) return HeuristicLab.Common.Resources.VS2008ImageLibrary.ExecutablePrepared;
46          else if (job.JobState == JobState.Calculating) return HeuristicLab.Common.Resources.VS2008ImageLibrary.ExecutableStarted;
47          else if (job.JobState == JobState.Aborted) return HeuristicLab.Common.Resources.VS2008ImageLibrary.ExecutableStopped;
48          else if (job.JobState == JobState.Failed) return HeuristicLab.Common.Resources.VS2008ImageLibrary.Error;
49          else if (job.JobState == JobState.Finished) return HeuristicLab.Common.Resources.VS2008ImageLibrary.ExecutableStopped;
50          else return HeuristicLab.Common.Resources.VS2008ImageLibrary.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        JobState = JobState.Waiting,
108        DateCreated = DateTime.Now,
109        CoresNeeded = 1,
110        MemoryNeeded = 0
111      };
112      this.childHiveJobs = new ItemList<HiveJob>();
113      syncJobsWithOptimizers = true;
114    }
115
116    public HiveJob(Job jobDto)
117      : this() {
118      this.Job = jobDto;
119    }
120
121    public HiveJob(LightweightJob lightweightJob)
122      : this() {
123      UpdateFromLightweightJob(lightweightJob);
124    }
125
126    public HiveJob(OptimizerJob optimizerJob, bool autoCreateChildHiveJobs)
127      : this() {
128      this.syncJobsWithOptimizers = autoCreateChildHiveJobs;
129      this.OptimizerJob = optimizerJob;
130      this.syncJobsWithOptimizers = true;
131    }
132
133    public HiveJob(IOptimizer optimizer)
134      : this() {
135      this.OptimizerJob = new OptimizerJob(optimizer);
136    }
137
138    public HiveJob(Job job, JobData serializedJob, bool autoCreateChildHiveJobs)
139      : this() {
140      this.syncJobsWithOptimizers = autoCreateChildHiveJobs;
141      this.Job = job;
142      this.OptimizerJob = PersistenceUtil.Deserialize<OptimizerJob>(serializedJob.Data);
143      this.syncJobsWithOptimizers = true;
144    }
145
146    protected HiveJob(HiveJob original, Cloner cloner)
147      : base(original, cloner) {
148      this.Job = cloner.Clone(original.job);
149      this.OptimizerJob = cloner.Clone(original.OptimizerJob);
150    }
151    public override IDeepCloneable Clone(Cloner cloner) {
152      return new HiveJob(this, cloner);
153    }
154
155    /// <summary>
156    /// if this.Optimizer is an experiment
157    ///   Uses the child-optimizers of this.HiveJob and creates HiveJob-childs
158    /// if this.Optimizer is a batchrun
159    ///   Creates a number of child-jobs according to repetitions
160    /// </summary>
161    private void UpdateChildHiveJobs() {
162      if (Job != null && syncJobsWithOptimizers) {
163        if (OptimizerJob.Optimizer is Optimization.Experiment) {
164          Optimization.Experiment experiment = (Optimization.Experiment)OptimizerJob.Optimizer;
165          foreach (IOptimizer childOpt in experiment.Optimizers) {
166            this.childHiveJobs.Add(new HiveJob(childOpt));
167          }
168        } else if (OptimizerJob.Optimizer is Optimization.BatchRun) {
169          Optimization.BatchRun batchRun = OptimizerJob.OptimizerAsBatchRun;
170          if (batchRun.Algorithm != null) {
171            while (this.childHiveJobs.Count < batchRun.Repetitions) {
172              this.childHiveJobs.Add(new HiveJob(batchRun.Algorithm));
173            }
174            while (this.childHiveJobs.Count > batchRun.Repetitions) {
175              this.childHiveJobs.Remove(this.childHiveJobs.Last());
176            }
177          }
178        }
179      }
180    }
181
182    private void RegisterOptimizerEvents() {
183      if (OptimizerJob != null) {
184        if (OptimizerJob.Optimizer is Optimization.Experiment) {
185          Optimization.Experiment experiment = OptimizerJob.OptimizerAsExperiment;
186          experiment.Optimizers.ItemsAdded += new Collections.CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsAdded);
187          experiment.Optimizers.ItemsReplaced += new Collections.CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsReplaced);
188          experiment.Optimizers.ItemsRemoved += new Collections.CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsRemoved);
189          experiment.Optimizers.CollectionReset += new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_CollectionReset);
190        } else if (OptimizerJob.Optimizer is Optimization.BatchRun) {
191          Optimization.BatchRun batchRun = OptimizerJob.OptimizerAsBatchRun;
192          batchRun.RepetitionsChanged += new EventHandler(batchRun_RepetitionsChanged);
193          batchRun.AlgorithmChanged += new EventHandler(batchRun_AlgorithmChanged);
194        }
195
196        OptimizerJob.ComputeInParallelChanged += new EventHandler(OptimizerJob_ComputeInParallelChanged);
197        OptimizerJob.ToStringChanged += new EventHandler(OptimizerJob_ToStringChanged);
198      }
199    }
200    private void DergisterOptimizerEvents() {
201      if (Job != null && OptimizerJob.Optimizer is Optimization.Experiment) {
202        if (OptimizerJob.Optimizer is Optimization.Experiment) {
203          Optimization.Experiment experiment = OptimizerJob.OptimizerAsExperiment;
204          experiment.Optimizers.ItemsAdded -= new Collections.CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsAdded);
205          experiment.Optimizers.ItemsReplaced -= new Collections.CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsReplaced);
206          experiment.Optimizers.ItemsRemoved -= new Collections.CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsRemoved);
207          experiment.Optimizers.CollectionReset -= new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_CollectionReset);
208        } else if (OptimizerJob.Optimizer is Optimization.BatchRun) {
209          Optimization.BatchRun batchRun = OptimizerJob.OptimizerAsBatchRun;
210          batchRun.RepetitionsChanged -= new EventHandler(batchRun_RepetitionsChanged);
211          batchRun.AlgorithmChanged -= new EventHandler(batchRun_AlgorithmChanged);
212        }
213
214        OptimizerJob.ComputeInParallelChanged -= new EventHandler(OptimizerJob_ComputeInParallelChanged);
215        OptimizerJob.ToStringChanged -= new EventHandler(OptimizerJob_ToStringChanged);
216      }
217    }
218
219    void batchRun_AlgorithmChanged(object sender, EventArgs e) {
220      if (syncJobsWithOptimizers) {
221        this.childHiveJobs.Clear();
222        UpdateChildHiveJobs();
223      }
224    }
225
226    void batchRun_RepetitionsChanged(object sender, EventArgs e) {
227      if (syncJobsWithOptimizers) {
228        UpdateChildHiveJobs();
229      }
230    }
231
232    void OptimizerJob_ToStringChanged(object sender, EventArgs e) {
233      this.OnToStringChanged();
234    }
235
236    private void Optimizers_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<IOptimizer>> e) {
237      if (syncJobsWithOptimizers && this.OptimizerJob.ComputeInParallel) {
238        foreach (var item in e.Items) {
239          if (GetChildByOptimizer(item.Value) == null && item.Value.Name != "Placeholder") {
240            this.childHiveJobs.Add(new HiveJob(item.Value));
241          }
242        }
243      }
244    }
245    private void Optimizers_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<IOptimizer>> e) {
246      if (syncJobsWithOptimizers && this.OptimizerJob.ComputeInParallel) {
247        foreach (var item in e.OldItems) {
248          this.childHiveJobs.Remove(this.GetChildByOptimizer(item.Value));
249        }
250        foreach (var item in e.Items) {
251          if (GetChildByOptimizer(item.Value) == null && item.Value.Name != "Placeholder") {
252            this.childHiveJobs.Add(new HiveJob(item.Value));
253          }
254        }
255      }
256    }
257    private void Optimizers_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<IOptimizer>> e) {
258      if (syncJobsWithOptimizers && this.OptimizerJob.ComputeInParallel) {
259        foreach (var item in e.Items) {
260          this.childHiveJobs.Remove(this.GetChildByOptimizer(item.Value));
261        }
262      }
263    }
264    void Optimizers_CollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedItem<IOptimizer>> e) {
265      if (syncJobsWithOptimizers && this.OptimizerJob.ComputeInParallel) {
266        foreach (var item in e.Items) {
267          this.childHiveJobs.Remove(this.GetChildByOptimizer(item.Value));
268        }
269      }
270    }
271
272    void OptimizerJob_ComputeInParallelChanged(object sender, EventArgs e) {
273      if (OptimizerJob != null && syncJobsWithOptimizers) {
274        if (OptimizerJob.ComputeInParallel) {
275          // child-hive jobs are not yet created, so create them according to the child-optimizers
276          this.UpdateChildHiveJobs();
277        } else {
278          // child-hive jobs need to be deleted
279          this.childHiveJobs.Clear();
280        }
281      }
282    }
283
284    public void AddChildHiveJob(HiveJob hiveJob) {
285      this.childHiveJobs.Add(hiveJob);
286      syncJobsWithOptimizers = false;
287      if (this.OptimizerJob.Optimizer is Optimization.Experiment) {
288        if (!this.OptimizerJob.OptimizerAsExperiment.Optimizers.Contains(hiveJob.OptimizerJob.Optimizer)) {
289          UpdateOptimizerInExperiment(this.OptimizerJob.OptimizerAsExperiment, hiveJob.OptimizerJob);
290        }
291      } else if (this.OptimizerJob.Optimizer is Optimization.BatchRun) {
292        UpdateOptimizerInBatchRun(this.OptimizerJob.OptimizerAsBatchRun, hiveJob.OptimizerJob);
293      }
294      syncJobsWithOptimizers = true;
295    }
296
297    /// <summary>
298    /// if this.Optimizer is Experiment
299    ///   replace the child-optimizer in the experiment
300    /// if this.Optimizer is BatchRun
301    ///   add the runs from the optimizerJob to the batchrun and replace the algorithm
302    /// </summary>
303    public void UpdateChildOptimizer(OptimizerJob optimizerJob, Guid childJobId) {
304      syncJobsWithOptimizers = false; // don't sync with optimizers during this method
305      bool childIsFinishedOptimizerDownloaded = false;
306
307      if (this.OptimizerJob.Optimizer is Optimization.Experiment) {
308        UpdateOptimizerInExperiment(this.OptimizerJob.OptimizerAsExperiment, optimizerJob);
309        childIsFinishedOptimizerDownloaded = true;
310      } else if (this.OptimizerJob.Optimizer is Optimization.BatchRun) {
311        UpdateOptimizerInBatchRun(this.OptimizerJob.OptimizerAsBatchRun, optimizerJob);
312        if (this.OptimizerJob.OptimizerAsBatchRun.Repetitions == this.OptimizerJob.Optimizer.Runs.Count) {
313          childIsFinishedOptimizerDownloaded = true;
314        }
315      } else {
316        childIsFinishedOptimizerDownloaded = optimizerJob.Optimizer.ExecutionState == ExecutionState.Stopped;
317      }
318
319      HiveJob child = this.ChildHiveJobs.Single(j => j.Job.Id == childJobId);
320      if (!optimizerJob.ComputeInParallel) {
321        child.syncJobsWithOptimizers = false;
322        child.OptimizerJob = optimizerJob;
323        child.syncJobsWithOptimizers = true;
324      }
325      if (childIsFinishedOptimizerDownloaded) {
326        child.IsFinishedOptimizerDownloaded = true;
327      }
328      syncJobsWithOptimizers = true;
329    }
330
331    /// <summary>
332    /// Adds the runs from the optimizerJob to the batchrun and replaces the algorithm
333    /// Sideeffect: the optimizerJob.Optimizer will be prepared (scopes are deleted and executionstate will be reset)
334    /// </summary>
335    private void UpdateOptimizerInBatchRun(BatchRun batchRun, OptimizerJob optimizerJob) {
336      if (batchRun.Algorithm == null) {
337        batchRun.Algorithm = (IAlgorithm)optimizerJob.Optimizer; // only set the first optimizer as algorithm. if every time the Algorithm would be set, the runs would be cleared each time
338      }
339      foreach (IRun run in optimizerJob.Optimizer.Runs) {
340        if (!batchRun.Runs.Contains(run))
341          batchRun.Runs.Add(run);
342      }
343    }
344
345    /// <summary>
346    /// replace the child-optimizer in the experiment
347    /// Sideeffect: the optimizerJob.Optimizer will be prepared (scopes are deleted and executionstate will be reset)
348    /// </summary>
349    private void UpdateOptimizerInExperiment(Optimization.Experiment experiment, OptimizerJob optimizerJob) {
350      if (optimizerJob.IndexInParentOptimizerList < 0)
351        throw new IndexOutOfRangeException("IndexInParentOptimizerList must be equal or greater than zero! The Job is invalid and the optimizer-tree cannot be reassembled.");
352
353      while (experiment.Optimizers.Count < optimizerJob.IndexInParentOptimizerList) {
354        experiment.Optimizers.Add(new UserDefinedAlgorithm("Placeholder")); // add dummy-entries to Optimizers so that its possible to insert the optimizerJob at the correct position
355      }
356      if (experiment.Optimizers.Count < optimizerJob.IndexInParentOptimizerList + 1) {
357        experiment.Optimizers.Add(optimizerJob.Optimizer);
358      } else {
359        // if ComputeInParallel==true, don't replace the optimizer (except it is still a Placeholder)
360        // this is because Jobs with ComputeInParallel get submitted to hive with their child-optimizers deleted
361        if (!optimizerJob.ComputeInParallel || experiment.Optimizers[optimizerJob.IndexInParentOptimizerList].Name == "Placeholder") {
362          experiment.Optimizers[optimizerJob.IndexInParentOptimizerList] = optimizerJob.Optimizer;
363        }
364      }
365    }
366
367    /// <summary>
368    /// Sets the IndexInParentOptimizerList property of the OptimizerJob
369    /// according to the position in the OptimizerList of the parentHiveJob.Job
370    /// Recursively updates all the child-jobs as well
371    /// </summary>
372    internal void SetIndexInParentOptimizerList(HiveJob parentHiveJob) {
373      if (parentHiveJob != null) {
374        if (parentHiveJob.OptimizerJob.Optimizer is Optimization.Experiment) {
375          this.OptimizerJob.IndexInParentOptimizerList = parentHiveJob.OptimizerJob.OptimizerAsExperiment.Optimizers.IndexOf(this.OptimizerJob.Optimizer);
376        } else if (parentHiveJob.OptimizerJob.Optimizer is Optimization.BatchRun) {
377          this.OptimizerJob.IndexInParentOptimizerList = 0;
378        } else {
379          throw new NotSupportedException("Only Experiment and BatchRuns are supported");
380        }
381      }
382      foreach (HiveJob child in childHiveJobs) {
383        child.SetIndexInParentOptimizerList(this);
384      }
385    }
386
387    public override string ToString() {
388      if (optimizerJob != null) {
389        return optimizerJob.ToString();
390      } else {
391        return base.ToString();
392      }
393    }
394
395    public void UpdateFromLightweightJob(LightweightJob lightweightJob) {
396      if (lightweightJob != null) {
397        job.Id = lightweightJob.Id;
398        job.DateCreated = lightweightJob.DateCreated;
399        job.DateCalculated = lightweightJob.DateCalculated;
400        job.DateFinished = lightweightJob.DateFinished;
401        job.Exception = lightweightJob.Exception;
402        job.Id = lightweightJob.Id;
403        job.ExecutionTime = lightweightJob.ExecutionTime;
404        job.JobState = lightweightJob.JobState;
405        // what about parentJob
406        OnJobStateChanged();
407        OnToStringChanged();
408        OnItemImageChanged();
409      }
410    }
411
412    /// <summary>
413    /// Creates a SerializedJob object containing the Job and the IJob-Object as byte[]
414    /// </summary>
415    /// <param name="withoutChildOptimizers">
416    ///   if true the Child-Optimizers will not be serialized (if the job contains an Experiment)
417    /// </param>
418    public JobData GetAsSerializedJob(bool withoutChildOptimizers) {
419      byte[] jobByteArray;
420      if (withoutChildOptimizers && this.OptimizerJob.Optimizer is Optimization.Experiment) {
421        OptimizerJob clonedJob = (OptimizerJob)this.OptimizerJob.Clone(); // use a cloned job, so that the childHiveJob don't get confused
422        clonedJob.OptimizerAsExperiment.Optimizers.Clear();
423        jobByteArray = PersistenceUtil.Serialize(clonedJob);
424      } else if (withoutChildOptimizers && this.OptimizerJob.Optimizer is Optimization.BatchRun) {
425        OptimizerJob clonedJob = (OptimizerJob)this.OptimizerJob.Clone();
426        clonedJob.OptimizerAsBatchRun.Algorithm = null;
427        jobByteArray = PersistenceUtil.Serialize(clonedJob);
428      } else if (this.OptimizerJob.Optimizer is IAlgorithm) {
429        ((IAlgorithm)this.OptimizerJob.Optimizer).StoreAlgorithmInEachRun = false; // avoid storing the algorithm in runs to reduce size
430        jobByteArray = PersistenceUtil.Serialize(this.OptimizerJob);
431      } else {
432        jobByteArray = PersistenceUtil.Serialize(this.OptimizerJob);
433      }
434
435      UpdateRequiredPlugins();
436
437      JobData serializedJob = new JobData() {
438        JobId = job.Id,
439        Data = jobByteArray
440      };
441
442      return serializedJob;
443    }
444
445    /// <summary>
446    /// find out which which plugins are needed for the given object
447    /// </summary>
448    private void UpdateRequiredPlugins() {
449      //this.Job.PluginsNeeded = HivePluginInfoDto.FindPluginsNeeded(optimizerJob.GetType());
450      throw new NotImplementedException();
451    }
452
453    #region Events
454    public event EventHandler JobChanged;
455    private void OnJobChanged() {
456      LogMessage("JobChanged");
457      EventHandler handler = JobChanged;
458      if (handler != null) handler(this, EventArgs.Empty);
459    }
460
461    public event EventHandler JobStateChanged;
462    private void OnJobStateChanged() {
463      LogMessage("JobStateChanged (State: " + this.Job.JobState + ", ExecutionTime: " + this.Job.ExecutionTime.ToString() + ")");
464      EventHandler handler = JobStateChanged;
465      if (handler != null) handler(this, EventArgs.Empty);
466    }
467
468    public event EventHandler OptimizerJobChanged;
469    private void OnOptimizerJobChanged() {
470      OptimizerJob_ComputeInParallelChanged(this, EventArgs.Empty);
471      var handler = JobChanged;
472      if (handler != null) handler(this, EventArgs.Empty);
473    }
474
475    public event EventHandler IsFinishedOptimizerDownloadedChanged;
476    private void OnIsFinishedOptimizerDownloadedChanged() {
477      var handler = IsFinishedOptimizerDownloadedChanged;
478      if (handler != null) handler(this, EventArgs.Empty);
479    }
480    #endregion
481
482    public void LogMessage(string message) {
483      lock (locker) {
484        if (optimizerJob != null) {
485          optimizerJob.Log.LogMessage(message);
486        }
487      }
488    }
489
490    /// <summary>
491    /// Returns a list of HiveJobs including this and all its child-jobs recursively
492    /// </summary>
493    public IEnumerable<HiveJob> GetAllHiveJobs() {
494      List<HiveJob> jobs = new List<HiveJob>();
495      jobs.Add(this);
496      foreach (HiveJob child in this.ChildHiveJobs) {
497        jobs.AddRange(child.GetAllHiveJobs());
498      }
499      return jobs;
500    }
501
502    public HiveJob GetParentByJobId(Guid jobId) {
503      if (this.ChildHiveJobs.SingleOrDefault(j => j.job.Id == jobId) != null)
504        return this;
505      foreach (HiveJob child in this.childHiveJobs) {
506        HiveJob result = child.GetParentByJobId(jobId);
507        if (result != null)
508          return result;
509      }
510      return null;
511    }
512
513
514    public HiveJob GetChildByOptimizerJob(OptimizerJob optimizerJob) {
515      foreach (var child in ChildHiveJobs) {
516        if (child.OptimizerJob == optimizerJob)
517          return child;
518      }
519      return null;
520    }
521
522
523    public HiveJob GetChildByOptimizer(IOptimizer optimizer) {
524      foreach (var child in ChildHiveJobs) {
525        if (child.OptimizerJob.Optimizer == optimizer)
526          return child;
527      }
528      return null;
529    }
530
531    /// <summary>
532    /// Searches for an HiveJob object with the correct jobId recursively
533    /// </summary>
534    public HiveJob GetHiveJobByJobId(Guid jobId) {
535      if (this.Job.Id == jobId) {
536        return this;
537      } else {
538        foreach (HiveJob child in this.ChildHiveJobs) {
539          HiveJob result = child.GetHiveJobByJobId(jobId);
540          if (result != null)
541            return result;
542        }
543      }
544      return null;
545    }
546
547
548    public void RemoveByJobId(Guid jobId) {
549      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
550      foreach (HiveJob j in jobs) {
551        this.childHiveJobs.Remove(j);
552      }
553      foreach (HiveJob child in ChildHiveJobs) {
554        child.RemoveByJobId(jobId);
555      }
556    }
557
558  }
559}
Note: See TracBrowser for help on using the repository browser.