Free cookie consent management tool by TermsFeed Policy Generator

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

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

Implemented reviewers' comments (#947)

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