Free cookie consent management tool by TermsFeed Policy Generator

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

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

Corrected behavior of RunCollection and changed minor parts in the views (ticket #1213).

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