Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 3632 was 3632, checked in by mkommend, 12 years ago

corrected RunCollectionConstraints and the according views (ticket#970)

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