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

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

Set mark for the dictionary update

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