source: trunk/CrypPlugins/KeySearcher/P2P/Tree/KeyPoolTree.cs @ 2295

Last change on this file since 2295 was 2295, checked in by Sven Rech, 11 years ago

Prepared KeySearcher for Localization

File size: 8.8 KB
Line 
1using System;
2using System.Collections.Generic;
3using Cryptool.P2PEditor.Distributed;
4using Cryptool.PluginBase;
5using KeySearcher.Helper;
6using KeySearcher.KeyPattern;
7using KeySearcher.P2P.Exceptions;
8using KeySearcher.P2P.Presentation;
9using KeySearcher.P2P.Storage;
10using KeySearcher.Properties;
11
12namespace KeySearcher.P2P.Tree
13{
14    internal class KeyPoolTree
15    {
16        public readonly string Identifier;
17       
18        private readonly KeySearcher keySearcher;
19        private readonly StatusContainer statusContainer;
20        private readonly StatisticsGenerator statisticsGenerator;
21        private readonly KeyPatternPool patternPool;
22        private readonly NodeBase rootNode;
23        private readonly StorageHelper storageHelper;
24        private readonly StatusUpdater statusUpdater;
25        private readonly int updateIntervalMod;
26
27        private NodeBase currentNode;
28        private bool skippedReservedNodes;
29
30        private enum SearchOption { UseReservedLeafs, SkipReservedLeafs }
31
32        public KeyPoolTree(KeyPatternPool patternPool, KeySearcher keySearcher, KeyQualityHelper keyQualityHelper, StorageKeyGenerator identifierGenerator, StatusContainer statusContainer, StatisticsGenerator statisticsGenerator)
33        {
34            this.patternPool = patternPool;
35            this.keySearcher = keySearcher;
36            this.statusContainer = statusContainer;
37            this.statisticsGenerator = statisticsGenerator;
38            Identifier = identifierGenerator.Generate();
39
40            storageHelper = new StorageHelper(keySearcher, statisticsGenerator, statusContainer);
41            statusUpdater = new StatusUpdater(statusContainer, identifierGenerator.GenerateStatusKey());
42            skippedReservedNodes = false;
43            updateIntervalMod = 5;
44
45            statisticsGenerator.MarkStartOfNodeSearch();
46            rootNode = NodeFactory.CreateNode(storageHelper, keyQualityHelper, null, 0, this.patternPool.Length - 1,
47                                              Identifier);
48            statisticsGenerator.MarkEndOfNodeSearch();
49
50            currentNode = rootNode;
51        }
52
53        public DateTime StartDate()
54        {
55            return storageHelper.StartDate(Identifier);
56        }
57
58        //---------------------------------------------------
59        public long SubmitterID()
60        {
61            return storageHelper.SubmitterID(Identifier);
62        }
63        //----------------------------------------------------
64
65        public Leaf FindNextLeaf()
66        {
67            // REMOVEME uncommenting the next line will cause a search for the next free pattern starting from the root node - for every leaf!
68            //Reset();
69
70            statusContainer.IsSearchingForReservedNodes = false;
71            statisticsGenerator.MarkStartOfNodeSearch();
72
73            var nodeBeforeStarting = currentNode;
74            keySearcher.GuiLogMessage("Calling FindNextLeaf(SearchOption.SkipReservedLeafs) now!", NotificationLevel.Debug);
75            var foundNode = FindNextLeaf(SearchOption.SkipReservedLeafs);
76            keySearcher.GuiLogMessage("Returned from FindNextLeaf(SearchOption.SkipReservedLeafs)...", NotificationLevel.Debug);
77            if (foundNode == null)
78                keySearcher.GuiLogMessage("FindNextLeaf(SearchOption.SkipReservedLeafs) returned null!", NotificationLevel.Debug);
79            if (skippedReservedNodes)
80                keySearcher.GuiLogMessage("FindNextLeaf(SearchOption.SkipReservedLeafs) skipped reserved nodes!", NotificationLevel.Debug);
81
82            if (foundNode == null && skippedReservedNodes)
83            {
84                keySearcher.GuiLogMessage("Searching again with reserved nodes enabled...", NotificationLevel.Info);
85
86                currentNode = nodeBeforeStarting;
87                statusContainer.IsSearchingForReservedNodes = true;
88                foundNode = FindNextLeaf(SearchOption.UseReservedLeafs);
89                currentNode = foundNode;
90
91                statisticsGenerator.MarkEndOfNodeSearch();
92                return foundNode;
93            }
94
95            currentNode = foundNode;
96
97            statisticsGenerator.MarkEndOfNodeSearch();
98            return foundNode;
99        }
100
101        private Leaf FindNextLeaf(SearchOption useReservedLeafsOption)
102        {
103            try
104            {
105                if (currentNode == null)
106                {
107                    keySearcher.GuiLogMessage("Inside FindNextLeaf: currentNode is null!", NotificationLevel.Debug);
108                    return null;
109                }
110
111                var isReserved = false;
112                var useReservedLeafs = useReservedLeafsOption == SearchOption.UseReservedLeafs;
113
114                keySearcher.GuiLogMessage("Inside FindNextLeaf: updating currentNode now!", NotificationLevel.Debug);
115                storageHelper.UpdateFromDht(currentNode, true);
116                currentNode.UpdateCache();
117                keySearcher.GuiLogMessage("Inside FindNextLeaf: Now entering while loop!", NotificationLevel.Debug);
118                while (currentNode.IsCalculated() || (!useReservedLeafs && (isReserved = currentNode.IsReserved())))
119                {
120                    if (isReserved)
121                    {
122                        keySearcher.GuiLogMessage("Inside FindNextLeaf: currentNode was reserved!", NotificationLevel.Debug);
123                        skippedReservedNodes = true;
124                    }
125                    if (currentNode.IsCalculated())
126                        keySearcher.GuiLogMessage("Inside FindNextLeaf: currentNode is already calculated!", NotificationLevel.Debug);
127
128                    // Current node is calculated or reserved,
129                    // move one node up and update it
130                    keySearcher.GuiLogMessage("Inside FindNextLeaf: set currentNode to its own parent!", NotificationLevel.Debug);
131                    currentNode = currentNode.ParentNode;
132
133                    // Root node calculated => everything finished
134                    if (currentNode == null)
135                    {
136                        keySearcher.GuiLogMessage("Inside FindNextLeaf: parent was null, so set currentNode to rootNode!", NotificationLevel.Debug);
137                        currentNode = rootNode;
138                        return null;
139                    }
140
141                    keySearcher.GuiLogMessage("Inside FindNextLeaf: updating currentNode now!", NotificationLevel.Debug);
142                    // Update the new _currentNode
143                    storageHelper.UpdateFromDht(currentNode, true);
144                    currentNode.UpdateCache();
145                }
146
147                keySearcher.GuiLogMessage("Inside FindNextLeaf: Exiting loop! Updating currentNode!", NotificationLevel.Debug);
148                // currentNode is calculateable => find leaf
149                currentNode.UpdateCache();
150                return currentNode.CalculatableLeaf(useReservedLeafs);
151            }
152            catch (KeySearcherStopException)
153            {
154                throw new KeySearcherStopException();
155            }
156        }
157
158
159        internal bool IsCalculationFinished()
160        {
161            try
162            {
163                storageHelper.UpdateFromDht(rootNode, true);
164                return rootNode.IsCalculated();
165            }
166            catch (KeySearcherStopException)
167            {
168                throw new KeySearcherStopException();
169            }
170        }
171
172        internal void Reset()
173        {
174            rootNode.Reset();
175            currentNode = rootNode;
176            skippedReservedNodes = false;
177        }
178
179        public static void ProcessCurrentPatternCalculationResult(Leaf currentLeaf,
180                                                                  LinkedList<KeySearcher.ValueKey> result)
181        {
182            currentLeaf.HandleResults(result);
183        }
184
185        public void UpdateStatusForNewCalculation()
186        {
187            statusUpdater.SendUpdate(DistributedJobStatus.Status.New);
188        }
189
190        public void UpdateStatusForFinishedCalculation()
191        {
192            statusUpdater.SendUpdate(DistributedJobStatus.Status.Finished);
193        }
194
195        public void UpdateStatus(Leaf currentLeaf)
196        {
197            var isHigherPatternThanBefore = (currentLeaf.PatternId() + 1) >= statisticsGenerator.HighestChunkCalculated;
198            var isLastPattern = currentLeaf.PatternId() == statisticsGenerator.TotalAmountOfChunks - 1;
199            var patternIdQualifiesForUpdate = currentLeaf.PatternId() % updateIntervalMod == 0;
200
201            if ((!isHigherPatternThanBefore || !patternIdQualifiesForUpdate) && !isLastPattern) return;
202            statusUpdater.SendUpdate();
203            keySearcher.GuiLogMessage(Resources.Updating_status_in_DHT, NotificationLevel.Info);
204        }
205    }
206}
Note: See TracBrowser for help on using the repository browser.