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

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

MTC *1 Live Up* Update.
MTC working again. Fixed rereservation bug which killed the challenge twice.

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
78            if (foundNode == null)
79                keySearcher.GuiLogMessage("FindNextLeaf(SearchOption.SkipReservedLeafs) returned null!", NotificationLevel.Debug);
80
81            if (skippedReservedNodes)
82                keySearcher.GuiLogMessage("FindNextLeaf(SearchOption.SkipReservedLeafs) skipped reserved nodes!", NotificationLevel.Debug);
83
84            if (foundNode == null && skippedReservedNodes)
85            {
86                keySearcher.GuiLogMessage("Searching again with reserved nodes enabled...", NotificationLevel.Info);
87
88                currentNode = nodeBeforeStarting;
89                statusContainer.IsSearchingForReservedNodes = true;
90                foundNode = FindNextLeaf(SearchOption.UseReservedLeafs);
91                currentNode = foundNode;
92
93                statisticsGenerator.MarkEndOfNodeSearch();
94                return foundNode;
95            }
96
97            currentNode = foundNode;
98
99            statisticsGenerator.MarkEndOfNodeSearch();
100            return foundNode;
101        }
102
103        private Leaf FindNextLeaf(SearchOption useReservedLeafsOption)
104        {
105            try
106            {
107                if (currentNode == null)
108                {
109                    keySearcher.GuiLogMessage("Inside FindNextLeaf: currentNode is null!", NotificationLevel.Debug);
110                    return null;
111                }
112
113                var isReserved = false;
114                var useReservedLeafs = useReservedLeafsOption == SearchOption.UseReservedLeafs;
115
116                keySearcher.GuiLogMessage("Inside FindNextLeaf: updating currentNode now!", NotificationLevel.Debug);
117                storageHelper.UpdateFromDht(currentNode, true);
118                currentNode.UpdateCache();
119                keySearcher.GuiLogMessage("Inside FindNextLeaf: Now entering while loop!", NotificationLevel.Debug);
120                while (currentNode.IsCalculated() || (!useReservedLeafs && (isReserved = currentNode.IsReserved())))
121                {
122                    if (isReserved)
123                    {
124                        keySearcher.GuiLogMessage("Inside FindNextLeaf: currentNode was reserved!", NotificationLevel.Debug);
125                        skippedReservedNodes = true;
126                    }
127                    if (currentNode.IsCalculated())
128                        keySearcher.GuiLogMessage("Inside FindNextLeaf: currentNode is already calculated!", NotificationLevel.Debug);
129
130                    // Current node is calculated or reserved,
131                    // move one node up and update it
132                    keySearcher.GuiLogMessage("Inside FindNextLeaf: set currentNode to its own parent!", NotificationLevel.Debug);
133                    currentNode = currentNode.ParentNode;
134
135                    // Root node calculated => everything finished
136                    if (currentNode == null)
137                    {
138                        keySearcher.GuiLogMessage("Inside FindNextLeaf: parent was null, so set currentNode to rootNode!", NotificationLevel.Debug);
139                        currentNode = rootNode;
140                        return null;
141                    }
142
143                    keySearcher.GuiLogMessage("Inside FindNextLeaf: updating currentNode now!", NotificationLevel.Debug);
144                    // Update the new _currentNode
145                    storageHelper.UpdateFromDht(currentNode, true);
146                    currentNode.UpdateCache();
147                }
148
149                keySearcher.GuiLogMessage("Inside FindNextLeaf: Exiting loop! Updating currentNode!", NotificationLevel.Debug);
150                // currentNode is calculateable => find leaf
151                currentNode.UpdateCache();
152                return currentNode.CalculatableLeaf(useReservedLeafs);
153            }
154            catch (KeySearcherStopException)
155            {
156                throw new KeySearcherStopException();
157            }
158        }
159
160
161        internal bool IsCalculationFinished()
162        {
163            try
164            {
165                storageHelper.UpdateFromDht(rootNode, true);
166                return rootNode.IsCalculated();
167            }
168            catch (KeySearcherStopException)
169            {
170                throw new KeySearcherStopException();
171            }
172        }
173
174        internal void Reset()
175        {
176            rootNode.Reset();
177            currentNode = rootNode;
178            skippedReservedNodes = false;
179        }
180
181        public static void ProcessCurrentPatternCalculationResult(Leaf currentLeaf,
182                                                                  LinkedList<KeySearcher.ValueKey> result)
183        {
184            currentLeaf.HandleResults(result);
185        }
186
187        public void UpdateStatusForNewCalculation()
188        {
189            statusUpdater.SendUpdate(DistributedJobStatus.Status.New);
190        }
191
192        public void UpdateStatusForFinishedCalculation()
193        {
194            statusUpdater.SendUpdate(DistributedJobStatus.Status.Finished);
195        }
196
197        public void UpdateStatus(Leaf currentLeaf)
198        {
199            var isHigherPatternThanBefore = (currentLeaf.PatternId() + 1) >= statisticsGenerator.HighestChunkCalculated;
200            var isLastPattern = currentLeaf.PatternId() == statisticsGenerator.TotalAmountOfChunks - 1;
201            var patternIdQualifiesForUpdate = currentLeaf.PatternId() % updateIntervalMod == 0;
202
203            if ((!isHigherPatternThanBefore || !patternIdQualifiesForUpdate) && !isLastPattern) return;
204            statusUpdater.SendUpdate();
205            keySearcher.GuiLogMessage(Resources.Updating_status_in_DHT, NotificationLevel.Info);
206        }
207    }
208}
Note: See TracBrowser for help on using the repository browser.