source: trunk/CrypPlugins/KeySearcher/P2P/Storage/StorageHelper.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: 17.0 KB
RevLine 
[1634]1using System;
[2196]2using System.Collections.Generic;
[1634]3using System.IO;
4using Cryptool.P2P;
[1665]5using Cryptool.P2P.Internal;
[2142]6using Cryptool.PluginBase;
7using KeySearcher.P2P.Exceptions;
[1682]8using KeySearcher.P2P.Presentation;
[1674]9using KeySearcher.P2P.Tree;
[1634]10
[1674]11namespace KeySearcher.P2P.Storage
[1634]12{
[1674]13    class StorageHelper
[1634]14    {
[1674]15        private readonly KeySearcher keySearcher;
[1682]16        private readonly StatisticsGenerator statisticsGenerator;
17        private readonly StatusContainer statusContainer;
[1634]18
[2094]19        //VERSIONNUMBER: Important. Set it +1 manually everytime the length of the MemoryStream Changes
[2249]20        private const int version = 4;
[2240]21        /*
22        -----------------------------Versionnumber Changelog---------------------------------------------
[2249]23        |   Version 1: Added the Versionnumber to the Stream (Leafs)
[2240]24        |   Version 2: Added the first User Statistics (Avatar,ID,Count) to the Stream
25        |   Version 3: Added version question (in front of results) + more statistic information (hostname,date) to the Stream
[2249]26        |   Version 4: Reorganisation of the DHT structure. Update fully working now + features from previous versions available
[2359]27        |   Version 5: Extended the key information by the user who found it. (Username,Date,Maschid,Host)
[2240]28        -------------------------------------------------------------------------------------------------
29         */
[2094]30
[1682]31        public StorageHelper(KeySearcher keySearcher, StatisticsGenerator statisticsGenerator, StatusContainer statusContainer)
[1634]32        {
[1674]33            this.keySearcher = keySearcher;
[1682]34            this.statisticsGenerator = statisticsGenerator;
35            this.statusContainer = statusContainer;
[1634]36        }
37
[2240]38        //-------------------------------------------------------------------------------------------
39        //AFTER CHANGING THE FOLLOWING METHODS INCREASE THE VERSION-NUMBER AT THE TOP OF THIS CLASS!
40        //-------------------------------------------------------------------------------------------
[1682]41        internal RequestResult UpdateInDht(NodeBase nodeToUpdate)
[1634]42        {
43            var memoryStream = new MemoryStream();
44            var binaryWriter = new BinaryWriter(memoryStream);
45
[2359]46            //Append Updater Version
[2248]47            binaryWriter.Write('W');
[2240]48            binaryWriter.Write(version); 
49
[1634]50            if (nodeToUpdate is Node)
51            {
52                UpdateNodeInDht((Node) nodeToUpdate, binaryWriter);
53            } else
54            {
55                UpdateLeafInDht((Leaf) nodeToUpdate, binaryWriter);
56            }
57
58            // Append results
59            binaryWriter.Write(nodeToUpdate.Result.Count);
60            foreach (var valueKey in nodeToUpdate.Result)
61            {
62                binaryWriter.Write(valueKey.key);
63                binaryWriter.Write(valueKey.value);
64                binaryWriter.Write(valueKey.decryption.Length);
65                binaryWriter.Write(valueKey.decryption);
[2359]66
67/*                //--------------------------------------------------------
68                binaryWriter.Write(valueKey.user);
69                var buffertime = valueKey.time.ToBinary();
70                binaryWriter.Write(buffertime);
71                binaryWriter.Write(valueKey.maschid);
72                binaryWriter.Write(valueKey.maschname);
73*/                //---------------------------------------------------------
[2121]74            }                       
[2249]75             
[2196]76            //Creating a copy of the activity dictionary
[2233]77            var copyAct = nodeToUpdate.Activity;
[1634]78
[2196]79            //Write number of avatarnames
80            binaryWriter.Write(copyAct.Keys.Count);
81            foreach (string avatar in copyAct.Keys)
82            {
[2233]83                var maschCopy = copyAct[avatar];
[2196]84                //write avatarname
85                binaryWriter.Write(avatar);
86                //write the number of maschines for this avatar
[2199]87                binaryWriter.Write(maschCopy.Keys.Count);
[2196]88
[2199]89                foreach (long maschID in maschCopy.Keys)
[2196]90                {
91                    //write the maschines and their patterncount
92                    binaryWriter.Write(maschID);
[2233]93                    binaryWriter.Write(maschCopy[maschID].Count); //int 32
94                    binaryWriter.Write(maschCopy[maschID].Hostname); //String
95                    binaryWriter.Write(maschCopy[maschID].Date.ToBinary()); //DateTime
[2196]96                }
97            }
[1682]98            return StoreWithStatistic(KeyInDht(nodeToUpdate), memoryStream.ToArray());
[1634]99        }
100
101        private static void UpdateNodeInDht(Node nodeToUpdate, BinaryWriter binaryWriter)
102        {
103            binaryWriter.Write(nodeToUpdate.LeftChildFinished);
104            binaryWriter.Write(nodeToUpdate.RightChildFinished);
105        }
106
107        private static void UpdateLeafInDht(Leaf nodeToUpdate, BinaryWriter binaryWriter)
108        {
[2155]109            binaryWriter.Write('V');
110            binaryWriter.Write(version);
[1634]111            var buffer = nodeToUpdate.LastReservationDate.ToBinary();
112            binaryWriter.Write(buffer);
[2019]113            binaryWriter.Write(nodeToUpdate.getClientIdentifier());
[1634]114        }
115
[1665]116        internal RequestResult UpdateFromDht(NodeBase nodeToUpdate, bool forceUpdate = false)
[1634]117        {
[2391]118                if (!forceUpdate && nodeToUpdate.LastUpdate > DateTime.Now.Subtract(new TimeSpan(0, 0, 5)))
119                {
120                    return new RequestResult {Status = RequestResultType.Success};
121                }
[2240]122
[2391]123                nodeToUpdate.LastUpdate = DateTime.Now;
[1634]124
[2391]125                var requestResult = RetrieveWithStatistic(KeyInDht(nodeToUpdate));
126                var nodeBytes = requestResult.Data;
[1651]127
[2391]128                if (nodeBytes == null)
129                {
130                    return requestResult;
131                }
[1634]132
[2391]133                var binaryReader = new BinaryReader(new MemoryStream(nodeBytes));
[1634]134
[2391]135                //oldVersionFlag will be used to garantee further changes in the Stream
136                var oldVersionFlag = CheckNodeVersion(binaryReader);
[2249]137
[2391]138                if (nodeToUpdate is Node)
[2359]139                {
[2391]140                    UpdateNodeFromDht((Node) nodeToUpdate, binaryReader);
[2359]141                }
142                else
143                {
[2391]144                    UpdateLeafFromDht((Leaf) nodeToUpdate, binaryReader);
[2359]145                }
[2391]146
147                // Load results
148                var resultCount = binaryReader.ReadInt32();
149       
150                for (var i = 0; i < resultCount; i++)
[2199]151                {
[2391]152                    try
[2249]153                    {
[2391]154                        if (oldVersionFlag < 5)
155                        {
156                            var newResult = new KeySearcher.ValueKey
157                                                {
158                                                    key = binaryReader.ReadString(),
159                                                    value = binaryReader.ReadDouble(),
160                                                    decryption = binaryReader.ReadBytes(binaryReader.ReadInt32())
161                                                };
162                            /*
163                                                                        user = "Unknown",
164                                                                        time = DateTime.MinValue,
165                                                                        maschid = 666,
166                                                                        maschname = "Devil"
167
168                            */
169                            nodeToUpdate.Result.AddLast(newResult);
170                        }
171                        else
172                        {
173                            var newResult = new KeySearcher.ValueKey
174                                                {
175                                                    key = binaryReader.ReadString(),
176                                                    value = binaryReader.ReadDouble(),
177                                                    decryption = binaryReader.ReadBytes(binaryReader.ReadInt32())
178                                                };
179                            /*
180                                                    user = binaryReader.ReadString(),
181                                                    time = DateTime.FromBinary(binaryReader.ReadInt64()),
182                                                    maschid = binaryReader.ReadInt64(),
183                                                    maschname = binaryReader.ReadString()
184                            */
185                            nodeToUpdate.Result.AddLast(newResult);
186                        }
[2233]187                    }
[2391]188                    catch(Exception e)
[2217]189                    {
[2391]190                        keySearcher.GuiLogMessage(e.Message + ": Node causing the failure: " + nodeToUpdate.ToString(),NotificationLevel.Error);
191                        if (nodeToUpdate is Leaf)
192                        {
193                            nodeToUpdate.Result.Clear();
194                        }
195                    }                                       
196                }
197
198                if (binaryReader.BaseStream.Length != binaryReader.BaseStream.Position)
199                {
200                    //Reading the number of avatarnames
201                    int avatarcount = binaryReader.ReadInt32();
202                    for (int i = 0; i < avatarcount; i++)
[2217]203                    {
[2391]204                        //Reading the avatarname and the maschine-count for this name
205                        string avatarname = binaryReader.ReadString();
206                        int maschcount = binaryReader.ReadInt32();
207                        var readMaschcount = new Dictionary<long, Information>();
208
209                        for (int j = 0; j < maschcount; j++)
210                        {
211                            //reading the IDs and patterncount
212                            long maschID = binaryReader.ReadInt64();
213                            int count = binaryReader.ReadInt32();
214                            string host = binaryReader.ReadString();
215                            var date = DateTime.FromBinary(binaryReader.ReadInt64());
216                            readMaschcount.Add(maschID, new Information() {Count = count, Hostname = host, Date = date});
217
218                        }
219
220                        if (nodeToUpdate.Activity.ContainsKey(avatarname))
221                        {
222                            nodeToUpdate.Activity[avatarname] = readMaschcount;
223                        }
224                        else
225                        {
226                            nodeToUpdate.Activity.Add(avatarname, readMaschcount);
227                        }
[2217]228                    }
[2391]229                }
[1665]230
[2391]231                if (resultCount > 0)
232                {
233                    keySearcher.IntegrateNewResults(nodeToUpdate.Result, nodeToUpdate.Activity,
234                                                    nodeToUpdate.DistributedJobIdentifier);
235                    statisticsGenerator.ProcessPatternResults(nodeToUpdate.Result);
236                }
237
238                nodeToUpdate.UpdateCache();
239                return requestResult;
240           
241
[1634]242        }
243
244        private static void UpdateNodeFromDht(Node nodeToUpdate, BinaryReader binaryReader)
245        {
[1647]246            nodeToUpdate.LeftChildFinished = binaryReader.ReadBoolean() || nodeToUpdate.LeftChildFinished;
247            nodeToUpdate.RightChildFinished = binaryReader.ReadBoolean() || nodeToUpdate.RightChildFinished;
[1634]248        }
249
250        private static void UpdateLeafFromDht(Leaf nodeToUpdate, BinaryReader binaryReader)
251        {
[2240]252            var oldVersionFlag = CheckVersion(binaryReader);
[2155]253               
[1647]254            var date = DateTime.FromBinary(binaryReader.ReadInt64());
255            if (date > nodeToUpdate.LastReservationDate)
256            {
257                nodeToUpdate.LastReservationDate = date;
258            }
[2019]259           
[2017]260            try
261            {
[2019]262                if (binaryReader.BaseStream.Length - binaryReader.BaseStream.Position >= 8)
263                {
264                    nodeToUpdate.setClientIdentifier(binaryReader.ReadInt64());
265                }
266                else
267                {
268                    throw new Exception();
269                }
270            }
271            catch (Exception)
[2017]272            {
273                // client id not available, use default
[2019]274                nodeToUpdate.setClientIdentifier(-1);
[2017]275            }
[2019]276           
[1634]277        }
278
279        internal static string KeyInDht(NodeBase node)
280        {
[1674]281            return string.Format("{0}_node_{1}_{2}", node.DistributedJobIdentifier, node.From, node.To);
[1634]282        }
[1682]283
[2240]284        private static int CheckVersion(BinaryReader binaryReader)
[2142]285        {           
[2121]286            try
287            {
[2142]288                //Checking if there's a version in the stream
289                int vers = binaryReader.PeekChar();
[2249]290                if (vers == 86) //V infront of a Leaf
[2121]291                {
292                    //Reading the char and the versionnumber
[2142]293                    char magic = binaryReader.ReadChar();
[2121]294                    int versionInUse = binaryReader.ReadInt32();
295                    //Check if a newer Version is in use
296                    if (versionInUse > version)
297                    {
298                        throw new KeySearcherStopException();
299                    }
[2240]300                    return versionInUse;
[2121]301                }
[2240]302                else
303                {
[2249]304                    return 0;
[2240]305                }
[2121]306            }
[2142]307            catch(KeySearcherStopException)
[2121]308            {
309                throw new KeySearcherStopException();
[2249]310            }           
311        }
312
313        private static int CheckNodeVersion(BinaryReader binaryReader)
314        {
315            try
316            {
317                //Checking if there's a version in the stream
318                int vers = binaryReader.PeekChar();
319                if (vers == 87) //W infront of a Node
320                {
321                    //Reading the char and the versionnumber
322                    char magic = binaryReader.ReadChar();
323                    int versionInUse = binaryReader.ReadInt32();
324                    //Check if a newer Version is in use
325                    if (versionInUse > version)
326                    {
327                        throw new KeySearcherStopException();
328                    }
329                    return versionInUse;
330                }
331                else
332                {
333                    return 0;
334                }
[2121]335            }
[2249]336            catch (KeySearcherStopException)
337            {
338                throw new KeySearcherStopException();
339            }
[2121]340        }
341
[1705]342        public DateTime StartDate(String ofJobIdentifier)
343        {
344            var key = ofJobIdentifier + "_startdate";
345            var requestResult = RetrieveWithStatistic(key);
346
347            if (requestResult.IsSuccessful() && requestResult.Data != null)
348            {
349                var startTimeUtc = DateTime.SpecifyKind(
350                    DateTime.FromBinary(BitConverter.ToInt64(requestResult.Data, 0)), DateTimeKind.Utc);
351                return startTimeUtc.ToLocalTime();
352            }
353
354            StoreWithStatistic(key, BitConverter.GetBytes((DateTime.UtcNow.ToBinary())));
355            return DateTime.Now;
356        }
357
[2074]358        public long SubmitterID(String ofJobIdentifier)
359        {
360            var key = ofJobIdentifier + "_submitterid";
361            var requestResult = RetrieveWithStatistic(key);
362
363            if (requestResult.IsSuccessful() && requestResult.Data != null)
364            {
365                var submitterid = BitConverter.ToInt64(requestResult.Data, 0);
366                return submitterid;
367            }
368
369            StoreWithStatistic(key, BitConverter.GetBytes(Cryptool.PluginBase.Miscellaneous.UniqueIdentifier.GetID()));
370            return Cryptool.PluginBase.Miscellaneous.UniqueIdentifier.GetID();
371        }
372
[1682]373        public RequestResult RetrieveWithStatistic(string key)
374        {
375            statusContainer.RetrieveRequests++;
376            statusContainer.TotalDhtRequests++;
[1703]377            var requestResult = P2PManager.Retrieve(key);
378
379            if (requestResult.Data != null)
380            {
381                statusContainer.RetrievedBytes += requestResult.Data.Length;
[1705]382                statusContainer.TotalBytes += requestResult.Data.Length;
[1703]383            }
384
385            return requestResult;
[1682]386        }
387
388        public RequestResult RemoveWithStatistic(string key)
389        {
390            statusContainer.RemoveRequests++;
391            statusContainer.TotalDhtRequests++;
392            return P2PManager.Remove(key);
393        }
394
395        public RequestResult StoreWithStatistic(string key, byte[] data)
396        {
397            statusContainer.StoreRequests++;
398            statusContainer.TotalDhtRequests++;
[1703]399            var requestResult = P2PManager.Store(key, data);
400
401            if (requestResult.Data != null)
402            {
403                statusContainer.StoredBytes += requestResult.Data.Length;
[1705]404                statusContainer.TotalBytes += requestResult.Data.Length;
[1703]405            }
406
407            return requestResult;
[1682]408        }
[1634]409    }
410}
Note: See TracBrowser for help on using the repository browser.