source: trunk/CrypPlugins/KeySearcher/P2P/Presentation/StatisticsGenerator.cs @ 1708

Last change on this file since 1708 was 1708, checked in by Paul Lelgemann, 11 years ago

o KeySearcher: small visualization fixes

File size: 9.7 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Diagnostics;
4using System.Numerics;
5using System.Text;
6using System.Threading;
7using System.Windows.Threading;
8using Cryptool.P2P;
9using KeySearcher.KeyPattern;
10using KeySearcherPresentation.Controls;
11using Timer = System.Timers.Timer;
12
13namespace KeySearcher.P2P.Presentation
14{
15    class StatisticsGenerator
16    {
17        private readonly StatusContainer status;
18        private readonly P2PQuickWatchPresentation quickWatch;
19        private readonly KeySearcher keySearcher;
20        private readonly DistributedBruteForceManager distributedBruteForceManager;
21        private readonly BigInteger totalAmountOfChunks;
22        private readonly Stopwatch stopWatch;
23        private readonly Timer elapsedTimeTimer;
24        private readonly Timer trafficUpdateTimer;
25
26        private DateTime lastDateOfGlobalStatistics;
27        private BigInteger highestChunkCalculated;
28        private BigInteger totalRequestsAtStartOfNodeSearch;
29
30        public StatisticsGenerator(StatusContainer status, P2PQuickWatchPresentation quickWatch, KeySearcher keySearcher, KeySearcherSettings settings, DistributedBruteForceManager distributedBruteForceManager)
31        {
32            this.status = status;
33            this.quickWatch = quickWatch;
34            this.keySearcher = keySearcher;
35            this.distributedBruteForceManager = distributedBruteForceManager;
36
37            lastDateOfGlobalStatistics = DateTime.Now;
38            highestChunkCalculated = -1;
39            stopWatch = new Stopwatch();
40
41            var keyPattern = new KeyPattern.KeyPattern(keySearcher.ControlMaster.getKeyPattern())
42                                 {WildcardKey = settings.Key};
43            var keysPerChunk = Math.Pow(2, settings.ChunkSize);
44            var keyPatternPool = new KeyPatternPool(keyPattern, new BigInteger(keysPerChunk));
45
46            totalAmountOfChunks = keyPatternPool.Length;
47
48            status.PropertyChanged += StatusPropertyChanged;
49
50            elapsedTimeTimer = new Timer(1000);
51            elapsedTimeTimer.Elapsed += ElapsedTimeTimerTick;
52            elapsedTimeTimer.Start();
53
54            trafficUpdateTimer = new Timer(10000);
55            trafficUpdateTimer.Elapsed += TrafficUpdateTimerTick;
56            trafficUpdateTimer.Start();
57        }
58
59        public void CalculationStopped()
60        {
61            elapsedTimeTimer.Stop();
62            trafficUpdateTimer.Stop();
63        }
64
65        void TrafficUpdateTimerTick(object sender, System.Timers.ElapsedEventArgs e)
66        {
67            UpdateTrafficStatistics();
68        }
69
70        void ElapsedTimeTimerTick(object sender, EventArgs e)
71        {
72            status.ElapsedTime = DateTime.Now.Subtract(status.StartDate);
73
74            if (status.RemainingTimeTotal > new TimeSpan(0))
75                status.RemainingTimeTotal = status.RemainingTimeTotal.Subtract(TimeSpan.FromSeconds(1));
76        }
77
78        void StatusPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
79        {
80            switch (e.PropertyName)
81            {
82                case "DhtOverheadInReadableTime":
83                    HandleUpdateOfOverheadTime();
84                    break;
85                case "StoredBytes":
86                    UpdateTrafficStatistics();
87                    break;
88                case "RetrievedBytes":
89                    UpdateTrafficStatistics();
90                    break;
91            }
92        }
93
94        private void UpdateTrafficStatistics()
95        {
96            status.SentBytesByLinkManager = P2PManager.P2PBase.TotalBytesSentOnAllLinks();
97            status.ReceivedBytesByLinkManager = P2PManager.P2PBase.TotalBytesReceivedOnAllLinks();
98            status.TotalBytesByLinkManager = status.ReceivedBytesByLinkManager + status.SentBytesByLinkManager;
99        }
100
101        private void HandleUpdateOfOverheadTime()
102        {
103            if (distributedBruteForceManager.StopWatch.Elapsed.Ticks == 0)
104            {
105                status.DhtOverheadInPercent = "0 %";
106                return;
107            }
108
109            var overheadInTicks = (double)status.DhtOverheadInReadableTime.Ticks /
110                           distributedBruteForceManager.StopWatch.Elapsed.Ticks;
111            var overheadInPercent = overheadInTicks * 100;
112            overheadInPercent = Math.Round(overheadInPercent, 2);
113           
114            status.DhtOverheadInPercent = overheadInPercent + " %";
115        }
116
117        public void MarkStartOfNodeSearch()
118        {
119            totalRequestsAtStartOfNodeSearch = status.TotalDhtRequests;
120            stopWatch.Start();
121        }
122
123        public void MarkEndOfNodeSearch()
124        {
125            stopWatch.Stop();
126            var elapsedTime = stopWatch.Elapsed.Add(status.DhtOverheadInReadableTime);
127            status.DhtOverheadInReadableTime = new TimeSpan(((long) Math.Round((1.0*elapsedTime.Ticks/5))*5));
128            stopWatch.Reset();
129           
130            var requestsForThisNode = status.TotalDhtRequests - totalRequestsAtStartOfNodeSearch;
131
132            if (status.RequestsPerNode == 0)
133            {
134                status.RequestsPerNode = requestsForThisNode;
135                return;
136            }
137
138            status.RequestsPerNode = (status.RequestsPerNode + requestsForThisNode)/2;
139        }
140
141        public void CalculateGlobalStatistics(BigInteger nextChunk)
142        {
143            if (highestChunkCalculated == -1) highestChunkCalculated = nextChunk;
144            if (nextChunk <= highestChunkCalculated) return;
145
146            var totalAmountOfParticipants = nextChunk - highestChunkCalculated;
147            status.TotalAmountOfParticipants = totalAmountOfParticipants;
148
149            var timeUsedForLatestProgress = DateTime.Now.Subtract(lastDateOfGlobalStatistics);
150            var secondsForOneChunk = timeUsedForLatestProgress.TotalSeconds/(double) totalAmountOfParticipants;
151            var remainingChunks = totalAmountOfChunks - nextChunk;
152            var secondsRemaining = (double) remainingChunks*secondsForOneChunk;
153
154            try
155            {
156                var estimatedFinishDate = DateTime.Now.AddSeconds(secondsRemaining);
157                status.EstimatedFinishDate = estimatedFinishDate.ToString("g", Thread.CurrentThread.CurrentCulture);
158                status.RemainingTimeTotal = estimatedFinishDate.Subtract(DateTime.Now);
159            }
160            catch (ArgumentOutOfRangeException)
161            {
162                status.EstimatedFinishDate = "~";
163                status.RemainingTimeTotal = new TimeSpan(-1);
164            }
165
166            lastDateOfGlobalStatistics = DateTime.Now;
167
168            highestChunkCalculated = nextChunk;
169            var globalProgressValue = (double) highestChunkCalculated/(double) totalAmountOfChunks;
170            keySearcher.ProgressChanged(globalProgressValue, 1);
171        }
172
173        public void ProcessPatternResults(LinkedList<KeySearcher.ValueKey> result)
174        {
175            ProcessResultList(result);
176        }
177
178        public void ShowProgress(LinkedList<KeySearcher.ValueKey> bestResultList, BigInteger keysInThisChunk, BigInteger keysFinishedInThisChunk, BigInteger keysPerSecond)
179        {
180            status.ProgressOfCurrentChunk = (double) keysFinishedInThisChunk/(double) keysInThisChunk;
181            status.KeysPerSecond = keysPerSecond;
182
183            var time = (Math.Pow(10, BigInteger.Log((keysInThisChunk - keysFinishedInThisChunk), 10) - BigInteger.Log(keysPerSecond, 10)));
184            var timeleft = new TimeSpan(-1);
185
186            try
187            {
188                if (time / (24 * 60 * 60) <= int.MaxValue)
189                {
190                    int days = (int)(time / (24 * 60 * 60));
191                    time = time - (days * 24 * 60 * 60);
192                    int hours = (int)(time / (60 * 60));
193                    time = time - (hours * 60 * 60);
194                    int minutes = (int)(time / 60);
195                    time = time - (minutes * 60);
196                    int seconds = (int)time;
197
198                    timeleft = new TimeSpan(days, hours, minutes, (int)seconds, 0);
199                }
200            }
201            catch
202            {
203                //can not calculate time span
204            }
205
206            status.RemainingTime = timeleft;
207
208            ProcessResultList(bestResultList);
209        }
210
211        private void ProcessResultList(LinkedList<KeySearcher.ValueKey> bestResultList)
212        {
213            quickWatch.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
214            {
215
216                var enc = Encoding.Default;
217                LinkedListNode<KeySearcher.ValueKey> linkedListNode;
218                status.TopList.Clear();
219                linkedListNode = bestResultList.First;
220
221                int i = 0;
222                while (linkedListNode != null)
223                {
224                    i++;
225
226                    var entry = new ResultEntry();
227                    entry.Ranking = i.ToString();
228                    entry.Value = Math.Round(linkedListNode.Value.value, 2).ToString();
229                    entry.Key = linkedListNode.Value.key;
230                    var plainText = enc.GetString(linkedListNode.Value.decryption);
231
232                    const string replaceWith = "";
233                    plainText = plainText.Replace("\r\n", replaceWith).Replace("\n", replaceWith).Replace("\r", replaceWith);
234                    if (plainText.Length > 30)
235                        plainText = plainText.Substring(0, 30) + "...";
236
237                    entry.Text = plainText;
238
239                    status.TopList.Add(entry);
240                    linkedListNode = linkedListNode.Next;
241                }
242            }, null);
243        }
244    }
245}
Note: See TracBrowser for help on using the repository browser.