private static DoubleValueState ReadDouble(BitBinaryReader reader, DoubleValueState state) { var firstBit = reader.ReadBit(); if (!firstBit) { return(state); } var secondBit = reader.ReadBit(); long meaningFulBits; if (!secondBit) { var numBitsToRead = BitAggregateMagic.NumBitsInLongInteger - state.LeadingZeros - state.TrailingZeros; meaningFulBits = reader.ReadBits(numBitsToRead); } else { // a new block position was started since the number starts with "11". state.LeadingZeros = (sbyte)reader.ReadBits(NumBitsToEncodeNumLeadingZeros); var numBitsToRead = (sbyte)reader.ReadBits(NumBitsToEncodeNumMeaningfulBits); if (numBitsToRead == 0) { // The block size is 64 bits which becomes 0 in writing into 6 bits - overflow. // If the block size were indeed 0 bits, the xor value would be 0, and the actual value would be identical to the prior value, // so we would have bailed out early on since firstBit would be 0. numBitsToRead = (sbyte)BitAggregateMagic.NumBitsInLongInteger; } state.TrailingZeros = (sbyte)(BitAggregateMagic.NumBitsInLongInteger - state.LeadingZeros - numBitsToRead); meaningFulBits = reader.ReadBits(numBitsToRead); } var xor = meaningFulBits << state.TrailingZeros; state.Value = BitConverter.Int64BitsToDouble(xor ^ BitConverter.DoubleToInt64Bits(state.Value)); return(state); }
/// <summary> /// Deserializes for one timestamp - v2. /// </summary> /// <param name="version">The serialization version.</param> /// <param name="reader">The bit reader.</param> /// <param name="definition">The definition.</param> /// <param name="values">The values.</param> /// <param name="dataPointIndex">Index of the data point.</param> /// <param name="currentBlockLeadingZeros">The current block leading zeros.</param> /// <param name="currentBlockTrailingZeros">The current block trailing zeros.</param> /// <param name="priorValidValues">The prior valid values.</param> private static void DeserializeForOneTimestampV2AndAbove(byte version, BitBinaryReader reader, TimeSeriesDefinition <MetricIdentifier> definition, List <List <double?> > values, int dataPointIndex, sbyte[] currentBlockLeadingZeros, sbyte[] currentBlockTrailingZeros, double[] priorValidValues) { var numSamplingTypes = values.Count; for (var s = 0; s < numSamplingTypes; s++) { if (dataPointIndex == 0) { // very first value of the series priorValidValues[s] = reader.BinaryReader.ReadDouble(); values[s].Add(GetNullableDouble(priorValidValues[s])); } else { var firstBit = reader.ReadBit(); if (!firstBit) { // first bit is 0 values[s].Add(GetNullableDouble(priorValidValues[s])); } else { var secondBit = reader.ReadBit(); long meaningfulBits; if (!secondBit) { // 2nd bit is 0 while the first is 1. if (currentBlockLeadingZeros[s] < 0) { throw new Exception("The block has not been set so it is a bug in serialization on server"); } var numBitsToRead = BitAggregateMagic.NumBitsInLongInteger - currentBlockLeadingZeros[s] - currentBlockTrailingZeros[s]; meaningfulBits = reader.ReadBits(numBitsToRead); } else { // a new block position was started since the number starts with "11". currentBlockLeadingZeros[s] = (sbyte)reader.ReadBits(GetNumBitsToEncodeNumLeadingZeros(version)); var numBitsToRead = (sbyte)reader.ReadBits(NumBitsToEncodeNumMeaningfulBits); if (numBitsToRead == 0) { // The block size is 64 bits which becomes 0 in writing into 6 bits - overflow. // If the block size were indeed 0 bits, the xor value would be 0, and the actual value would be identical to the prior value, // so we would not have reached here since firstBit would be 0. numBitsToRead = (sbyte)BitAggregateMagic.NumBitsInLongInteger; } currentBlockTrailingZeros[s] = (sbyte)(BitAggregateMagic.NumBitsInLongInteger - currentBlockLeadingZeros[s] - numBitsToRead); meaningfulBits = reader.ReadBits(numBitsToRead); } long xor = meaningfulBits << currentBlockTrailingZeros[s]; priorValidValues[s] = BitConverter.Int64BitsToDouble(xor ^ BitConverter.DoubleToInt64Bits(priorValidValues[s])); values[s].Add(GetNullableDouble(priorValidValues[s])); } } } }