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

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

Added the version number at the beginning of the stream.
Still needs to be tested and verified.
Update to version 1 will be announced soon.

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