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

Last change on this file since 2017 was 2017, checked in by Paul Lelgemann, 11 years ago

+ Added TODOs

File size: 7.1 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        public StorageHelper(KeySearcher keySearcher, StatisticsGenerator statisticsGenerator, StatusContainer statusContainer)
17        {
18            this.keySearcher = keySearcher;
19            this.statisticsGenerator = statisticsGenerator;
20            this.statusContainer = statusContainer;
21        }
22
23        internal RequestResult UpdateInDht(NodeBase nodeToUpdate)
24        {
25            var memoryStream = new MemoryStream();
26            var binaryWriter = new BinaryWriter(memoryStream);
27
28            if (nodeToUpdate is Node)
29            {
30                UpdateNodeInDht((Node) nodeToUpdate, binaryWriter);
31            } else
32            {
33                UpdateLeafInDht((Leaf) nodeToUpdate, binaryWriter);
34            }
35
36            // Append results
37            binaryWriter.Write(nodeToUpdate.Result.Count);
38            foreach (var valueKey in nodeToUpdate.Result)
39            {
40                binaryWriter.Write(valueKey.key);
41                binaryWriter.Write(valueKey.value);
42                binaryWriter.Write(valueKey.decryption.Length);
43                binaryWriter.Write(valueKey.decryption);
44            }
45
46            return StoreWithStatistic(KeyInDht(nodeToUpdate), memoryStream.ToArray());
47        }
48
49        private static void UpdateNodeInDht(Node nodeToUpdate, BinaryWriter binaryWriter)
50        {
51            binaryWriter.Write(nodeToUpdate.LeftChildFinished);
52            binaryWriter.Write(nodeToUpdate.RightChildFinished);
53        }
54
55        private static void UpdateLeafInDht(Leaf nodeToUpdate, BinaryWriter binaryWriter)
56        {
57            var buffer = nodeToUpdate.LastReservationDate.ToBinary();
58            binaryWriter.Write(buffer);
59           
60            // TODO write client identification to binaryWriter, e.g.
61            // binaryWriter.Write("id here from some other method");
62        }
63
64        internal RequestResult UpdateFromDht(NodeBase nodeToUpdate, bool forceUpdate = false)
65        {
66            if (!forceUpdate && nodeToUpdate.LastUpdate > DateTime.Now.Subtract(new TimeSpan(0, 0, 5)))
67            {
68                return new RequestResult { Status = RequestResultType.Success };
69            }
70
71            nodeToUpdate.LastUpdate = DateTime.Now;
72
73            var requestResult = RetrieveWithStatistic(KeyInDht(nodeToUpdate));
74            var nodeBytes = requestResult.Data;
75
76            if (nodeBytes == null)
77            {
78                return requestResult;
79            }
80
81            var binaryReader = new BinaryReader(new MemoryStream(nodeBytes));
82
83            if (nodeToUpdate is Node)
84            {
85                UpdateNodeFromDht((Node) nodeToUpdate, binaryReader);
86            } else
87            {
88                UpdateLeafFromDht((Leaf) nodeToUpdate, binaryReader);
89            }
90
91            // Load results
92            var resultCount = binaryReader.ReadInt32();
93            for (var i = 0; i < resultCount; i++)
94            {
95                var newResult = new KeySearcher.ValueKey
96                                    {
97                                        key = binaryReader.ReadString(),
98                                        value = binaryReader.ReadDouble(),
99                                        decryption = binaryReader.ReadBytes(binaryReader.ReadInt32())
100                                    };
101                nodeToUpdate.Result.AddLast(newResult);
102            }
103
104            if (resultCount > 0)
105            {
106                keySearcher.IntegrateNewResults(nodeToUpdate.Result);
107                statisticsGenerator.ProcessPatternResults(nodeToUpdate.Result);
108            }
109
110            nodeToUpdate.UpdateCache();
111            return requestResult;
112        }
113
114        private static void UpdateNodeFromDht(Node nodeToUpdate, BinaryReader binaryReader)
115        {
116            nodeToUpdate.LeftChildFinished = binaryReader.ReadBoolean() || nodeToUpdate.LeftChildFinished;
117            nodeToUpdate.RightChildFinished = binaryReader.ReadBoolean() || nodeToUpdate.RightChildFinished;
118        }
119
120        private static void UpdateLeafFromDht(Leaf nodeToUpdate, BinaryReader binaryReader)
121        {
122            var date = DateTime.FromBinary(binaryReader.ReadInt64());
123            if (date > nodeToUpdate.LastReservationDate)
124            {
125                nodeToUpdate.LastReservationDate = date;
126            }
127
128            // TODO read leaf from reader, e.g.
129            /*
130            try
131            {
132                nodeToUpdate.ClientIdentifier = binaryReader.ReadString();
133            } catch (IOException)
134            {
135                // client id not available, use default
136                nodeToUpdate.ClientIdentifier = "-1";
137            }
138            */
139        }
140
141        internal static string KeyInDht(NodeBase node)
142        {
143            return string.Format("{0}_node_{1}_{2}", node.DistributedJobIdentifier, node.From, node.To);
144        }
145
146        public DateTime StartDate(String ofJobIdentifier)
147        {
148            var key = ofJobIdentifier + "_startdate";
149            var requestResult = RetrieveWithStatistic(key);
150
151            if (requestResult.IsSuccessful() && requestResult.Data != null)
152            {
153                var startTimeUtc = DateTime.SpecifyKind(
154                    DateTime.FromBinary(BitConverter.ToInt64(requestResult.Data, 0)), DateTimeKind.Utc);
155                return startTimeUtc.ToLocalTime();
156            }
157
158            StoreWithStatistic(key, BitConverter.GetBytes((DateTime.UtcNow.ToBinary())));
159            return DateTime.Now;
160        }
161
162        public RequestResult RetrieveWithStatistic(string key)
163        {
164            statusContainer.RetrieveRequests++;
165            statusContainer.TotalDhtRequests++;
166            var requestResult = P2PManager.Retrieve(key);
167
168            if (requestResult.Data != null)
169            {
170                statusContainer.RetrievedBytes += requestResult.Data.Length;
171                statusContainer.TotalBytes += requestResult.Data.Length;
172            }
173
174            return requestResult;
175        }
176
177        public RequestResult RemoveWithStatistic(string key)
178        {
179            statusContainer.RemoveRequests++;
180            statusContainer.TotalDhtRequests++;
181            return P2PManager.Remove(key);
182        }
183
184        public RequestResult StoreWithStatistic(string key, byte[] data)
185        {
186            statusContainer.StoreRequests++;
187            statusContainer.TotalDhtRequests++;
188            var requestResult = P2PManager.Store(key, data);
189
190            if (requestResult.Data != null)
191            {
192                statusContainer.StoredBytes += requestResult.Data.Length;
193                statusContainer.TotalBytes += requestResult.Data.Length;
194            }
195
196            return requestResult;
197        }
198    }
199}
Note: See TracBrowser for help on using the repository browser.