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

Last change on this file since 2142 was 2142, checked in by nolte, 11 years ago

Full working Versionnumber code added.
INFO: THE UNCOMMENTED UPDATE WILL BE COMITTED THURSDAY 8PM (20Uhr :P )
PLEASE UPDATE YOUR SVN AFTERWARDS!

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