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

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

Versionnumber added. (Not in use yet)
Required whenever the size of the Memory Stream changes.

File size: 10.0 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: Versionnumber write
50            //-----------------------------------------------------
51            //binaryWriter.Write(version);
52            //-----------------------------------------------------
53           
54            //TODO: Hash Table write;
55
56            return StoreWithStatistic(KeyInDht(nodeToUpdate), memoryStream.ToArray());
57        }
58
59        private static void UpdateNodeInDht(Node nodeToUpdate, BinaryWriter binaryWriter)
60        {
61            binaryWriter.Write(nodeToUpdate.LeftChildFinished);
62            binaryWriter.Write(nodeToUpdate.RightChildFinished);
63        }
64
65        private static void UpdateLeafInDht(Leaf nodeToUpdate, BinaryWriter binaryWriter)
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            //TODO: Versionnumber read
119            /*
120            try
121            {
122                //If you're already at the end of the stream ignore the version
123                if (binaryReader.BaseStream.Length != binaryReader.BaseStream.Position)
124                {
125                    int versionInUse = binaryReader.ReadInt32();
126                    //Check if a newer Version is in use
127                    if (versionInUse > version)
128                    {
129                        throw new KeySearcherStopException();
130                    }
131                    //TODO: Hashtable read
132                }
133            }
134            catch(Exception)
135            {
136                throw new KeySearcherStopException();
137            }
138
139            //----------------------------------------------------------------------------------
140            */
141            if (resultCount > 0)
142            {
143                keySearcher.IntegrateNewResults(nodeToUpdate.Result);
144                statisticsGenerator.ProcessPatternResults(nodeToUpdate.Result);
145            }
146
147            nodeToUpdate.UpdateCache();
148            return requestResult;
149        }
150
151        private static void UpdateNodeFromDht(Node nodeToUpdate, BinaryReader binaryReader)
152        {
153            nodeToUpdate.LeftChildFinished = binaryReader.ReadBoolean() || nodeToUpdate.LeftChildFinished;
154            nodeToUpdate.RightChildFinished = binaryReader.ReadBoolean() || nodeToUpdate.RightChildFinished;
155        }
156
157        private static void UpdateLeafFromDht(Leaf nodeToUpdate, BinaryReader binaryReader)
158        {
159            var date = DateTime.FromBinary(binaryReader.ReadInt64());
160            if (date > nodeToUpdate.LastReservationDate)
161            {
162                nodeToUpdate.LastReservationDate = date;
163            }
164           
165            //----------------------------------------------------------------
166            try
167            {
168                if (binaryReader.BaseStream.Length - binaryReader.BaseStream.Position >= 8)
169                {
170                    nodeToUpdate.setClientIdentifier(binaryReader.ReadInt64());
171                }
172                else
173                {
174                    throw new Exception();
175                }
176            }
177            catch (Exception)
178            {
179                // client id not available, use default
180                nodeToUpdate.setClientIdentifier(-1);
181            }
182            //----------------------------------------------------------------
183           
184        }
185
186        internal static string KeyInDht(NodeBase node)
187        {
188            return string.Format("{0}_node_{1}_{2}", node.DistributedJobIdentifier, node.From, node.To);
189        }
190
191        public DateTime StartDate(String ofJobIdentifier)
192        {
193            var key = ofJobIdentifier + "_startdate";
194            var requestResult = RetrieveWithStatistic(key);
195
196            if (requestResult.IsSuccessful() && requestResult.Data != null)
197            {
198                var startTimeUtc = DateTime.SpecifyKind(
199                    DateTime.FromBinary(BitConverter.ToInt64(requestResult.Data, 0)), DateTimeKind.Utc);
200                return startTimeUtc.ToLocalTime();
201            }
202
203            StoreWithStatistic(key, BitConverter.GetBytes((DateTime.UtcNow.ToBinary())));
204            return DateTime.Now;
205        }
206
207        //------------------------------------------------------------------------
208        public long SubmitterID(String ofJobIdentifier)
209        {
210            var key = ofJobIdentifier + "_submitterid";
211            var requestResult = RetrieveWithStatistic(key);
212
213            if (requestResult.IsSuccessful() && requestResult.Data != null)
214            {
215                var submitterid = BitConverter.ToInt64(requestResult.Data, 0);
216                return submitterid;
217            }
218
219            StoreWithStatistic(key, BitConverter.GetBytes(Cryptool.PluginBase.Miscellaneous.UniqueIdentifier.GetID()));
220            return Cryptool.PluginBase.Miscellaneous.UniqueIdentifier.GetID();
221        }
222        //---------------------------------------------------------------------------
223
224        public RequestResult RetrieveWithStatistic(string key)
225        {
226            statusContainer.RetrieveRequests++;
227            statusContainer.TotalDhtRequests++;
228            var requestResult = P2PManager.Retrieve(key);
229
230            if (requestResult.Data != null)
231            {
232                statusContainer.RetrievedBytes += requestResult.Data.Length;
233                statusContainer.TotalBytes += requestResult.Data.Length;
234            }
235
236            return requestResult;
237        }
238
239        public RequestResult RemoveWithStatistic(string key)
240        {
241            statusContainer.RemoveRequests++;
242            statusContainer.TotalDhtRequests++;
243            return P2PManager.Remove(key);
244        }
245
246        public RequestResult StoreWithStatistic(string key, byte[] data)
247        {
248            statusContainer.StoreRequests++;
249            statusContainer.TotalDhtRequests++;
250            var requestResult = P2PManager.Store(key, data);
251
252            if (requestResult.Data != null)
253            {
254                statusContainer.StoredBytes += requestResult.Data.Length;
255                statusContainer.TotalBytes += requestResult.Data.Length;
256            }
257
258            return requestResult;
259        }
260    }
261}
Note: See TracBrowser for help on using the repository browser.