Free cookie consent management tool by TermsFeed Policy Generator

source: branches/CloningRefactoring/HeuristicLab.Optimization/3.3/RunCollection.cs @ 4665

Last change on this file since 4665 was 4665, checked in by mkommend, 13 years ago

Refactored Optimization (ticket #922).

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