source: trunk/CrypPlugins/KeySearcher/P2P/Storage/StorageHelper.cs @ 2074

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

Added the Branch Changes to the Trunk...Each Job will see a unique machine ID as the momentary "Jobsubmitter". This will be changed to the Avatar Name of the Job Submitter later on. These changes are tested.

File size: 8.4 KB
Line 
1using System;
2using System.IO;
3using Cryptool.P2P;
4using Cryptool.P2P.Internal;
5using KeySearcher.P2P.Presentation;
6using KeySearcher.P2P.Tree;
7
8namespace KeySearcher.P2P.Storage
9{
10    class StorageHelper
11    {
12        private readonly KeySearcher keySearcher;
13        private readonly StatisticsGenerator statisticsGenerator;
14        private readonly StatusContainer statusContainer;
15
16        public StorageHelper(KeySearcher keySearcher, StatisticsGenerator statisticsGenerator, StatusContainer statusContainer)
17        {
18            this.keySearcher = keySearcher;
19            this.statisticsGenerator = statisticsGenerator;
20            this.statusContainer = statusContainer;
21        }
22
23        internal RequestResult UpdateInDht(NodeBase nodeToUpdate)
24        {
25            var memoryStream = new MemoryStream();
26            var binaryWriter = new BinaryWriter(memoryStream);
27
28            if (nodeToUpdate is Node)
29            {
30                UpdateNodeInDht((Node) nodeToUpdate, binaryWriter);
31            } else
32            {
33                UpdateLeafInDht((Leaf) nodeToUpdate, binaryWriter);
34            }
35
36            // Append results
37            binaryWriter.Write(nodeToUpdate.Result.Count);
38            foreach (var valueKey in nodeToUpdate.Result)
39            {
40                binaryWriter.Write(valueKey.key);
41                binaryWriter.Write(valueKey.value);
42                binaryWriter.Write(valueKey.decryption.Length);
43                binaryWriter.Write(valueKey.decryption);
44            }
45
46            return StoreWithStatistic(KeyInDht(nodeToUpdate), memoryStream.ToArray());
47        }
48
49        private static void UpdateNodeInDht(Node nodeToUpdate, BinaryWriter binaryWriter)
50        {
51            binaryWriter.Write(nodeToUpdate.LeftChildFinished);
52            binaryWriter.Write(nodeToUpdate.RightChildFinished);
53        }
54
55        private static void UpdateLeafInDht(Leaf nodeToUpdate, BinaryWriter binaryWriter)
56        {
57            var buffer = nodeToUpdate.LastReservationDate.ToBinary();
58            binaryWriter.Write(buffer);
59           
60            //--------------------------------------------------------------------------------
61            binaryWriter.Write(nodeToUpdate.getClientIdentifier());
62            //--------------------------------------------------------------------------------
63        }
64
65        internal RequestResult UpdateFromDht(NodeBase nodeToUpdate, bool forceUpdate = false)
66        {
67            if (!forceUpdate && nodeToUpdate.LastUpdate > DateTime.Now.Subtract(new TimeSpan(0, 0, 5)))
68            {
69                return new RequestResult { Status = RequestResultType.Success };
70            }
71
72            nodeToUpdate.LastUpdate = DateTime.Now;
73
74            var requestResult = RetrieveWithStatistic(KeyInDht(nodeToUpdate));
75            var nodeBytes = requestResult.Data;
76
77            if (nodeBytes == null)
78            {
79                return requestResult;
80            }
81
82            var binaryReader = new BinaryReader(new MemoryStream(nodeBytes));
83
84            if (nodeToUpdate is Node)
85            {
86                UpdateNodeFromDht((Node) nodeToUpdate, binaryReader);
87            } else
88            {
89                UpdateLeafFromDht((Leaf) nodeToUpdate, binaryReader);
90            }
91
92            // Load results
93            var resultCount = binaryReader.ReadInt32();
94            for (var i = 0; i < resultCount; i++)
95            {
96                var newResult = new KeySearcher.ValueKey
97                                    {
98                                        key = binaryReader.ReadString(),
99                                        value = binaryReader.ReadDouble(),
100                                        decryption = binaryReader.ReadBytes(binaryReader.ReadInt32())
101                                    };
102                nodeToUpdate.Result.AddLast(newResult);
103            }
104
105            if (resultCount > 0)
106            {
107                keySearcher.IntegrateNewResults(nodeToUpdate.Result);
108                statisticsGenerator.ProcessPatternResults(nodeToUpdate.Result);
109            }
110
111            nodeToUpdate.UpdateCache();
112            return requestResult;
113        }
114
115        private static void UpdateNodeFromDht(Node nodeToUpdate, BinaryReader binaryReader)
116        {
117            nodeToUpdate.LeftChildFinished = binaryReader.ReadBoolean() || nodeToUpdate.LeftChildFinished;
118            nodeToUpdate.RightChildFinished = binaryReader.ReadBoolean() || nodeToUpdate.RightChildFinished;
119        }
120
121        private static void UpdateLeafFromDht(Leaf nodeToUpdate, BinaryReader binaryReader)
122        {
123            var date = DateTime.FromBinary(binaryReader.ReadInt64());
124            if (date > nodeToUpdate.LastReservationDate)
125            {
126                nodeToUpdate.LastReservationDate = date;
127            }
128           
129            //----------------------------------------------------------------
130            try
131            {
132                if (binaryReader.BaseStream.Length - binaryReader.BaseStream.Position >= 8)
133                {
134                    nodeToUpdate.setClientIdentifier(binaryReader.ReadInt64());
135                }
136                else
137                {
138                    throw new Exception();
139                }
140            }
141            catch (Exception)
142            {
143                // client id not available, use default
144                nodeToUpdate.setClientIdentifier(-1);
145            }
146            //----------------------------------------------------------------
147           
148        }
149
150        internal static string KeyInDht(NodeBase node)
151        {
152            return string.Format("{0}_node_{1}_{2}", node.DistributedJobIdentifier, node.From, node.To);
153        }
154
155        public DateTime StartDate(String ofJobIdentifier)
156        {
157            var key = ofJobIdentifier + "_startdate";
158            var requestResult = RetrieveWithStatistic(key);
159
160            if (requestResult.IsSuccessful() && requestResult.Data != null)
161            {
162                var startTimeUtc = DateTime.SpecifyKind(
163                    DateTime.FromBinary(BitConverter.ToInt64(requestResult.Data, 0)), DateTimeKind.Utc);
164                return startTimeUtc.ToLocalTime();
165            }
166
167            StoreWithStatistic(key, BitConverter.GetBytes((DateTime.UtcNow.ToBinary())));
168            return DateTime.Now;
169        }
170
171        //------------------------------------------------------------------------
172        public long SubmitterID(String ofJobIdentifier)
173        {
174            var key = ofJobIdentifier + "_submitterid";
175            var requestResult = RetrieveWithStatistic(key);
176
177            if (requestResult.IsSuccessful() && requestResult.Data != null)
178            {
179                var submitterid = BitConverter.ToInt64(requestResult.Data, 0);
180                return submitterid;
181            }
182
183            StoreWithStatistic(key, BitConverter.GetBytes(Cryptool.PluginBase.Miscellaneous.UniqueIdentifier.GetID()));
184            return Cryptool.PluginBase.Miscellaneous.UniqueIdentifier.GetID();
185        }
186        //---------------------------------------------------------------------------
187
188        public RequestResult RetrieveWithStatistic(string key)
189        {
190            statusContainer.RetrieveRequests++;
191            statusContainer.TotalDhtRequests++;
192            var requestResult = P2PManager.Retrieve(key);
193
194            if (requestResult.Data != null)
195            {
196                statusContainer.RetrievedBytes += requestResult.Data.Length;
197                statusContainer.TotalBytes += requestResult.Data.Length;
198            }
199
200            return requestResult;
201        }
202
203        public RequestResult RemoveWithStatistic(string key)
204        {
205            statusContainer.RemoveRequests++;
206            statusContainer.TotalDhtRequests++;
207            return P2PManager.Remove(key);
208        }
209
210        public RequestResult StoreWithStatistic(string key, byte[] data)
211        {
212            statusContainer.StoreRequests++;
213            statusContainer.TotalDhtRequests++;
214            var requestResult = P2PManager.Store(key, data);
215
216            if (requestResult.Data != null)
217            {
218                statusContainer.StoredBytes += requestResult.Data.Length;
219                statusContainer.TotalBytes += requestResult.Data.Length;
220            }
221
222            return requestResult;
223        }
224    }
225}
Note: See TracBrowser for help on using the repository browser.