Changeset 15427


Ignore:
Timestamp:
10/20/17 17:39:51 (2 years ago)
Author:
bburlacu
Message:

#2848: Factor out functionality into static methods inside DatasetUtil.cs and adjust menu item code.

Location:
trunk/sources
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/MenuItems/ShrinkDataAnalysisRunsMenuItem.cs

    r14185 r15427  
    2323
    2424using System;
    25 using System.Collections;
    2625using System.Collections.Generic;
    2726using System.Linq;
    28 using System.Linq.Expressions;
    29 using HeuristicLab.Common;
    3027using HeuristicLab.MainForm;
    3128using HeuristicLab.Optimization;
     
    3330
    3431using MenuItem = HeuristicLab.MainForm.WindowsForms.MenuItem;
    35 using ValuesType = System.Collections.Generic.Dictionary<string, System.Collections.IList>;
    3632
    3733namespace HeuristicLab.Problems.DataAnalysis.Views {
     
    7975      mainForm.AddOperationProgressToContent(activeView.Content, "Removing duplicate datasets.");
    8076
    81       Action<IContentView> action = (view) => {
    82         var variableValuesMapping = new Dictionary<ValuesType, ValuesType>();
    83         foreach (var problemData in view.Content.GetObjectGraphObjects(excludeStaticMembers: true).OfType<IDataAnalysisProblemData>()) {
    84           var dataset = problemData.Dataset as Dataset;
    85           if (dataset == null) continue;
    86           var originalValues = variableValuesGetter(dataset);
    87           var matchingValues = GetEqualValues(originalValues, variableValuesMapping);
    88           variableValuesSetter(dataset, matchingValues);
    89         }
    90       };
     77      Action<IContentView> action = (view) => DatasetUtil.RemoveDuplicateDatasets(view.Content);
    9178
    92       action.BeginInvoke(activeView, delegate(IAsyncResult result) {
     79      action.BeginInvoke(activeView, delegate (IAsyncResult result) {
    9380        action.EndInvoke(result);
    9481        mainForm.RemoveOperationProgressFromContent(activeView.Content);
    9582      }, null);
    9683    }
    97 
    98     private static ValuesType GetEqualValues(ValuesType originalValues, Dictionary<ValuesType, ValuesType> variableValuesMapping) {
    99       if (variableValuesMapping.ContainsKey(originalValues)) return variableValuesMapping[originalValues];
    100 
    101       var matchingValues = variableValuesMapping.FirstOrDefault(kv => kv.Key == kv.Value && EqualVariableValues(originalValues, kv.Key)).Key ?? originalValues;
    102       variableValuesMapping[originalValues] = matchingValues;
    103       return matchingValues;
    104     }
    105 
    106     private static bool EqualVariableValues(ValuesType values1, ValuesType values2) {
    107       //compare variable names for equality
    108       if (!values1.Keys.SequenceEqual(values2.Keys)) return false;
    109       foreach (var key in values1.Keys) {
    110         var v1 = values1[key];
    111         var v2 = values2[key];
    112         if (v1.Count != v2.Count) return false;
    113         for (int i = 0; i < v1.Count; i++) {
    114           if (!v1[i].Equals(v2[i])) return false;
    115         }
    116       }
    117       return true;
    118     }
    119 
    120     private static readonly Action<Dataset, Dictionary<string, IList>> variableValuesSetter;
    121     private static readonly Func<Dataset, Dictionary<string, IList>> variableValuesGetter;
    122     /// <summary>
    123     /// The static initializer is used to create expressions for getting and setting the private variableValues field in the dataset.
    124     /// This is done by expressions because the field is private and compiled expression calls are much faster compared to standad reflection calls.
    125     /// </summary>
    126     static ShrinkDataAnalysisRunsMenuItem() {
    127       var dataset = Expression.Parameter(typeof(Dataset));
    128       var variableValues = Expression.Parameter(typeof(ValuesType));
    129       var valuesExpression = Expression.Field(dataset, "variableValues");
    130       var assignExpression = Expression.Assign(valuesExpression, variableValues);
    131 
    132       var variableValuesSetExpression = Expression.Lambda<Action<Dataset, ValuesType>>(assignExpression, dataset, variableValues);
    133       variableValuesSetter = variableValuesSetExpression.Compile();
    134 
    135       var variableValuesGetExpression = Expression.Lambda<Func<Dataset, ValuesType>>(valuesExpression, dataset);
    136       variableValuesGetter = variableValuesGetExpression.Compile();
    137     }
    13884  }
    13985}
  • trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/DatasetUtil.cs

    r15013 r15427  
    2323using System.Collections;
    2424using System.Collections.Generic;
    25 using System.ComponentModel;
    2625using System.Linq;
    27 using System.Text;
     26using System.Linq.Expressions;
     27using HeuristicLab.Common;
    2828using HeuristicLab.Core;
    2929using HeuristicLab.Random;
    3030
    3131namespace HeuristicLab.Problems.DataAnalysis {
     32  using ValuesType = Dictionary<string, IList>;
     33
    3234  public static class DatasetUtil {
    3335    /// <summary>
     
    5759      }
    5860      return shuffled;
     61    }
    5962
     63    private static readonly Action<Dataset, ValuesType> setValues;
     64    private static readonly Func<Dataset, ValuesType> getValues;
     65    static DatasetUtil() {
     66      var dataset = Expression.Parameter(typeof(Dataset));
     67      var variableValues = Expression.Parameter(typeof(ValuesType));
     68      var valuesExpression = Expression.Field(dataset, "variableValues");
     69      var assignExpression = Expression.Assign(valuesExpression, variableValues);
     70
     71      var variableValuesSetExpression = Expression.Lambda<Action<Dataset, ValuesType>>(assignExpression, dataset, variableValues);
     72      setValues = variableValuesSetExpression.Compile();
     73
     74      var variableValuesGetExpression = Expression.Lambda<Func<Dataset, ValuesType>>(valuesExpression, dataset);
     75      getValues = variableValuesGetExpression.Compile();
     76    }
     77
     78    public static void RemoveDuplicateDatasets(IContent content) {
     79      var variableValuesMapping = new Dictionary<ValuesType, ValuesType>();
     80
     81      foreach (var problemData in content.GetObjectGraphObjects(excludeStaticMembers: true).OfType<IDataAnalysisProblemData>()) {
     82        var dataset = problemData.Dataset as Dataset;
     83        if (dataset == null) continue;
     84
     85        var originalValues = getValues(dataset);
     86
     87        ValuesType matchingValues;
     88
     89        variableValuesMapping.GetEqualValues(originalValues, out matchingValues);
     90
     91        setValues(dataset, matchingValues);
     92      }
     93    }
     94
     95    private static bool GetEqualValues(this Dictionary<ValuesType, ValuesType> variableValuesMapping, ValuesType originalValues, out ValuesType matchingValues) {
     96      if (variableValuesMapping.ContainsKey(originalValues)) {
     97        matchingValues = variableValuesMapping[originalValues];
     98        return true;
     99      }
     100      matchingValues = variableValuesMapping.FirstOrDefault(kv => kv.Key == kv.Value && EqualVariableValues(originalValues, kv.Key)).Key;
     101      bool result = true;
     102      if (matchingValues == null) {
     103        matchingValues = originalValues;
     104        result = false;
     105      }
     106      variableValuesMapping[originalValues] = matchingValues;
     107      return result;
     108    }
     109
     110    private static bool EqualVariableValues(ValuesType values1, ValuesType values2) {
     111      //compare variable names for equality
     112      if (!values1.Keys.SequenceEqual(values2.Keys)) return false;
     113      foreach (var key in values1.Keys) {
     114        var v1 = values1[key];
     115        var v2 = values2[key];
     116        if (v1.Count != v2.Count) return false;
     117        for (int i = 0; i < v1.Count; i++) {
     118          if (!v1[i].Equals(v2[i])) return false;
     119        }
     120      }
     121      return true;
    60122    }
    61123  }
Note: See TracChangeset for help on using the changeset viewer.