/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
- //******************************************************************************************************
- // HistorianCompressedStream.cs - Gbtc
- //
- // Copyright © 2013, Grid Protection Alliance. All Rights Reserved.
- //
- // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
- // the NOTICE file distributed with this work for additional information regarding copyright ownership.
- // The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may
- // not use this file except in compliance with the License. You may obtain a copy of the License at:
- //
- // http://www.opensource.org/licenses/eclipse-1.0.php
- //
- // Unless agreed to in writing, the subject software distributed under the License is distributed on an
- // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
- // License for the specific language governing permissions and limitations.
- //
- // Code Modification History:
- // ----------------------------------------------------------------------------------------------------
- // 8/10/2013 - Steven E. Chisholm
- // Generated original version of source code.
- //
- //
- //******************************************************************************************************
-
- using System;
- using GSF.IO;
- using openHistorian.Collections;
- using GSF.SortedTreeStore.Net.Initialization;
-
- namespace GSF.SortedTreeStore.Net.Compression
- {
- public class HistorianCompressedStream
- : KeyValueStreamCompressionBase<HistorianKey, HistorianValue>
- {
-
- ulong m_prevTimestamp;
- ulong m_prevPointID;
-
- public override bool SupportsPointerSerialization
- {
- get
- {
- return true;
- }
- }
-
- public override int MaxCompressedSize
- {
- get
- {
- return 55; //3 extra bytes just to be safe.
- }
- }
-
- public override Guid CompressionType
- {
- get
- {
- return CreateHistorianCompressedStream.TypeGuid;
- }
- }
-
- public override void WriteEndOfStream(BinaryStreamBase stream)
- {
- stream.Write((byte)255);
- }
-
- public override void Encode(BinaryStreamBase stream, HistorianKey currentKey, HistorianValue currentValue)
- {
- if (currentKey.Timestamp == m_prevTimestamp
- && ((currentKey.PointID ^ m_prevPointID) < 64)
- && currentKey.EntryNumber == 0
- && currentValue.Value1 <= uint.MaxValue //must be a 32-bit value
- && currentValue.Value2 == 0
- && currentValue.Value3 == 0)
- {
- if (currentValue.Value1 == 0)
- {
- stream.Write((byte)((currentKey.PointID ^ m_prevPointID)));
- }
- else
- {
- stream.Write((byte)((currentKey.PointID ^ m_prevPointID) | 64));
- stream.Write((uint)currentValue.Value1);
- }
- m_prevTimestamp = currentKey.Timestamp;
- m_prevPointID = currentKey.PointID;
- return;
- }
-
- byte code = 128;
-
- if (currentKey.Timestamp != m_prevTimestamp)
- code |= 64;
-
- if (currentKey.EntryNumber != 0)
- code |= 32;
-
- if (currentValue.Value1 > uint.MaxValue)
- code |= 16;
- else if (currentValue.Value1 > 0)
- code |= 8;
-
- if (currentValue.Value2 != 0)
- code |= 4;
-
- if (currentValue.Value3 > uint.MaxValue)
- code |= 2;
- else if (currentValue.Value3 > 0)
- code |= 1;
-
- stream.Write(code);
-
- if (currentKey.Timestamp != m_prevTimestamp)
- stream.Write7Bit(currentKey.Timestamp ^ m_prevTimestamp);
-
- stream.Write7Bit(currentKey.PointID ^ m_prevPointID);
-
- if (currentKey.EntryNumber != 0)
- stream.Write7Bit(currentKey.EntryNumber);
-
- if (currentValue.Value1 > uint.MaxValue)
- stream.Write(currentValue.Value1);
- else if (currentValue.Value1 > 0)
- stream.Write((uint)currentValue.Value1);
-
- if (currentValue.Value2 != 0)
- stream.Write(currentValue.Value2);
-
- if (currentValue.Value3 > uint.MaxValue)
- stream.Write(currentValue.Value3);
- else if (currentValue.Value3 > 0)
- stream.Write((uint)currentValue.Value3);
-
- m_prevTimestamp = currentKey.Timestamp;
- m_prevPointID = currentKey.PointID;
- }
-
- public override unsafe int Encode(byte* stream, HistorianKey currentKey, HistorianValue currentValue)
- {
- int size = 0;
- if (currentKey.Timestamp == m_prevTimestamp
- && ((currentKey.PointID ^ m_prevPointID) < 64)
- && currentKey.EntryNumber == 0
- && currentValue.Value1 <= uint.MaxValue //must be a 32-bit value
- && currentValue.Value2 == 0
- && currentValue.Value3 == 0)
- {
- if (currentValue.Value1 == 0)
- {
- stream[0] = (byte)(currentKey.PointID ^ m_prevPointID);
- size = 1;
- }
- else
- {
- stream[0] = ((byte)((currentKey.PointID ^ m_prevPointID) | 64));
- *(uint*)(stream + 1) = (uint)currentValue.Value1;
- size = 5;
- }
- m_prevTimestamp = currentKey.Timestamp;
- m_prevPointID = currentKey.PointID;
- return size;
- }
-
- byte code = 128;
-
- if (currentKey.Timestamp != m_prevTimestamp)
- code |= 64;
-
- if (currentKey.EntryNumber != 0)
- code |= 32;
-
- if (currentValue.Value1 > uint.MaxValue)
- code |= 16;
- else if (currentValue.Value1 > 0)
- code |= 8;
-
- if (currentValue.Value2 != 0)
- code |= 4;
-
- if (currentValue.Value3 > uint.MaxValue)
- code |= 2;
- else if (currentValue.Value3 > 0)
- code |= 1;
-
- stream[0] = code;
- size = 1;
-
- if (currentKey.Timestamp != m_prevTimestamp)
- GSF.Compression.Write7Bit(stream, ref size, currentKey.Timestamp ^ m_prevTimestamp);
-
- GSF.Compression.Write7Bit(stream, ref size, currentKey.PointID ^ m_prevPointID);
-
- if (currentKey.EntryNumber != 0)
- GSF.Compression.Write7Bit(stream, ref size, currentKey.EntryNumber);
-
- if (currentValue.Value1 > uint.MaxValue)
- {
- *(ulong*)(stream + size) = currentValue.Value1;
- size += 8;
- }
- else if (currentValue.Value1 > 0)
- {
- *(uint*)(stream + size) = (uint)currentValue.Value1;
- size += 4;
- }
-
- if (currentValue.Value2 != 0)
- {
- *(ulong*)(stream + size) = currentValue.Value2;
- size += 8;
- }
-
- if (currentValue.Value3 > uint.MaxValue)
- {
- *(ulong*)(stream + size) = currentValue.Value3;
- size += 8;
- }
- else if (currentValue.Value3 > 0)
- {
- *(uint*)(stream + size) = (uint)currentValue.Value3;
- size += 4;
- }
-
- m_prevTimestamp = currentKey.Timestamp;
- m_prevPointID = currentKey.PointID;
- return size;
- }
-
- public override unsafe bool TryDecode(BinaryStreamBase stream, HistorianKey key, HistorianValue value)
- {
- byte code = stream.ReadUInt8();
- if (code == 255)
- return false;
-
- if (code < 128)
- {
- if (code < 64)
- {
- key.Timestamp = m_prevTimestamp;
- key.PointID = m_prevPointID ^ code;
- key.EntryNumber = 0;
- value.Value1 = 0;
- value.Value2 = 0;
- value.Value3 = 0;
- }
- else
- {
- key.Timestamp = m_prevTimestamp;
- key.PointID = m_prevPointID ^ code ^ 64;
- key.EntryNumber = 0;
- value.Value1 = stream.ReadUInt32();
- value.Value2 = 0;
- value.Value3 = 0;
- }
- m_prevTimestamp = key.Timestamp;
- m_prevPointID = key.PointID;
- return true;
- }
-
- if ((code & 64) != 0) //T is set
- key.Timestamp = m_prevTimestamp ^ stream.Read7BitUInt64();
- else
- key.Timestamp = m_prevTimestamp;
-
- key.PointID = m_prevPointID ^ stream.Read7BitUInt64();
-
- if ((code & 32) != 0) //E is set)
- key.EntryNumber = stream.Read7BitUInt64();
- else
- key.EntryNumber = 0;
-
- if ((code & 16) != 0) //V1 High is set)
- value.Value1 = stream.ReadUInt64();
- else if ((code & 8) != 0) //V1 low is set)
- value.Value1 = stream.ReadUInt32();
- else
- value.Value1 = 0;
-
- if ((code & 4) != 0) //V2 is set)
- value.Value2 = stream.ReadUInt64();
- else
- value.Value2 = 0;
-
- if ((code & 2) != 0) //V1 High is set)
- value.Value3 = stream.ReadUInt64();
- else if ((code & 1) != 0) //V1 low is set)
- value.Value3 = stream.ReadUInt32();
- else
- value.Value3 = 0;
- m_prevTimestamp = key.Timestamp;
- m_prevPointID = key.PointID;
-
- return true;
- }
-
- public override void ResetEncoder()
- {
- m_prevTimestamp = 0;
- m_prevPointID = 0;
- }
- }
- }