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

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

Defined new Storage Helper Standard...further changes will
follow soon. With this update all former Challenges won't
work anymore.

File size: 13.1 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.IO;
4using System.Threading;
5using Cryptool.P2P;
6using Cryptool.P2P.Internal;
7using Cryptool.PluginBase;
8using KeySearcher.P2P.Exceptions;
9using KeySearcher.P2P.Presentation;
10using KeySearcher.P2P.Tree;
11
12namespace KeySearcher.P2P.Storage
13{
14    class StorageHelper
15    {
16        private readonly KeySearcher keySearcher;
17        private readonly StatisticsGenerator statisticsGenerator;
18        private readonly StatusContainer statusContainer;
19
20        //VERSIONNUMBER: Important. Set it +1 manually everytime the length of the MemoryStream Changes
21        private const int version = 1;
22
23        public StorageHelper(KeySearcher keySearcher, StatisticsGenerator statisticsGenerator, StatusContainer statusContainer)
24        {
25            this.keySearcher = keySearcher;
26            this.statisticsGenerator = statisticsGenerator;
27            this.statusContainer = statusContainer;
28        }
29
30        //-------------------------------------------------------------------------------------------
31        //AFTER CHANGING THE FOLLOWING METHODS INCREASE THE VERSION-NUMBER AT THE TOP OF THIS CLASS!
32        //-------------------------------------------------------------------------------------------
33        internal RequestResult UpdateInDht(NodeBase nodeToUpdate)
34        {
35            var memoryStream = new MemoryStream();
36            var binaryWriter = new BinaryWriter(memoryStream);
37
38            //Append Updater Version
39            binaryWriter.Write('V');
40            binaryWriter.Write(version); 
41
42            if (nodeToUpdate is Node)
43            {
44                UpdateNodeInDht((Node) nodeToUpdate, binaryWriter);
45            } else
46            {
47                UpdateLeafInDht((Leaf) nodeToUpdate, binaryWriter);
48            }
49
50            // Append results
51            binaryWriter.Write(nodeToUpdate.Result.Count);
52            foreach (var valueKey in nodeToUpdate.Result)
53            {
54                binaryWriter.Write(valueKey.key);
55                binaryWriter.Write(valueKey.value);
56                binaryWriter.Write(valueKey.decryption.Length);
57                binaryWriter.Write(valueKey.decryption);
58
59                binaryWriter.Write(valueKey.user);
60                var buffertime = valueKey.time.ToBinary();
61                binaryWriter.Write(buffertime);
62                binaryWriter.Write(valueKey.maschid);
63                binaryWriter.Write(valueKey.maschname);
64            }                       
65             
66            //Creating a copy of the activity dictionary
67            var copyAct = nodeToUpdate.Activity;
68
69            //Write number of avatarnames
70            binaryWriter.Write(copyAct.Keys.Count);
71            foreach (string avatar in copyAct.Keys)
72            {
73                var maschCopy = copyAct[avatar];
74                //write avatarname
75                binaryWriter.Write(avatar);
76                //write the number of maschines for this avatar
77                binaryWriter.Write(maschCopy.Keys.Count);
78
79                foreach (long maschID in maschCopy.Keys)
80                {
81                    //write the maschines and their patterncount
82                    binaryWriter.Write(maschID);
83                    binaryWriter.Write(maschCopy[maschID].Count); //int 32
84                    binaryWriter.Write(maschCopy[maschID].Hostname); //String
85                    binaryWriter.Write(maschCopy[maschID].Date.ToBinary()); //DateTime
86                }
87            }
88            return StoreWithStatistic(KeyInDht(nodeToUpdate), memoryStream.ToArray());
89        }
90
91        private static void UpdateNodeInDht(Node nodeToUpdate, BinaryWriter binaryWriter)
92        {
93            binaryWriter.Write(nodeToUpdate.LeftChildFinished);
94            binaryWriter.Write(nodeToUpdate.RightChildFinished);
95        }
96
97        private static void UpdateLeafInDht(Leaf nodeToUpdate, BinaryWriter binaryWriter)
98        {
99            var buffer = nodeToUpdate.LastReservationDate.ToBinary();
100            binaryWriter.Write(buffer);
101            binaryWriter.Write(nodeToUpdate.getClientIdentifier());
102        }
103
104        internal RequestResult UpdateFromDht(NodeBase nodeToUpdate, bool forceUpdate = false)
105        {
106            try
107            {
108                if (!forceUpdate && nodeToUpdate.LastUpdate > DateTime.Now.Subtract(new TimeSpan(0, 0, 5)))
109                {
110                    return new RequestResult { Status = RequestResultType.Success };
111                }
112
113                nodeToUpdate.LastUpdate = DateTime.Now;
114
115                var requestResult = RetrieveWithStatistic(KeyInDht(nodeToUpdate));
116                var nodeBytes = requestResult.Data;
117
118                if (nodeBytes == null)
119                {
120                    return requestResult;
121                }
122
123                var binaryReader = new BinaryReader(new MemoryStream(nodeBytes));
124
125                //oldVersionFlag will be used to garantee further changes in the Stream
126                var oldVersionFlag = CheckNodeVersion(binaryReader);
127
128                if (nodeToUpdate is Node)
129                {
130                    UpdateNodeFromDht((Node)nodeToUpdate, binaryReader);
131                }
132                else
133                {
134                    UpdateLeafFromDht((Leaf)nodeToUpdate, binaryReader);
135                }
136
137                // Load results
138                var resultCount = binaryReader.ReadInt32();
139
140                for (var i = 0; i < resultCount; i++)
141                {
142                    var newResult = new KeySearcher.ValueKey
143                                            {
144                                                key = binaryReader.ReadString(),
145                                                value = binaryReader.ReadDouble(),
146                                                decryption = binaryReader.ReadBytes(binaryReader.ReadInt32()),
147                                                user = binaryReader.ReadString(),
148                                                time = DateTime.FromBinary(binaryReader.ReadInt64()),
149                                                maschid = binaryReader.ReadInt64(),
150                                                maschname = binaryReader.ReadString()
151                                            };
152                    nodeToUpdate.Result.AddLast(newResult);                   
153                }
154
155                //Reading the number of avatarnames
156                int avatarcount = binaryReader.ReadInt32();
157                for (int i = 0; i < avatarcount; i++)
158                {
159                    //Reading the avatarname and the maschine-count for this name
160                    string avatarname = binaryReader.ReadString();
161                    int maschcount = binaryReader.ReadInt32();
162                    var readMaschcount = new Dictionary<long, Information>();
163
164                    for (int j = 0; j < maschcount; j++)
165                    {
166                        //reading the IDs and patterncount
167                        long maschID = binaryReader.ReadInt64();
168                        int count = binaryReader.ReadInt32();
169                        string host = binaryReader.ReadString();
170                        var date = DateTime.FromBinary(binaryReader.ReadInt64());
171                        readMaschcount.Add(maschID, new Information() { Count = count, Hostname = host, Date = date });
172                    }
173
174                    if (nodeToUpdate.Activity.ContainsKey(avatarname))
175                    {
176                        nodeToUpdate.Activity[avatarname] = readMaschcount;
177                    }
178                    else
179                    {
180                        nodeToUpdate.Activity.Add(avatarname, readMaschcount);
181                    }
182                }
183               
184                if (resultCount > 0)
185                {
186                    keySearcher.IntegrateNewResults(nodeToUpdate.Result, nodeToUpdate.Activity,
187                                                    nodeToUpdate.DistributedJobIdentifier);
188                    statisticsGenerator.ProcessPatternResults(nodeToUpdate.Result);
189                }
190                nodeToUpdate.UpdateCache();
191                return requestResult;
192            }
193            catch (Exception e)
194            {
195                if (e is KeySearcherStopException)
196                    throw new KeySearcherStopException();
197                else if (e is NotConnectedException)
198                    throw new NotConnectedException();
199
200                keySearcher.GuiLogMessage(e.Message + ": Node causing the failure: " + nodeToUpdate.ToString(), NotificationLevel.Error);
201                nodeToUpdate.Reset();
202                throw new InvalidOperationException();
203            }
204        }
205
206        private static void UpdateNodeFromDht(Node nodeToUpdate, BinaryReader binaryReader)
207        {
208            nodeToUpdate.LeftChildFinished = binaryReader.ReadBoolean() || nodeToUpdate.LeftChildFinished;
209            nodeToUpdate.RightChildFinished = binaryReader.ReadBoolean() || nodeToUpdate.RightChildFinished;
210        }
211
212        private static void UpdateLeafFromDht(Leaf nodeToUpdate, BinaryReader binaryReader)
213        {
214            try
215            {   
216                var date = DateTime.FromBinary(binaryReader.ReadInt64());
217                if (date > nodeToUpdate.LastReservationDate)
218                {
219                    nodeToUpdate.LastReservationDate = date;
220                }
221                nodeToUpdate.setClientIdentifier(binaryReader.ReadInt64());
222            }
223            catch (Exception)
224            {
225                throw new Exception();
226            }           
227        }
228
229        internal static string KeyInDht(NodeBase node)
230        {
231            return string.Format("{0}_node_{1}_{2}", node.DistributedJobIdentifier, node.From, node.To);
232        }
233
234        private static int CheckNodeVersion(BinaryReader binaryReader)
235        {
236            try
237            {
238                //Reading the char and the versionnumber
239                char magic = binaryReader.ReadChar();
240                if (magic != 86) //V infront of a Node
241                {
242                    throw new Exception();
243                }
244                var versionInUse = binaryReader.ReadInt32();
245                if (versionInUse > version) //Check if a newer Version is in use
246                {
247                    throw new KeySearcherStopException();
248                }
249                return versionInUse;
250            }
251            catch (KeySearcherStopException)
252            {
253                throw new KeySearcherStopException();
254            }
255        }
256
257        public DateTime StartDate(String ofJobIdentifier)
258        {
259            var key = ofJobIdentifier + "_startdate";
260            var requestResult = RetrieveWithStatistic(key);
261
262            if (requestResult.IsSuccessful() && requestResult.Data != null)
263            {
264                var startTimeUtc = DateTime.SpecifyKind(
265                    DateTime.FromBinary(BitConverter.ToInt64(requestResult.Data, 0)), DateTimeKind.Utc);
266                return startTimeUtc.ToLocalTime();
267            }
268
269            StoreWithStatistic(key, BitConverter.GetBytes((DateTime.UtcNow.ToBinary())));
270            return DateTime.Now;
271        }
272
273        public long SubmitterID(String ofJobIdentifier)
274        {
275            var key = ofJobIdentifier + "_submitterid";
276            var requestResult = RetrieveWithStatistic(key);
277
278            if (requestResult.IsSuccessful() && requestResult.Data != null)
279            {
280                var submitterid = BitConverter.ToInt64(requestResult.Data, 0);
281                return submitterid;
282            }
283
284            StoreWithStatistic(key, BitConverter.GetBytes(Cryptool.PluginBase.Miscellaneous.UniqueIdentifier.GetID()));
285            return Cryptool.PluginBase.Miscellaneous.UniqueIdentifier.GetID();
286        }
287
288        public RequestResult RetrieveWithStatistic(string key)
289        {
290            statusContainer.RetrieveRequests++;
291            statusContainer.TotalDhtRequests++;
292            var requestResult = P2PManager.Retrieve(key);
293
294            if (requestResult.Data != null)
295            {
296                statusContainer.RetrievedBytes += requestResult.Data.Length;
297                statusContainer.TotalBytes += requestResult.Data.Length;
298            }
299
300            return requestResult;
301        }
302
303        public RequestResult RemoveWithStatistic(string key)
304        {
305            statusContainer.RemoveRequests++;
306            statusContainer.TotalDhtRequests++;
307            return P2PManager.Remove(key);
308        }
309
310        public RequestResult StoreWithStatistic(string key, byte[] data)
311        {
312            statusContainer.StoreRequests++;
313            statusContainer.TotalDhtRequests++;
314            var requestResult = P2PManager.Store(key, data);
315
316            if (requestResult.Data != null)
317            {
318                statusContainer.StoredBytes += requestResult.Data.Length;
319                statusContainer.TotalBytes += requestResult.Data.Length;
320            }
321
322            return requestResult;
323        }
324    }
325}
Note: See TracBrowser for help on using the repository browser.