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

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

User Statistics Added. The CSV Data will be saved under C\Users\ct2\Local\CrypTool2...

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