Free cookie consent management tool by TermsFeed Policy Generator

source: branches/ParameterBinding/HeuristicLab.Optimization/3.3/RunCollection.cs @ 9302

Last change on this file since 9302 was 4722, checked in by swagner, 14 years ago

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