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

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

+ KeySearcher: display of aggregated linkmanager statistics
o KeySearcher: job identifier extended with sample decryption data to preserve decryption algorithm settings

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