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

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

Versionnumbers final version.
Use of the versionnumber starts this evening (7-8 PM).

File size: 10.4 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                UpdateLeafFromDht((Leaf)nodeToUpdate, binaryReader);
102            }
103
104            // Load results
105            var resultCount = binaryReader.ReadInt32();
106            for (var i = 0; i < resultCount; i++)
107            {
108                var newResult = new KeySearcher.ValueKey
109                                    {
110                                        key = binaryReader.ReadString(),
111                                        value = binaryReader.ReadDouble(),
112                                        decryption = binaryReader.ReadBytes(binaryReader.ReadInt32())
113                                    };
114                nodeToUpdate.Result.AddLast(newResult);
115            }
116           
117            //-------------------------------------------------------------------------------------------
118            //AFTER CHANGING THE FOLLOWING PART INCREASE THE VERSION-NUMBER AT THE TOP OF THIS CLASS!
119            //-------------------------------------------------------------------------------------------
120            /*
121            if (binaryReader.BaseStream.Length != binaryReader.BaseStream.Position)
122            {
123                //TODO: Dictionary read
124            }
125            */
126
127            if (resultCount > 0)
128            {
129                keySearcher.IntegrateNewResults(nodeToUpdate.Result);
130                statisticsGenerator.ProcessPatternResults(nodeToUpdate.Result);
131            }
132
133            nodeToUpdate.UpdateCache();
134            return requestResult;
135        }
136
137        private static void UpdateNodeFromDht(Node nodeToUpdate, BinaryReader binaryReader)
138        {
139            nodeToUpdate.LeftChildFinished = binaryReader.ReadBoolean() || nodeToUpdate.LeftChildFinished;
140            nodeToUpdate.RightChildFinished = binaryReader.ReadBoolean() || nodeToUpdate.RightChildFinished;
141        }
142
143        private static void UpdateLeafFromDht(Leaf nodeToUpdate, BinaryReader binaryReader)
144        {
145            //---------------------------------------------------------------------------------
146            //TODO: Versionnumber read
147            //CheckVersion(binaryReader);
148            //----------------------------------------------------------------------------------           
149               
150            var date = DateTime.FromBinary(binaryReader.ReadInt64());
151            if (date > nodeToUpdate.LastReservationDate)
152            {
153                nodeToUpdate.LastReservationDate = date;
154            }
155           
156            try
157            {
158                if (binaryReader.BaseStream.Length - binaryReader.BaseStream.Position >= 8)
159                {
160                    nodeToUpdate.setClientIdentifier(binaryReader.ReadInt64());
161                }
162                else
163                {
164                    throw new Exception();
165                }
166            }
167            catch (Exception)
168            {
169                // client id not available, use default
170                nodeToUpdate.setClientIdentifier(-1);
171            }
172           
173        }
174
175        internal static string KeyInDht(NodeBase node)
176        {
177            return string.Format("{0}_node_{1}_{2}", node.DistributedJobIdentifier, node.From, node.To);
178        }
179
180        //----------------------------------------------------------------------------
181        private static void CheckVersion(BinaryReader binaryReader)
182        {           
183            try
184            {
185                //Checking if there's a version in the stream
186                int vers = binaryReader.PeekChar();
187                if (vers == 86)
188                {
189                    //Reading the char and the versionnumber
190                    char magic = binaryReader.ReadChar();
191                    int versionInUse = binaryReader.ReadInt32();
192                    //Check if a newer Version is in use
193                    if (versionInUse > version)
194                    {
195                        throw new KeySearcherStopException();
196                    }
197                }
198            }
199            catch(KeySearcherStopException)
200            {
201                throw new KeySearcherStopException();
202            }
203           
204        }
205        //-----------------------------------------------------------------------------
206
207        public DateTime StartDate(String ofJobIdentifier)
208        {
209            var key = ofJobIdentifier + "_startdate";
210            var requestResult = RetrieveWithStatistic(key);
211
212            if (requestResult.IsSuccessful() && requestResult.Data != null)
213            {
214                var startTimeUtc = DateTime.SpecifyKind(
215                    DateTime.FromBinary(BitConverter.ToInt64(requestResult.Data, 0)), DateTimeKind.Utc);
216                return startTimeUtc.ToLocalTime();
217            }
218
219            StoreWithStatistic(key, BitConverter.GetBytes((DateTime.UtcNow.ToBinary())));
220            return DateTime.Now;
221        }
222
223        public long SubmitterID(String ofJobIdentifier)
224        {
225            var key = ofJobIdentifier + "_submitterid";
226            var requestResult = RetrieveWithStatistic(key);
227
228            if (requestResult.IsSuccessful() && requestResult.Data != null)
229            {
230                var submitterid = BitConverter.ToInt64(requestResult.Data, 0);
231                return submitterid;
232            }
233
234            StoreWithStatistic(key, BitConverter.GetBytes(Cryptool.PluginBase.Miscellaneous.UniqueIdentifier.GetID()));
235            return Cryptool.PluginBase.Miscellaneous.UniqueIdentifier.GetID();
236        }
237
238        public RequestResult RetrieveWithStatistic(string key)
239        {
240            statusContainer.RetrieveRequests++;
241            statusContainer.TotalDhtRequests++;
242            var requestResult = P2PManager.Retrieve(key);
243
244            if (requestResult.Data != null)
245            {
246                statusContainer.RetrievedBytes += requestResult.Data.Length;
247                statusContainer.TotalBytes += requestResult.Data.Length;
248            }
249
250            return requestResult;
251        }
252
253        public RequestResult RemoveWithStatistic(string key)
254        {
255            statusContainer.RemoveRequests++;
256            statusContainer.TotalDhtRequests++;
257            return P2PManager.Remove(key);
258        }
259
260        public RequestResult StoreWithStatistic(string key, byte[] data)
261        {
262            statusContainer.StoreRequests++;
263            statusContainer.TotalDhtRequests++;
264            var requestResult = P2PManager.Store(key, data);
265
266            if (requestResult.Data != null)
267            {
268                statusContainer.StoredBytes += requestResult.Data.Length;
269                statusContainer.TotalBytes += requestResult.Data.Length;
270            }
271
272            return requestResult;
273        }
274    }
275}
Note: See TracBrowser for help on using the repository browser.