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

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

+ P2PEditor can display the status of jobs, if available; Participating displays overlay while loading workspace data
+ KeySearcher can upload status for P2PEditor display

File size: 5.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.Presentation;
8using KeySearcher.P2P.Storage;
9
10namespace KeySearcher.P2P.Tree
11{
12    internal class KeyPoolTree
13    {
14        private readonly KeySearcher keySearcher;
15        private readonly StatusContainer statusContainer;
16        private readonly StatisticsGenerator statisticsGenerator;
17        private readonly KeyPatternPool patternPool;
18        private readonly NodeBase rootNode;
19        private readonly StorageHelper storageHelper;
20        private readonly string identifier;
21        private readonly StatusUpdater statusUpdater;
22        private readonly int updateIntervalMod;
23
24        private NodeBase currentNode;
25        private bool skippedReservedNodes;
26
27        public KeyPoolTree(KeyPatternPool patternPool, KeySearcher keySearcher, KeyQualityHelper keyQualityHelper, StorageKeyGenerator identifierGenerator, StatusContainer statusContainer, StatisticsGenerator statisticsGenerator)
28        {
29            this.patternPool = patternPool;
30            this.keySearcher = keySearcher;
31            this.statusContainer = statusContainer;
32            this.statisticsGenerator = statisticsGenerator;
33            identifier = identifierGenerator.Generate();
34
35            storageHelper = new StorageHelper(keySearcher, statisticsGenerator, statusContainer);
36            statusUpdater = new StatusUpdater(statusContainer, identifierGenerator.GenerateStatusKey());
37            UpdateStatusForNewCalculation();
38            skippedReservedNodes = false;
39            updateIntervalMod = 5;
40
41            statisticsGenerator.MarkStartOfNodeSearch();
42            rootNode = NodeFactory.CreateNode(storageHelper, keyQualityHelper, null, 0, this.patternPool.Length - 1,
43                                              identifier);
44            statisticsGenerator.MarkEndOfNodeSearch();
45
46            currentNode = rootNode;
47        }
48
49        public DateTime StartDate()
50        {
51            return storageHelper.StartDate(identifier);
52        }
53
54        public Leaf FindNextLeaf()
55        {
56            statusContainer.IsSearchingForReservedNodes = false;
57            statisticsGenerator.MarkStartOfNodeSearch();
58
59            var nodeBeforeStarting = currentNode;
60            var foundNode = FindNextLeaf(false);
61
62            if (foundNode == null && skippedReservedNodes)
63            {
64                keySearcher.GuiLogMessage("Searching again with reserved nodes enabled...", NotificationLevel.Info);
65
66                currentNode = nodeBeforeStarting;
67                statusContainer.IsSearchingForReservedNodes = true;
68                foundNode = FindNextLeaf(true);
69                currentNode = foundNode;
70
71                statisticsGenerator.MarkEndOfNodeSearch();
72                return foundNode;
73            }
74
75            currentNode = foundNode;
76
77            statisticsGenerator.MarkEndOfNodeSearch();
78            return foundNode;
79        }
80
81        private Leaf FindNextLeaf(bool useReservedLeafs)
82        {
83            if (currentNode == null)
84            {
85                return null;
86            }
87
88            var isReserved = false;
89            storageHelper.UpdateFromDht(currentNode, true);
90            currentNode.UpdateCache();
91            while (currentNode.IsCalculated() || (!useReservedLeafs && (isReserved = currentNode.IsReserverd())))
92            {
93                if (isReserved)
94                    skippedReservedNodes = true;
95
96                // Current node is calculated or reserved,
97                // move one node up and update it
98                currentNode = currentNode.ParentNode;
99
100                // Root node calculated => everything finished
101                if (currentNode == null)
102                {
103                    currentNode = rootNode;
104                    return null;
105                }
106
107                // Update the new _currentNode
108                storageHelper.UpdateFromDht(currentNode, true);
109                currentNode.UpdateCache();
110            }
111
112            // currentNode is calculateable => find leaf
113            currentNode.UpdateCache();
114            return currentNode.CalculatableLeaf(useReservedLeafs);
115        }
116
117
118        internal bool IsCalculationFinished()
119        {
120            storageHelper.UpdateFromDht(rootNode, true);
121            return rootNode.IsCalculated();
122        }
123
124        internal void Reset()
125        {
126            rootNode.Reset();
127            currentNode = rootNode;
128            skippedReservedNodes = false;
129        }
130
131        public static void ProcessCurrentPatternCalculationResult(Leaf currentLeaf,
132                                                                  LinkedList<KeySearcher.ValueKey> result)
133        {
134            currentLeaf.HandleResults(result);
135        }
136
137        private void UpdateStatusForNewCalculation()
138        {
139            statusUpdater.SendUpdate(DistributedJobStatus.Status.New);
140        }
141
142        public void UpdateStatusForFinishedCalculation()
143        {
144            statusUpdater.SendUpdate(DistributedJobStatus.Status.Finished);
145        }
146
147        public void UpdateStatus(Leaf currentLeaf)
148        {
149            var isHigherPatternThanBefore = (currentLeaf.PatternId() + 1) >= statisticsGenerator.HighestChunkCalculated;
150            var isLastPattern = currentLeaf.PatternId() == statisticsGenerator.TotalAmountOfChunks - 1;
151            var patternIdQualifiesForUpdate = currentLeaf.PatternId() % updateIntervalMod == 0;
152
153            if ((!isHigherPatternThanBefore || !patternIdQualifiesForUpdate) && !isLastPattern) return;
154            statusUpdater.SendUpdate();
155            keySearcher.GuiLogMessage("Updating status in DHT", NotificationLevel.Info);
156        }
157    }
158}
Note: See TracBrowser for help on using the repository browser.