Free cookie consent management tool by TermsFeed Policy Generator

source: branches/DataPreprocessing/HeuristicLab.DataPreprocessing/3.4/Implementations/TransactionalPreprocessingData.cs @ 10978

Last change on this file since 10978 was 10978, checked in by mleitner, 10 years ago

Refactoring

File size: 6.4 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2013 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;
24using System.Collections.Generic;
25using HeuristicLab.Common;
26using HeuristicLab.Core;
27using HeuristicLab.Problems.DataAnalysis;
28using HeuristicLab.Problems.DataAnalysis.Transformations;
29
30namespace HeuristicLab.DataPreprocessing {
31
32  [Item("PreprocessingData", "Represents data used for preprocessing.")]
33  public class TransactionalPreprocessingData : PreprocessingData, ITransactionalPreprocessingData {
34
35    private class Snapshot {
36      public IList<IList> VariableValues { get; set; }
37      public IList<string> VariableNames { get; set; }
38
39      public double TrainingToTestRatio { get; set; }
40      public IList<ITransformation> Transformations { get; set; }
41      public DataPreprocessingChangedEventType ChangedType { get; set; }
42
43      public int ChangedColumn { get; set; }
44      public int ChangedRow { get; set; }
45    }
46
47    private const int MAX_UNDO_DEPTH = 5;
48
49    private readonly IList<Snapshot> undoHistory = new List<Snapshot>();
50    private readonly Stack<DataPreprocessingChangedEventType> eventStack = new Stack<DataPreprocessingChangedEventType>();
51
52    public bool IsInTransaction { get { return eventStack.Count > 0; } }
53
54    public TransactionalPreprocessingData(IDataAnalysisProblemData problemData)
55      : base(problemData) {
56    }
57
58    private TransactionalPreprocessingData(TransactionalPreprocessingData original, Cloner cloner)
59      : base(original, cloner) {
60     }
61
62    private void SaveSnapshot(DataPreprocessingChangedEventType changedType, int column, int row) {
63      if (IsInTransaction) return;
64
65      var currentSnapshot = new Snapshot {
66        VariableValues = CopyVariableValues(variableValues),
67        VariableNames = new List<string>(variableNames),
68        TrainingToTestRatio = trainingToTestRatio,
69        Transformations = new List<ITransformation>(transformations),
70        ChangedType = changedType,
71        ChangedColumn = column,
72        ChangedRow = row
73      };
74
75      if (undoHistory.Count >= MAX_UNDO_DEPTH)
76        undoHistory.RemoveAt(0);
77
78      undoHistory.Add(currentSnapshot);
79    }
80
81    #region NamedItem abstract Member Implementations
82
83    public override IDeepCloneable Clone(Cloner cloner) {
84      return new TransactionalPreprocessingData(this, cloner);
85    }
86
87    #endregion
88
89    #region Overridden IPreprocessingData Members
90
91    public override void SetCell<T>(int columnIndex, int rowIndex, T value) {
92      SaveSnapshot(DataPreprocessingChangedEventType.ChangeItem, columnIndex, rowIndex);
93      base.SetCell<T>(columnIndex, rowIndex, value);
94      if (!IsInTransaction)
95        OnChanged(DataPreprocessingChangedEventType.ChangeItem, columnIndex, rowIndex);
96    }
97
98    public override void SetValues<T>(int columnIndex, IList<T> values) {
99      SaveSnapshot(DataPreprocessingChangedEventType.ChangeColumn, columnIndex, -1);
100      base.SetValues<T>(columnIndex, values);
101      if (!IsInTransaction)
102        OnChanged(DataPreprocessingChangedEventType.ChangeColumn, columnIndex, -1);
103    }
104
105    public override void InsertRow(int rowIndex) {
106      SaveSnapshot(DataPreprocessingChangedEventType.DeleteRow, -1, rowIndex);
107      base.InsertRow(rowIndex);
108      if (!IsInTransaction)
109        OnChanged(DataPreprocessingChangedEventType.AddRow, -1, rowIndex);
110    }
111
112    public override void DeleteRow(int rowIndex) {
113      SaveSnapshot(DataPreprocessingChangedEventType.AddRow, -1, rowIndex);
114      base.DeleteRow(rowIndex);
115      if (!IsInTransaction)
116        OnChanged(DataPreprocessingChangedEventType.DeleteRow, -1, rowIndex);
117    }
118
119    public override void InsertColumn<T>(string variableName, int columnIndex) {
120      SaveSnapshot(DataPreprocessingChangedEventType.DeleteColumn, columnIndex, -1);
121      base.InsertColumn<T>(variableName, columnIndex);
122      if (!IsInTransaction)
123        OnChanged(DataPreprocessingChangedEventType.AddColumn, columnIndex, -1);
124    }
125
126    public override void DeleteColumn(int columnIndex) {
127      SaveSnapshot(DataPreprocessingChangedEventType.AddColumn, columnIndex, -1);
128      base.DeleteColumn(columnIndex);
129      if (!IsInTransaction)
130        OnChanged(DataPreprocessingChangedEventType.DeleteColumn, columnIndex, -1);
131    }
132
133    #endregion
134
135    #region TransactionalPreprocessingData members
136
137    public bool IsUndoAvailable {
138      get { return undoHistory.Count > 0; }
139    }
140
141    public void Undo() {
142      if (IsUndoAvailable) {
143        Snapshot previousSnapshot = undoHistory[undoHistory.Count - 1];
144        variableValues = previousSnapshot.VariableValues;
145        variableNames = previousSnapshot.VariableNames;
146        trainingToTestRatio = previousSnapshot.TrainingToTestRatio;
147        transformations = previousSnapshot.Transformations;
148        undoHistory.Remove(previousSnapshot);
149        OnChanged(previousSnapshot.ChangedType,
150          previousSnapshot.ChangedColumn,
151          previousSnapshot.ChangedRow);
152      }
153    }
154
155    public void InTransaction(Action action, DataPreprocessingChangedEventType type = DataPreprocessingChangedEventType.Any) {
156      BeginTransaction(type);
157      action();
158      EndTransaction();
159    }
160
161    public void BeginTransaction(DataPreprocessingChangedEventType type) {
162      SaveSnapshot(type, -1, -1);
163      eventStack.Push(type);
164    }
165
166    public void EndTransaction() {
167      if (eventStack.Count == 0)
168        throw new InvalidOperationException("There is no open transaction that can be ended.");
169
170      var @event = eventStack.Pop();
171      OnChanged(@event, -1, -1);
172    }
173
174    #endregion
175  }
176}
Note: See TracBrowser for help on using the repository browser.