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

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

o KeySearcher: fixed bugs in global statistic

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