Free cookie consent management tool by TermsFeed Policy Generator

source: stable/HeuristicLab.Problems.DataAnalysis.Views/3.4/MenuItems/ShrinkDataAnalysisRunsMenuItem.cs @ 9932

Last change on this file since 9932 was 9932, checked in by ascheibe, 11 years ago

#2055 merged r9859, r9860, r9866 into stable branch

File size: 5.9 KB
Line 
1#region License Information
2
3/* HeuristicLab
4 * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
5 *
6 * This file is part of HeuristicLab.
7 *
8 * HeuristicLab is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * HeuristicLab is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#endregion
23
24using System;
25using System.Collections;
26using System.Collections.Generic;
27using System.Linq;
28using System.Linq.Expressions;
29using HeuristicLab.Common;
30using HeuristicLab.MainForm;
31using HeuristicLab.Optimization;
32using HeuristicLab.Optimizer;
33
34using MenuItem = HeuristicLab.MainForm.WindowsForms.MenuItem;
35using ValuesType = System.Collections.Generic.Dictionary<string, System.Collections.IList>;
36
37namespace HeuristicLab.Problems.DataAnalysis.Views {
38  internal sealed class ShrinkDataAnalysisRunsMenuItem : MenuItem, IOptimizerUserInterfaceItemProvider {
39    public override string Name {
40      get { return "Remove Duplicate Datasets"; }
41    }
42    public override IEnumerable<string> Structure {
43      get { return new string[] { "&Data Analysis" }; }
44    }
45    public override int Position {
46      get { return 5300; }
47    }
48    public override string ToolTipText {
49      get { return "This command shrinks the memory usage of data analysis optimizers by checking and unifying duplicate datasets."; }
50    }
51
52    protected override void OnToolStripItemSet(EventArgs e) {
53      ToolStripItem.Enabled = false;
54    }
55
56    protected override void OnActiveViewChanged(object sender, EventArgs e) {
57      IContentView activeView = MainFormManager.MainForm.ActiveView as IContentView;
58      if (activeView == null) {
59        ToolStripItem.Enabled = false;
60        return;
61      }
62
63      var content = activeView.Content;
64      RunCollection runCollection = content as RunCollection;
65      if (runCollection == null && content is IOptimizer)
66        runCollection = ((IOptimizer)content).Runs;
67
68      if (runCollection == null) {
69        ToolStripItem.Enabled = false;
70        return;
71      }
72
73      ToolStripItem.Enabled = runCollection.Any(run => run.Parameters.Any(p => p.Value is IDataAnalysisProblemData));
74    }
75
76    public override void Execute() {
77      IContentView activeView = (IContentView)MainFormManager.MainForm.ActiveView;
78      Progress progress = new Progress("Removing duplicate datasets.");
79      var mainForm = (MainForm.WindowsForms.MainForm)MainFormManager.MainForm;
80      mainForm.AddOperationProgressToContent(activeView.Content, progress);
81
82      Action<IContentView> action = (view) => {
83        var variableValuesMapping = new Dictionary<ValuesType, ValuesType>();
84        foreach (var problemData in view.Content.GetObjectGraphObjects(excludeStaticMembers: true).OfType<IDataAnalysisProblemData>()) {
85          var originalValues = variableValuesGetter(problemData.Dataset);
86          var matchingValues = GetEqualValues(originalValues, variableValuesMapping);
87          variableValuesSetter(problemData.Dataset, matchingValues);
88        }
89      };
90
91      action.BeginInvoke(activeView, delegate(IAsyncResult result) {
92        action.EndInvoke(result);
93        mainForm.RemoveOperationProgressFromContent(activeView.Content);
94      }, null);
95    }
96
97    private static ValuesType GetEqualValues(ValuesType originalValues, Dictionary<ValuesType, ValuesType> variableValuesMapping) {
98      if (variableValuesMapping.ContainsKey(originalValues)) return variableValuesMapping[originalValues];
99
100      var matchingValues = variableValuesMapping.FirstOrDefault(kv => kv.Key == kv.Value && EqualVariableValues(originalValues, kv.Key)).Key ?? originalValues;
101      variableValuesMapping[originalValues] = matchingValues;
102      return matchingValues;
103    }
104
105    private static bool EqualVariableValues(ValuesType values1, ValuesType values2) {
106      //compare variable names for equality
107      if (!values1.Keys.SequenceEqual(values2.Keys)) return false;
108      foreach (var key in values1.Keys) {
109        var v1 = values1[key];
110        var v2 = values2[key];
111        if (v1.Count != v2.Count) return false;
112        for (int i = 0; i < v1.Count; i++) {
113          if (!v1[i].Equals(v2[i])) return false;
114        }
115      }
116      return true;
117    }
118
119    private static readonly Action<Dataset, Dictionary<string, IList>> variableValuesSetter;
120    private static readonly Func<Dataset, Dictionary<string, IList>> variableValuesGetter;
121    /// <summary>
122    /// The static initializer is used to create expressions for getting and setting the private variableValues field in the dataset.
123    /// This is done by expressions because the field is private and compiled expression calls are much faster compared to standad reflection calls.
124    /// </summary>
125    static ShrinkDataAnalysisRunsMenuItem() {
126      var dataset = Expression.Parameter(typeof(Dataset));
127      var variableValues = Expression.Parameter(typeof(ValuesType));
128      var valuesExpression = Expression.Field(dataset, "variableValues");
129      var assignExpression = Expression.Assign(valuesExpression, variableValues);
130
131      var variableValuesSetExpression = Expression.Lambda<Action<Dataset, ValuesType>>(assignExpression, dataset, variableValues);
132      variableValuesSetter = variableValuesSetExpression.Compile();
133
134      var variableValuesGetExpression = Expression.Lambda<Func<Dataset, ValuesType>>(valuesExpression, dataset);
135      variableValuesGetter = variableValuesGetExpression.Compile();
136    }
137  }
138}
Note: See TracBrowser for help on using the repository browser.