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

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

corrected cloning of RunCollection (ticket#970)

File size: 12.1 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    }
87    protected override void OnItemsRemoved(IEnumerable<IRun> items) {
88      bool columnNamesChanged = false;
89      foreach (IRun run in items) {
90        foreach (string parameterName in run.Parameters.Keys)
91          columnNamesChanged |= RemoveParameterName(parameterName);
92        foreach (string resultName in run.Results.Keys)
93          columnNamesChanged |= RemoveResultName(resultName);
94      }
95      base.OnItemsRemoved(items);
96      OnReset();
97      if (columnNamesChanged)
98        OnColumnNamesChanged();
99      OnRowNamesChanged();
100    }
101
102    private bool AddParameter(string name, IItem value) {
103      if (value == null)
104        return false;
105      if (!parameterNames.Contains(name)) {
106        parameterNames.Add(name);
107        dataTypes[name] = new HashSet<Type>();
108        dataTypes[name].Add(value.GetType());
109        return true;
110      }
111      dataTypes[name].Add(value.GetType());
112      return false;
113    }
114    private bool AddResult(string name, IItem value) {
115      if (value == null)
116        return false;
117      if (!resultNames.Contains(name)) {
118        resultNames.Add(name);
119        dataTypes[name] = new HashSet<Type>();
120        dataTypes[name].Add(value.GetType());
121        return true;
122      }
123      dataTypes[name].Add(value.GetType());
124      return false;
125    }
126    private bool RemoveParameterName(string name) {
127      if (!list.Any(x => x.Parameters.ContainsKey(name))) {
128        parameterNames.Remove(name);
129        return true;
130      }
131      return false;
132    }
133    private bool RemoveResultName(string name) {
134      if (!list.Any(x => x.Results.ContainsKey(name))) {
135        resultNames.Remove(name);
136        return true;
137      }
138      return false;
139    }
140
141    public IItem GetValue(int rowIndex, int columnIndex) {
142      IRun run = this.list[rowIndex];
143      return GetValue(run, columnIndex);
144    }
145
146    public IItem GetValue(IRun run, int columnIndex) {
147      IItem value = null;
148      if (columnIndex < parameterNames.Count) {
149        string parameterName = parameterNames[columnIndex];
150        if (run.Parameters.ContainsKey(parameterName))
151          value = run.Parameters[parameterName];
152      } else if (columnIndex < parameterNames.Count + resultNames.Count) {
153        string resultName = resultNames[columnIndex - parameterNames.Count];
154        if (run.Results.ContainsKey(resultName))
155          value = run.Results[resultName];
156      }
157      return value;
158    }
159
160    public override IDeepCloneable Clone(Cloner cloner) {
161      RunCollection clone = (RunCollection)base.Clone(cloner);
162      clone.resultNames = this.resultNames;
163      clone.parameterNames = this.parameterNames;
164      clone.dataTypes = new Dictionary<string, HashSet<Type>>();
165      foreach (string s in this.dataTypes.Keys)
166        clone.dataTypes[s] = new HashSet<Type>(this.dataTypes[s]);
167
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() {
255      list.ForEach(r => r.Visible = true);
256      foreach (IRunCollectionConstraint constraint in this.constraints)
257        constraint.Check();
258    }
259
260    protected virtual void RegisterConstraintEvents(IEnumerable<IRunCollectionConstraint> constraints) {
261      foreach (IRunCollectionConstraint constraint in constraints) {
262        constraint.ActiveChanged += new EventHandler(Constraint_ActiveChanged);
263        constraint.ConstrainedValueChanged += new EventHandler(Constraint_ConstrainedValueChanged);
264        constraint.ConstraintOperationChanged += new EventHandler(Constraint_ConstraintOperationChanged);
265        constraint.ConstraintDataChanged += new EventHandler(Constraint_ConstraintDataChanged);
266      }
267    }
268    protected virtual void DeregisterConstraintEvents(IEnumerable<IRunCollectionConstraint> constraints) {
269      foreach (IRunCollectionConstraint constraint in constraints) {
270        constraint.ActiveChanged -= new EventHandler(Constraint_ActiveChanged);
271        constraint.ConstrainedValueChanged -= new EventHandler(Constraint_ConstrainedValueChanged);
272        constraint.ConstraintOperationChanged -= new EventHandler(Constraint_ConstraintOperationChanged);
273        constraint.ConstraintDataChanged -= new EventHandler(Constraint_ConstraintDataChanged);
274      }
275    }
276
277    protected virtual void Constraints_CollectionReset(object sender, CollectionItemsChangedEventArgs<IRunCollectionConstraint> e) {
278      DeregisterConstraintEvents(e.OldItems);
279      RegisterConstraintEvents(e.Items);
280      this.UpdateFiltering();
281    }
282    protected virtual void Constraints_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IRunCollectionConstraint> e) {
283      RegisterConstraintEvents(e.Items);
284      foreach (IRunCollectionConstraint constraint in e.Items)
285        constraint.ConstrainedValue = this;
286      this.UpdateFiltering();
287    }
288    protected virtual void Constraints_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IRunCollectionConstraint> e) {
289      DeregisterConstraintEvents(e.Items);
290      this.UpdateFiltering();
291    }
292    protected virtual void Constraint_ActiveChanged(object sender, EventArgs e) {
293      this.UpdateFiltering();
294    }
295    protected virtual void Constraint_ConstrainedValueChanged(object sender, EventArgs e) {
296      //mkommend: this method is intentionally left empty, because the constrainedValue is set in the ItemsAdded method
297    }
298    protected virtual void Constraint_ConstraintOperationChanged(object sender, EventArgs e) {
299      this.UpdateFiltering();
300    }
301    protected virtual void Constraint_ConstraintDataChanged(object sender, EventArgs e) {
302      this.UpdateFiltering();
303    }
304    #endregion
305  }
306}
Note: See TracBrowser for help on using the repository browser.