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

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

Added extension for the key values.
(Commited as comments. Needs to be tested before release)
Still using Version 4 -> No DHT changes yet.

File size: 16.1 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        {
[2240]118
[1665]119            if (!forceUpdate && nodeToUpdate.LastUpdate > DateTime.Now.Subtract(new TimeSpan(0, 0, 5)))
[1634]120            {
[1665]121                return new RequestResult { Status = RequestResultType.Success };
[1634]122            }
123
[1651]124            nodeToUpdate.LastUpdate = DateTime.Now;
125
[1682]126            var requestResult = RetrieveWithStatistic(KeyInDht(nodeToUpdate));
[1665]127            var nodeBytes = requestResult.Data;
[1634]128
129            if (nodeBytes == null)
130            {
[1665]131                return requestResult;
[1634]132            }
133
134            var binaryReader = new BinaryReader(new MemoryStream(nodeBytes));
[2249]135
136            //oldVersionFlag will be used to garantee further changes in the Stream
137            var oldVersionFlag = CheckNodeVersion(binaryReader);
138
[1634]139            if (nodeToUpdate is Node)
140            {
141                UpdateNodeFromDht((Node) nodeToUpdate, binaryReader);
142            } else
143            {
[2152]144                UpdateLeafFromDht((Leaf)nodeToUpdate, binaryReader);
[1634]145            }
146
147            // Load results
148            var resultCount = binaryReader.ReadInt32();
149            for (var i = 0; i < resultCount; i++)
150            {
[2359]151                if (oldVersionFlag < 5)
152                {
153                    var newResult = new KeySearcher.ValueKey
154                                        {
155                                            key = binaryReader.ReadString(),
156                                            value = binaryReader.ReadDouble(),
157                                            decryption = binaryReader.ReadBytes(binaryReader.ReadInt32())
158                                        };
159                    /*
160                                                                user = "Unknown",
161                                                                time = DateTime.MinValue,
162                                                                maschid = 666,
163                                                                maschname = "Devil"
164
165                    */
166                    nodeToUpdate.Result.AddLast(newResult);
167                }
168                else
169                {
170                    var newResult = new KeySearcher.ValueKey
171                                        {
172                                            key = binaryReader.ReadString(),
173                                            value = binaryReader.ReadDouble(),
174                                            decryption = binaryReader.ReadBytes(binaryReader.ReadInt32())
175                                        };
176                    /*
177                                            user = binaryReader.ReadString(),
178                                            time = DateTime.FromBinary(binaryReader.ReadInt64()),
179                                            maschid = binaryReader.ReadInt64(),
180                                            maschname = binaryReader.ReadString()
181                    */
182                    nodeToUpdate.Result.AddLast(newResult);
183                }
[1634]184            }
[2121]185           
[2217]186            if (binaryReader.BaseStream.Length != binaryReader.BaseStream.Position)
[2199]187            { 
188                //Reading the number of avatarnames
189                int avatarcount = binaryReader.ReadInt32();
190                for(int i=0; i<avatarcount;i++)
191                {
192                    //Reading the avatarname and the maschine-count for this name
193                    string avatarname = binaryReader.ReadString();
194                    int maschcount = binaryReader.ReadInt32();
[2233]195                    var readMaschcount = new Dictionary<long, Information>();
196                   
[2249]197                    for (int j = 0; j < maschcount; j++)
198                    {
199                        //reading the IDs and patterncount
200                        long maschID = binaryReader.ReadInt64();
201                        int count = binaryReader.ReadInt32();
202                        string host = binaryReader.ReadString(); 
203                        var date = DateTime.FromBinary(binaryReader.ReadInt64());
204                        readMaschcount.Add(maschID, new Information() {Count = count, Hostname = host, Date = date});
205                       
[2233]206                    }
[2249]207                   
[2217]208                    if (nodeToUpdate.Activity.ContainsKey(avatarname))
209                    {
210                        nodeToUpdate.Activity[avatarname] = readMaschcount;
211                    }
212                    else
213                    {
214                        nodeToUpdate.Activity.Add(avatarname, readMaschcount);                     
215                    }
[2199]216                }               
[2094]217            }
[2217]218                       
[1634]219            if (resultCount > 0)
220            {
[2233]221                keySearcher.IntegrateNewResults(nodeToUpdate.Result, nodeToUpdate.Activity, nodeToUpdate.DistributedJobIdentifier);
[1682]222                statisticsGenerator.ProcessPatternResults(nodeToUpdate.Result);
[1634]223            }
[1665]224
[1693]225            nodeToUpdate.UpdateCache();
[1665]226            return requestResult;
[1634]227        }
228
229        private static void UpdateNodeFromDht(Node nodeToUpdate, BinaryReader binaryReader)
230        {
[1647]231            nodeToUpdate.LeftChildFinished = binaryReader.ReadBoolean() || nodeToUpdate.LeftChildFinished;
232            nodeToUpdate.RightChildFinished = binaryReader.ReadBoolean() || nodeToUpdate.RightChildFinished;
[1634]233        }
234
235        private static void UpdateLeafFromDht(Leaf nodeToUpdate, BinaryReader binaryReader)
236        {
[2240]237            var oldVersionFlag = CheckVersion(binaryReader);
[2155]238               
[1647]239            var date = DateTime.FromBinary(binaryReader.ReadInt64());
240            if (date > nodeToUpdate.LastReservationDate)
241            {
242                nodeToUpdate.LastReservationDate = date;
243            }
[2019]244           
[2017]245            try
246            {
[2019]247                if (binaryReader.BaseStream.Length - binaryReader.BaseStream.Position >= 8)
248                {
249                    nodeToUpdate.setClientIdentifier(binaryReader.ReadInt64());
250                }
251                else
252                {
253                    throw new Exception();
254                }
255            }
256            catch (Exception)
[2017]257            {
258                // client id not available, use default
[2019]259                nodeToUpdate.setClientIdentifier(-1);
[2017]260            }
[2019]261           
[1634]262        }
263
264        internal static string KeyInDht(NodeBase node)
265        {
[1674]266            return string.Format("{0}_node_{1}_{2}", node.DistributedJobIdentifier, node.From, node.To);
[1634]267        }
[1682]268
[2240]269        private static int CheckVersion(BinaryReader binaryReader)
[2142]270        {           
[2121]271            try
272            {
[2142]273                //Checking if there's a version in the stream
274                int vers = binaryReader.PeekChar();
[2249]275                if (vers == 86) //V infront of a Leaf
[2121]276                {
277                    //Reading the char and the versionnumber
[2142]278                    char magic = binaryReader.ReadChar();
[2121]279                    int versionInUse = binaryReader.ReadInt32();
280                    //Check if a newer Version is in use
281                    if (versionInUse > version)
282                    {
283                        throw new KeySearcherStopException();
284                    }
[2240]285                    return versionInUse;
[2121]286                }
[2240]287                else
288                {
[2249]289                    return 0;
[2240]290                }
[2121]291            }
[2142]292            catch(KeySearcherStopException)
[2121]293            {
294                throw new KeySearcherStopException();
[2249]295            }           
296        }
297
298        private static int CheckNodeVersion(BinaryReader binaryReader)
299        {
300            try
301            {
302                //Checking if there's a version in the stream
303                int vers = binaryReader.PeekChar();
304                if (vers == 87) //W infront of a Node
305                {
306                    //Reading the char and the versionnumber
307                    char magic = binaryReader.ReadChar();
308                    int versionInUse = binaryReader.ReadInt32();
309                    //Check if a newer Version is in use
310                    if (versionInUse > version)
311                    {
312                        throw new KeySearcherStopException();
313                    }
314                    return versionInUse;
315                }
316                else
317                {
318                    return 0;
319                }
[2121]320            }
[2249]321            catch (KeySearcherStopException)
322            {
323                throw new KeySearcherStopException();
324            }
[2121]325        }
326
[1705]327        public DateTime StartDate(String ofJobIdentifier)
328        {
329            var key = ofJobIdentifier + "_startdate";
330            var requestResult = RetrieveWithStatistic(key);
331
332            if (requestResult.IsSuccessful() && requestResult.Data != null)
333            {
334                var startTimeUtc = DateTime.SpecifyKind(
335                    DateTime.FromBinary(BitConverter.ToInt64(requestResult.Data, 0)), DateTimeKind.Utc);
336                return startTimeUtc.ToLocalTime();
337            }
338
339            StoreWithStatistic(key, BitConverter.GetBytes((DateTime.UtcNow.ToBinary())));
340            return DateTime.Now;
341        }
342
[2074]343        public long SubmitterID(String ofJobIdentifier)
344        {
345            var key = ofJobIdentifier + "_submitterid";
346            var requestResult = RetrieveWithStatistic(key);
347
348            if (requestResult.IsSuccessful() && requestResult.Data != null)
349            {
350                var submitterid = BitConverter.ToInt64(requestResult.Data, 0);
351                return submitterid;
352            }
353
354            StoreWithStatistic(key, BitConverter.GetBytes(Cryptool.PluginBase.Miscellaneous.UniqueIdentifier.GetID()));
355            return Cryptool.PluginBase.Miscellaneous.UniqueIdentifier.GetID();
356        }
357
[1682]358        public RequestResult RetrieveWithStatistic(string key)
359        {
360            statusContainer.RetrieveRequests++;
361            statusContainer.TotalDhtRequests++;
[1703]362            var requestResult = P2PManager.Retrieve(key);
363
364            if (requestResult.Data != null)
365            {
366                statusContainer.RetrievedBytes += requestResult.Data.Length;
[1705]367                statusContainer.TotalBytes += requestResult.Data.Length;
[1703]368            }
369
370            return requestResult;
[1682]371        }
372
373        public RequestResult RemoveWithStatistic(string key)
374        {
375            statusContainer.RemoveRequests++;
376            statusContainer.TotalDhtRequests++;
377            return P2PManager.Remove(key);
378        }
379
380        public RequestResult StoreWithStatistic(string key, byte[] data)
381        {
382            statusContainer.StoreRequests++;
383            statusContainer.TotalDhtRequests++;
[1703]384            var requestResult = P2PManager.Store(key, data);
385
386            if (requestResult.Data != null)
387            {
388                statusContainer.StoredBytes += requestResult.Data.Length;
[1705]389                statusContainer.TotalBytes += requestResult.Data.Length;
[1703]390            }
391
392            return requestResult;
[1682]393        }
[1634]394    }
395}
Note: See TracBrowser for help on using the repository browser.