PageRenderTime 49ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/Alpha/Source/Libraries/openHistorian.Core/SortedTreeStore/Net/Compression/HistorianCompressedStream.cs

#
C# | 303 lines | 233 code | 47 blank | 23 comment | 92 complexity | b7dda6f8b45b8325de44cf4ee545ddcc MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, EPL-1.0
  1. //******************************************************************************************************
  2. // HistorianCompressedStream.cs - Gbtc
  3. //
  4. // Copyright © 2013, Grid Protection Alliance. All Rights Reserved.
  5. //
  6. // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
  7. // the NOTICE file distributed with this work for additional information regarding copyright ownership.
  8. // The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may
  9. // not use this file except in compliance with the License. You may obtain a copy of the License at:
  10. //
  11. // http://www.opensource.org/licenses/eclipse-1.0.php
  12. //
  13. // Unless agreed to in writing, the subject software distributed under the License is distributed on an
  14. // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
  15. // License for the specific language governing permissions and limitations.
  16. //
  17. // Code Modification History:
  18. // ----------------------------------------------------------------------------------------------------
  19. // 8/10/2013 - Steven E. Chisholm
  20. // Generated original version of source code.
  21. //
  22. //
  23. //******************************************************************************************************
  24. using System;
  25. using GSF.IO;
  26. using openHistorian.Collections;
  27. using GSF.SortedTreeStore.Net.Initialization;
  28. namespace GSF.SortedTreeStore.Net.Compression
  29. {
  30. public class HistorianCompressedStream
  31. : KeyValueStreamCompressionBase<HistorianKey, HistorianValue>
  32. {
  33. ulong m_prevTimestamp;
  34. ulong m_prevPointID;
  35. public override bool SupportsPointerSerialization
  36. {
  37. get
  38. {
  39. return true;
  40. }
  41. }
  42. public override int MaxCompressedSize
  43. {
  44. get
  45. {
  46. return 55; //3 extra bytes just to be safe.
  47. }
  48. }
  49. public override Guid CompressionType
  50. {
  51. get
  52. {
  53. return CreateHistorianCompressedStream.TypeGuid;
  54. }
  55. }
  56. public override void WriteEndOfStream(BinaryStreamBase stream)
  57. {
  58. stream.Write((byte)255);
  59. }
  60. public override void Encode(BinaryStreamBase stream, HistorianKey currentKey, HistorianValue currentValue)
  61. {
  62. if (currentKey.Timestamp == m_prevTimestamp
  63. && ((currentKey.PointID ^ m_prevPointID) < 64)
  64. && currentKey.EntryNumber == 0
  65. && currentValue.Value1 <= uint.MaxValue //must be a 32-bit value
  66. && currentValue.Value2 == 0
  67. && currentValue.Value3 == 0)
  68. {
  69. if (currentValue.Value1 == 0)
  70. {
  71. stream.Write((byte)((currentKey.PointID ^ m_prevPointID)));
  72. }
  73. else
  74. {
  75. stream.Write((byte)((currentKey.PointID ^ m_prevPointID) | 64));
  76. stream.Write((uint)currentValue.Value1);
  77. }
  78. m_prevTimestamp = currentKey.Timestamp;
  79. m_prevPointID = currentKey.PointID;
  80. return;
  81. }
  82. byte code = 128;
  83. if (currentKey.Timestamp != m_prevTimestamp)
  84. code |= 64;
  85. if (currentKey.EntryNumber != 0)
  86. code |= 32;
  87. if (currentValue.Value1 > uint.MaxValue)
  88. code |= 16;
  89. else if (currentValue.Value1 > 0)
  90. code |= 8;
  91. if (currentValue.Value2 != 0)
  92. code |= 4;
  93. if (currentValue.Value3 > uint.MaxValue)
  94. code |= 2;
  95. else if (currentValue.Value3 > 0)
  96. code |= 1;
  97. stream.Write(code);
  98. if (currentKey.Timestamp != m_prevTimestamp)
  99. stream.Write7Bit(currentKey.Timestamp ^ m_prevTimestamp);
  100. stream.Write7Bit(currentKey.PointID ^ m_prevPointID);
  101. if (currentKey.EntryNumber != 0)
  102. stream.Write7Bit(currentKey.EntryNumber);
  103. if (currentValue.Value1 > uint.MaxValue)
  104. stream.Write(currentValue.Value1);
  105. else if (currentValue.Value1 > 0)
  106. stream.Write((uint)currentValue.Value1);
  107. if (currentValue.Value2 != 0)
  108. stream.Write(currentValue.Value2);
  109. if (currentValue.Value3 > uint.MaxValue)
  110. stream.Write(currentValue.Value3);
  111. else if (currentValue.Value3 > 0)
  112. stream.Write((uint)currentValue.Value3);
  113. m_prevTimestamp = currentKey.Timestamp;
  114. m_prevPointID = currentKey.PointID;
  115. }
  116. public override unsafe int Encode(byte* stream, HistorianKey currentKey, HistorianValue currentValue)
  117. {
  118. int size = 0;
  119. if (currentKey.Timestamp == m_prevTimestamp
  120. && ((currentKey.PointID ^ m_prevPointID) < 64)
  121. && currentKey.EntryNumber == 0
  122. && currentValue.Value1 <= uint.MaxValue //must be a 32-bit value
  123. && currentValue.Value2 == 0
  124. && currentValue.Value3 == 0)
  125. {
  126. if (currentValue.Value1 == 0)
  127. {
  128. stream[0] = (byte)(currentKey.PointID ^ m_prevPointID);
  129. size = 1;
  130. }
  131. else
  132. {
  133. stream[0] = ((byte)((currentKey.PointID ^ m_prevPointID) | 64));
  134. *(uint*)(stream + 1) = (uint)currentValue.Value1;
  135. size = 5;
  136. }
  137. m_prevTimestamp = currentKey.Timestamp;
  138. m_prevPointID = currentKey.PointID;
  139. return size;
  140. }
  141. byte code = 128;
  142. if (currentKey.Timestamp != m_prevTimestamp)
  143. code |= 64;
  144. if (currentKey.EntryNumber != 0)
  145. code |= 32;
  146. if (currentValue.Value1 > uint.MaxValue)
  147. code |= 16;
  148. else if (currentValue.Value1 > 0)
  149. code |= 8;
  150. if (currentValue.Value2 != 0)
  151. code |= 4;
  152. if (currentValue.Value3 > uint.MaxValue)
  153. code |= 2;
  154. else if (currentValue.Value3 > 0)
  155. code |= 1;
  156. stream[0] = code;
  157. size = 1;
  158. if (currentKey.Timestamp != m_prevTimestamp)
  159. GSF.Compression.Write7Bit(stream, ref size, currentKey.Timestamp ^ m_prevTimestamp);
  160. GSF.Compression.Write7Bit(stream, ref size, currentKey.PointID ^ m_prevPointID);
  161. if (currentKey.EntryNumber != 0)
  162. GSF.Compression.Write7Bit(stream, ref size, currentKey.EntryNumber);
  163. if (currentValue.Value1 > uint.MaxValue)
  164. {
  165. *(ulong*)(stream + size) = currentValue.Value1;
  166. size += 8;
  167. }
  168. else if (currentValue.Value1 > 0)
  169. {
  170. *(uint*)(stream + size) = (uint)currentValue.Value1;
  171. size += 4;
  172. }
  173. if (currentValue.Value2 != 0)
  174. {
  175. *(ulong*)(stream + size) = currentValue.Value2;
  176. size += 8;
  177. }
  178. if (currentValue.Value3 > uint.MaxValue)
  179. {
  180. *(ulong*)(stream + size) = currentValue.Value3;
  181. size += 8;
  182. }
  183. else if (currentValue.Value3 > 0)
  184. {
  185. *(uint*)(stream + size) = (uint)currentValue.Value3;
  186. size += 4;
  187. }
  188. m_prevTimestamp = currentKey.Timestamp;
  189. m_prevPointID = currentKey.PointID;
  190. return size;
  191. }
  192. public override unsafe bool TryDecode(BinaryStreamBase stream, HistorianKey key, HistorianValue value)
  193. {
  194. byte code = stream.ReadUInt8();
  195. if (code == 255)
  196. return false;
  197. if (code < 128)
  198. {
  199. if (code < 64)
  200. {
  201. key.Timestamp = m_prevTimestamp;
  202. key.PointID = m_prevPointID ^ code;
  203. key.EntryNumber = 0;
  204. value.Value1 = 0;
  205. value.Value2 = 0;
  206. value.Value3 = 0;
  207. }
  208. else
  209. {
  210. key.Timestamp = m_prevTimestamp;
  211. key.PointID = m_prevPointID ^ code ^ 64;
  212. key.EntryNumber = 0;
  213. value.Value1 = stream.ReadUInt32();
  214. value.Value2 = 0;
  215. value.Value3 = 0;
  216. }
  217. m_prevTimestamp = key.Timestamp;
  218. m_prevPointID = key.PointID;
  219. return true;
  220. }
  221. if ((code & 64) != 0) //T is set
  222. key.Timestamp = m_prevTimestamp ^ stream.Read7BitUInt64();
  223. else
  224. key.Timestamp = m_prevTimestamp;
  225. key.PointID = m_prevPointID ^ stream.Read7BitUInt64();
  226. if ((code & 32) != 0) //E is set)
  227. key.EntryNumber = stream.Read7BitUInt64();
  228. else
  229. key.EntryNumber = 0;
  230. if ((code & 16) != 0) //V1 High is set)
  231. value.Value1 = stream.ReadUInt64();
  232. else if ((code & 8) != 0) //V1 low is set)
  233. value.Value1 = stream.ReadUInt32();
  234. else
  235. value.Value1 = 0;
  236. if ((code & 4) != 0) //V2 is set)
  237. value.Value2 = stream.ReadUInt64();
  238. else
  239. value.Value2 = 0;
  240. if ((code & 2) != 0) //V1 High is set)
  241. value.Value3 = stream.ReadUInt64();
  242. else if ((code & 1) != 0) //V1 low is set)
  243. value.Value3 = stream.ReadUInt32();
  244. else
  245. value.Value3 = 0;
  246. m_prevTimestamp = key.Timestamp;
  247. m_prevPointID = key.PointID;
  248. return true;
  249. }
  250. public override void ResetEncoder()
  251. {
  252. m_prevTimestamp = 0;
  253. m_prevPointID = 0;
  254. }
  255. }
  256. }