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

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

Statistic update. The CSV additionally shows the name of the host and the last time this computer gained a pattern point (PP)

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