source: trunk/CrypPlugins/KeySearcher/P2P/DistributedBruteForceManager.cs @ 1729

Last change on this file since 1729 was 1729, checked in by Paul Lelgemann, 12 years ago

o KeySearcher: fixed bugs in global statistic

File size: 8.2 KB
Line 
1using System;
2using System.Diagnostics;
3using System.Numerics;
4using System.Windows.Threading;
5using Cryptool.P2P;
6using Cryptool.PluginBase;
7using KeySearcher.Helper;
8using KeySearcher.KeyPattern;
9using KeySearcher.P2P.Exceptions;
10using KeySearcher.P2P.Helper;
11using KeySearcher.P2P.Presentation;
12using KeySearcher.P2P.Storage;
13using KeySearcher.P2P.Tree;
14using KeySearcherPresentation.Controls;
15
16namespace KeySearcher.P2P
17{
18    internal class DistributedBruteForceManager
19    {
20        private readonly StorageKeyGenerator keyGenerator;
21        private readonly KeySearcher keySearcher;
22        private readonly KeySearcherSettings settings;
23        private readonly KeyQualityHelper keyQualityHelper;
24        private readonly P2PQuickWatchPresentation quickWatch;
25        private readonly KeyPatternPool patternPool;
26        private readonly StatusContainer status;
27        internal readonly StatisticsGenerator StatisticsGenerator;
28        internal readonly Stopwatch StopWatch;
29
30        private KeyPoolTree keyPoolTree;
31
32        public DistributedBruteForceManager(KeySearcher keySearcher, KeyPattern.KeyPattern keyPattern, KeySearcherSettings settings,
33                                            KeyQualityHelper keyQualityHelper, P2PQuickWatchPresentation quickWatch)
34        {
35            this.keySearcher = keySearcher;
36            this.settings = settings;
37            this.keyQualityHelper = keyQualityHelper;
38            this.quickWatch = quickWatch;
39
40            // TODO when setting is still default (21), it is only displayed as 21 - but the settings-instance contains 0 for that key!
41            if (settings.ChunkSize == 0)
42            {
43                settings.ChunkSize = 21;
44            }
45
46            StopWatch = new Stopwatch();
47            status = new StatusContainer();
48            status.IsCurrentProgressIndeterminate = true;
49
50            keyGenerator = new StorageKeyGenerator(keySearcher, settings);
51            patternPool = new KeyPatternPool(keyPattern, new BigInteger(Math.Pow(2, settings.ChunkSize)));
52            StatisticsGenerator = new StatisticsGenerator(status, quickWatch, keySearcher, settings, this);
53            quickWatch.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(UpdateStatusContainerInQuickWatch));
54        }
55
56        public void Execute()
57        {
58            status.CurrentOperation = "Initializing connection to the peer-to-peer system";
59            new ConnectionHelper(keySearcher, settings).ValidateConnectionToPeerToPeerSystem();
60
61            if (!P2PManager.IsConnected)
62            {
63                keySearcher.GuiLogMessage("Unable to use peer-to-peer system.", NotificationLevel.Error);
64                status.CurrentOperation = "Unable to use peer-to-peer system";
65                return;
66            }
67
68            status.CurrentOperation = "Initializing distributed key pool tree";
69            keyPoolTree = new KeyPoolTree(patternPool, this.keySearcher, keyQualityHelper, keyGenerator, status, StatisticsGenerator);
70
71            keySearcher.GuiLogMessage(
72                "Total amount of patterns: " + patternPool.Length + ", each containing " + patternPool.PartSize +
73                " keys.", NotificationLevel.Info);
74            status.CurrentOperation = "Ready for calculation";
75
76            status.StartDate = keyPoolTree.StartDate();
77            keyPoolTree.UpdateStatusForNewCalculation();
78
79            Leaf currentLeaf;
80            while (!keySearcher.stop)
81            {
82                status.IsCurrentProgressIndeterminate = true;
83
84                BigInteger displayablePatternId;
85                try
86                {
87                    status.CurrentOperation = "Finding next leaf to calculate";
88                    currentLeaf = keyPoolTree.FindNextLeaf();
89                    if (currentLeaf == null)
90                    {
91                        break;
92                    }
93                    displayablePatternId = currentLeaf.PatternId() + 1;
94                }
95                catch (AlreadyCalculatedException)
96                {
97                    keySearcher.GuiLogMessage("Node was already calculated.", NotificationLevel.Info);
98                    keyPoolTree.Reset();
99                    continue;
100                }
101
102                if (!currentLeaf.ReserveLeaf())
103                {
104                    keySearcher.GuiLogMessage(
105                        "Pattern #" + displayablePatternId +
106                        " was reserved before it could be reserved for this CrypTool instance.",
107                        NotificationLevel.Info);
108                    keyPoolTree.Reset();
109                    continue;
110                }
111
112                keySearcher.GuiLogMessage(
113                    "Running pattern #" + displayablePatternId + " of " + patternPool.Length,
114                    NotificationLevel.Info);
115                status.CurrentChunk = displayablePatternId;
116                status.CurrentOperation = "Calculating pattern " + status.CurrentChunk;
117
118                try
119                {
120                    status.IsCurrentProgressIndeterminate = false;
121                    StopWatch.Start();
122                    var result = keySearcher.BruteForceWithLocalSystem(patternPool[currentLeaf.PatternId()], true);
123                    StopWatch.Stop();
124                    status.IsCurrentProgressIndeterminate = true;
125
126                    if (!keySearcher.stop)
127                    {
128                        status.CurrentOperation = "Processing results of calculation";
129                        KeyPoolTree.ProcessCurrentPatternCalculationResult(currentLeaf, result);
130                        StatisticsGenerator.ProcessPatternResults(result);
131
132                        status.CurrentOperation = "Calculating global statistics";
133                        StatisticsGenerator.CalculateGlobalStatistics(displayablePatternId);
134
135                        status.LocalFinishedChunks++;
136                        keySearcher.GuiLogMessage(
137                            string.Format("Best match: {0} with {1}", result.First.Value.key, result.First.Value.value),
138                            NotificationLevel.Info);
139
140                        status.CurrentOperation = "Updating status in DHT";
141                        keyPoolTree.UpdateStatus(currentLeaf);
142                    }
143                    else
144                    {
145                        keySearcher.GuiLogMessage("Brute force was stopped, not saving results...",
146                                                  NotificationLevel.Info);
147                        status.ProgressOfCurrentChunk = 0;
148                    }
149                }
150                catch (ReservationRemovedException)
151                {
152                    keySearcher.GuiLogMessage("Reservation removed by another node (while calculating). " +
153                                              "To avoid a state in limbo, proceeding to first available leaf...",
154                                              NotificationLevel.Info);
155                    keyPoolTree.Reset();
156                    continue;
157                }
158                catch (UpdateFailedException e)
159                {
160                    keySearcher.GuiLogMessage("Could not store results: " + e.Message, NotificationLevel.Info);
161                    keyPoolTree.Reset();
162                    continue;
163                }
164            }
165
166            // Set progress to 100%
167            if (!keySearcher.stop && keyPoolTree.IsCalculationFinished())
168            {
169                keySearcher.showProgress(keySearcher.costList, 1, 1, 1);
170                keySearcher.GuiLogMessage("Calculation complete.", NotificationLevel.Info);
171                keyPoolTree.UpdateStatusForFinishedCalculation();
172               
173            }
174
175            StatisticsGenerator.CalculationStopped();
176            status.ProgressOfCurrentChunk = 0;
177            status.IsSearchingForReservedNodes = false;
178            status.IsCurrentProgressIndeterminate = false;
179            status.CurrentOperation = "Idle";
180            status.RemainingTimeTotal = new TimeSpan(0);
181        }
182
183        private void UpdateStatusContainerInQuickWatch()
184        {
185            quickWatch.DataContext = status;
186            quickWatch.UpdateSettings(keySearcher, settings);
187        }
188    }
189}
Note: See TracBrowser for help on using the repository browser.