Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Optimization/3.3/RunCollection.cs @ 4888

Last change on this file since 4888 was 4888, checked in by swagner, 13 years ago

Trivial changes due to review of r4883 (#1284)

File size: 14.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.Linq;
25using HeuristicLab.Collections;
26using HeuristicLab.Common;
27using HeuristicLab.Core;
28using HeuristicLab.Data;
29using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
30
31namespace HeuristicLab.Optimization {
32  [Item("Run Collection", "Represents a collection of runs.")]
33  [Creatable("Testing & Analysis")]
34  [StorableClass]
35  public class RunCollection : ItemCollection<IRun>, IStringConvertibleMatrix, IStorableContent {
36    public string Filename { get; set; }
37
38    [StorableConstructor]
39    protected RunCollection(bool deserializing)
40      : base(deserializing) {
41      updateOfRunsInProgress = false;
42    }
43    protected RunCollection(RunCollection original, Cloner cloner)
44      : base(original, cloner) {
45      updateOfRunsInProgress = false;
46      resultNames = new List<string>(original.resultNames);
47      parameterNames = new List<string>(original.parameterNames);
48      dataTypes = new Dictionary<string, HashSet<Type>>();
49      foreach (string s in original.dataTypes.Keys)
50        dataTypes[s] = new HashSet<Type>(original.dataTypes[s]);
51
52      constraints = new RunCollectionConstraintCollection(original.constraints.Select(x => cloner.Clone(x)));
53      foreach (IRunCollectionConstraint constraint in constraints)
54        constraint.ConstrainedValue = this;
55      RegisterConstraintsEvents();
56      RegisterConstraintEvents(constraints);
57
58      UpdateFiltering(true);
59    }
60    public RunCollection() : base() { Initialize(); }
61    public RunCollection(int capacity) : base(capacity) { Initialize(); }
62    public RunCollection(IEnumerable<IRun> collection) : base(collection) { Initialize(); this.OnItemsAdded(collection); }
63    private void Initialize() {
64      updateOfRunsInProgress = false;
65      parameterNames = new List<string>();
66      resultNames = new List<string>();
67      dataTypes = new Dictionary<string, HashSet<Type>>();
68      constraints = new RunCollectionConstraintCollection();
69      RegisterConstraintsEvents();
70    }
71
72    [Storable]
73    private Dictionary<string, HashSet<Type>> dataTypes;
74    public IEnumerable<Type> GetDataType(string columnName) {
75      if (!dataTypes.ContainsKey(columnName))
76        return new Type[0];
77      return dataTypes[columnName];
78    }
79
80    [Storable]
81    private RunCollectionConstraintCollection constraints;
82    public RunCollectionConstraintCollection Constraints {
83      get { return constraints; }
84    }
85
86    private bool updateOfRunsInProgress;
87    public bool UpdateOfRunsInProgress {
88      get { return updateOfRunsInProgress; }
89      set {
90        if (updateOfRunsInProgress != value) {
91          updateOfRunsInProgress = value;
92          OnUpdateOfRunsInProgressChanged();
93        }
94      }
95    }
96
97    [StorableHook(HookType.AfterDeserialization)]
98    private void AfterDeserialization() {
99      if (constraints == null) constraints = new RunCollectionConstraintCollection();
100      RegisterConstraintsEvents();
101      RegisterConstraintEvents(constraints);
102      UpdateFiltering(true);
103    }
104
105    public override IDeepCloneable Clone(Cloner cloner) {
106      return new RunCollection(this, cloner);
107    }
108
109    public event EventHandler UpdateOfRunsInProgressChanged;
110    protected virtual void OnUpdateOfRunsInProgressChanged() {
111      var handler = UpdateOfRunsInProgressChanged;
112      if (handler != null) handler(this, EventArgs.Empty);
113    }
114
115    protected override void OnCollectionReset(IEnumerable<IRun> items, IEnumerable<IRun> oldItems) {
116      parameterNames.Clear();
117      resultNames.Clear();
118      foreach (IRun run in items) {
119        foreach (KeyValuePair<string, IItem> parameter in run.Parameters)
120          AddParameter(parameter.Key, parameter.Value);
121        foreach (KeyValuePair<string, IItem> result in run.Results)
122          AddResult(result.Key, result.Value);
123      }
124      columnNameCache = null;
125      OnColumnNamesChanged();
126      rowNamesCache = null;
127      base.OnCollectionReset(items, oldItems);
128      OnRowNamesChanged();
129      OnReset();
130      UpdateFiltering(false);
131    }
132    protected override void OnItemsAdded(IEnumerable<IRun> items) {
133      bool columnNamesChanged = false;
134      foreach (IRun run in items) {
135        foreach (KeyValuePair<string, IItem> parameter in run.Parameters)
136          columnNamesChanged |= AddParameter(parameter.Key, parameter.Value);
137        foreach (KeyValuePair<string, IItem> result in run.Results)
138          columnNamesChanged |= AddResult(result.Key, result.Value);
139      }
140      if (columnNamesChanged) columnNameCache = null;
141      rowNamesCache = null;
142      base.OnItemsAdded(items);
143      OnReset();
144      OnRowNamesChanged();
145      if (columnNamesChanged) OnColumnNamesChanged();
146      UpdateFiltering(false);
147    }
148    protected override void OnItemsRemoved(IEnumerable<IRun> items) {
149      bool columnNamesChanged = false;
150      foreach (IRun run in items) {
151        foreach (string parameterName in run.Parameters.Keys)
152          columnNamesChanged |= RemoveParameterName(parameterName);
153        foreach (string resultName in run.Results.Keys)
154          columnNamesChanged |= RemoveResultName(resultName);
155      }
156      if (columnNamesChanged) columnNameCache = null;
157      rowNamesCache = null;
158      base.OnItemsRemoved(items);
159      OnReset();
160      OnRowNamesChanged();
161      if (columnNamesChanged) OnColumnNamesChanged();
162    }
163
164    private bool AddParameter(string name, IItem value) {
165      if (value == null)
166        return false;
167      if (!parameterNames.Contains(name)) {
168        parameterNames.Add(name);
169        dataTypes[name] = new HashSet<Type>();
170        dataTypes[name].Add(value.GetType());
171        return true;
172      }
173      dataTypes[name].Add(value.GetType());
174      return false;
175    }
176    private bool AddResult(string name, IItem value) {
177      if (value == null)
178        return false;
179      if (!resultNames.Contains(name)) {
180        resultNames.Add(name);
181        dataTypes[name] = new HashSet<Type>();
182        dataTypes[name].Add(value.GetType());
183        return true;
184      }
185      dataTypes[name].Add(value.GetType());
186      return false;
187    }
188    private bool RemoveParameterName(string name) {
189      if (!list.Any(x => x.Parameters.ContainsKey(name))) {
190        parameterNames.Remove(name);
191        return true;
192      }
193      return false;
194    }
195    private bool RemoveResultName(string name) {
196      if (!list.Any(x => x.Results.ContainsKey(name))) {
197        resultNames.Remove(name);
198        return true;
199      }
200      return false;
201    }
202
203    public IItem GetValue(int rowIndex, int columnIndex) {
204      IRun run = this.list[rowIndex];
205      return GetValue(run, columnIndex);
206    }
207
208    public IItem GetValue(IRun run, int columnIndex) {
209      string name = ((IStringConvertibleMatrix)this).ColumnNames.ElementAt(columnIndex);
210      return GetValue(run, name);
211    }
212
213    public IItem GetValue(IRun run, string columnName) {
214      IItem value = null;
215      if (run.Parameters.ContainsKey(columnName))
216        value = run.Parameters[columnName];
217      else if (run.Results.ContainsKey(columnName))
218        value = run.Results[columnName];
219      return value;
220    }
221
222    #region IStringConvertibleMatrix Members
223    [Storable]
224    private List<string> parameterNames;
225    public IEnumerable<string> ParameterNames {
226      get { return this.parameterNames; }
227    }
228    [Storable]
229    private List<string> resultNames;
230    public IEnumerable<string> ResultNames {
231      get { return this.resultNames; }
232    }
233    int IStringConvertibleMatrix.Rows {
234      get { return this.Count; }
235      set { throw new NotSupportedException(); }
236    }
237    int IStringConvertibleMatrix.Columns {
238      get { return parameterNames.Count + resultNames.Count; }
239      set { throw new NotSupportedException(); }
240    }
241    private List<string> columnNameCache;
242    IEnumerable<string> IStringConvertibleMatrix.ColumnNames {
243      get {
244        if (columnNameCache == null) {
245          columnNameCache = new List<string>(parameterNames);
246          columnNameCache.AddRange(resultNames);
247          columnNameCache.Sort();
248        }
249        return columnNameCache;
250      }
251      set { throw new NotSupportedException(); }
252    }
253    private List<string> rowNamesCache;
254    IEnumerable<string> IStringConvertibleMatrix.RowNames {
255      get {
256        if (rowNamesCache == null)
257          rowNamesCache = list.Select(x => x.Name).ToList();
258        return rowNamesCache;
259      }
260      set { throw new NotSupportedException(); }
261    }
262    bool IStringConvertibleMatrix.SortableView {
263      get { return true; }
264      set { throw new NotSupportedException(); }
265    }
266    bool IStringConvertibleMatrix.ReadOnly {
267      get { return true; }
268    }
269
270    string IStringConvertibleMatrix.GetValue(int rowIndex, int columnIndex) {
271      IItem value = GetValue(rowIndex, columnIndex);
272      if (value == null)
273        return string.Empty;
274      return value.ToString();
275    }
276
277    public event EventHandler<EventArgs<int, int>> ItemChanged;
278    protected virtual void OnItemChanged(int rowIndex, int columnIndex) {
279      EventHandler<EventArgs<int, int>> handler = ItemChanged;
280      if (handler != null) handler(this, new EventArgs<int, int>(rowIndex, columnIndex));
281      OnToStringChanged();
282    }
283    public event EventHandler Reset;
284    protected virtual void OnReset() {
285      EventHandler handler = Reset;
286      if (handler != null) handler(this, EventArgs.Empty);
287      OnToStringChanged();
288    }
289    public event EventHandler ColumnNamesChanged;
290    protected virtual void OnColumnNamesChanged() {
291      EventHandler handler = ColumnNamesChanged;
292      if (handler != null) handler(this, EventArgs.Empty);
293    }
294    public event EventHandler RowNamesChanged;
295    protected virtual void OnRowNamesChanged() {
296      EventHandler handler = RowNamesChanged;
297      if (handler != null) handler(this, EventArgs.Empty);
298    }
299    public event EventHandler SortableViewChanged;
300    protected virtual void OnSortableViewChanged() {
301      EventHandler handler = SortableViewChanged;
302      if (handler != null) handler(this, EventArgs.Empty);
303    }
304
305    public bool Validate(string value, out string errorMessage) { throw new NotSupportedException(); }
306    public bool SetValue(string value, int rowIndex, int columnIndex) { throw new NotSupportedException(); }
307    #endregion
308
309    #region Filtering
310    private void UpdateFiltering(bool reset) {
311      UpdateOfRunsInProgress = true;
312      if (reset)
313        list.ForEach(r => r.Visible = true);
314      foreach (IRunCollectionConstraint constraint in this.constraints)
315        constraint.Check();
316      UpdateOfRunsInProgress = false;
317    }
318
319    private void RegisterConstraintsEvents() {
320      constraints.ItemsAdded += new CollectionItemsChangedEventHandler<IRunCollectionConstraint>(Constraints_ItemsAdded);
321      constraints.ItemsRemoved += new CollectionItemsChangedEventHandler<IRunCollectionConstraint>(Constraints_ItemsRemoved);
322      constraints.CollectionReset += new CollectionItemsChangedEventHandler<IRunCollectionConstraint>(Constraints_CollectionReset);
323    }
324
325    protected virtual void RegisterConstraintEvents(IEnumerable<IRunCollectionConstraint> constraints) {
326      foreach (IRunCollectionConstraint constraint in constraints) {
327        constraint.ActiveChanged += new EventHandler(Constraint_ActiveChanged);
328        constraint.ConstrainedValueChanged += new EventHandler(Constraint_ConstrainedValueChanged);
329        constraint.ConstraintOperationChanged += new EventHandler(Constraint_ConstraintOperationChanged);
330        constraint.ConstraintDataChanged += new EventHandler(Constraint_ConstraintDataChanged);
331      }
332    }
333    protected virtual void DeregisterConstraintEvents(IEnumerable<IRunCollectionConstraint> constraints) {
334      foreach (IRunCollectionConstraint constraint in constraints) {
335        constraint.ActiveChanged -= new EventHandler(Constraint_ActiveChanged);
336        constraint.ConstrainedValueChanged -= new EventHandler(Constraint_ConstrainedValueChanged);
337        constraint.ConstraintOperationChanged -= new EventHandler(Constraint_ConstraintOperationChanged);
338        constraint.ConstraintDataChanged -= new EventHandler(Constraint_ConstraintDataChanged);
339      }
340    }
341
342    protected virtual void Constraints_CollectionReset(object sender, CollectionItemsChangedEventArgs<IRunCollectionConstraint> e) {
343      DeregisterConstraintEvents(e.OldItems);
344      RegisterConstraintEvents(e.Items);
345      this.UpdateFiltering(true);
346    }
347    protected virtual void Constraints_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IRunCollectionConstraint> e) {
348      RegisterConstraintEvents(e.Items);
349      foreach (IRunCollectionConstraint constraint in e.Items)
350        constraint.ConstrainedValue = this;
351      this.UpdateFiltering(false);
352    }
353    protected virtual void Constraints_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IRunCollectionConstraint> e) {
354      DeregisterConstraintEvents(e.Items);
355      this.UpdateFiltering(true);
356    }
357    protected virtual void Constraint_ActiveChanged(object sender, EventArgs e) {
358      IRunCollectionConstraint constraint = (IRunCollectionConstraint)sender;
359      this.UpdateFiltering(!constraint.Active);
360    }
361    protected virtual void Constraint_ConstrainedValueChanged(object sender, EventArgs e) {
362      //mkommend: this method is intentionally left empty, because the constrainedValue is set in the ItemsAdded method
363    }
364    protected virtual void Constraint_ConstraintOperationChanged(object sender, EventArgs e) {
365      IRunCollectionConstraint constraint = (IRunCollectionConstraint)sender;
366      if (constraint.Active)
367        this.UpdateFiltering(true);
368    }
369    protected virtual void Constraint_ConstraintDataChanged(object sender, EventArgs e) {
370      IRunCollectionConstraint constraint = (IRunCollectionConstraint)sender;
371      if (constraint.Active)
372        this.UpdateFiltering(true);
373    }
374    #endregion
375  }
376}
Note: See TracBrowser for help on using the repository browser.