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

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

Serialising the Dictionary with the Binary Writer (writing)

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