Пример #1
0
        /// <summary>
        /// Store a delta of delta for the rest of the values in one of the
        /// following ways
        ///
        /// '0' = delta of delta did not change
        /// '10' followed by a value length of 7
        /// '110' followed by a value length of 9
        /// '1110' followed by a value length of 12
        /// '1111' followed by a value length of 32
        /// </summary>
        /// <param name="date"></param>
        public bool AppendTimestamp(DateTime date)
        {
            int timestamp = ToUnixTime(date);
            int delta     = timestamp - _previousTimestamp;

            if (delta < MinTimeStampDelta && _previousTimestamp != 0)
            {
                return(false);
            }

            if (_hasStoredFirstValue == false)
            {
                // Store the first timestamp as it.
                _buffer.AddValue(timestamp, Constants.BitsForFirstTimestamp);
                _previousTimestamp      = timestamp;
                _previousTimestampDelta = Constants.DefaultDelta;
                _hasStoredFirstValue    = true;
                return(true);
            }

            int deltaOfDelta = delta - _previousTimestampDelta;

            if (deltaOfDelta == 0)
            {
                _previousTimestamp = timestamp;
                _buffer.AddValue(0, 1);
                return(true);
            }

            if (deltaOfDelta > 0)
            {
                // We don't use zero (its handled above).  Shift down 1 so we fit in X number of bits.
                deltaOfDelta--;
            }

            int absValue = Math.Abs(deltaOfDelta);

            foreach (var timestampEncoding in TimestampEncodingDetails.Encodings)
            {
                if (absValue < timestampEncoding.MaxValueForEncoding)
                {
                    _buffer.AddValue(timestampEncoding.ControlValue, timestampEncoding.ControlValueBitLength);

                    // Make this value between [0, 2^timestampEncodings[i].bitsForValue - 1]
                    long encodedValue = deltaOfDelta + timestampEncoding.MaxValueForEncoding;
                    _buffer.AddValue(encodedValue, timestampEncoding.BitsForValue);

                    break;
                }
            }

            _previousTimestamp      = timestamp;
            _previousTimestampDelta = delta;

            return(true);
        }
Пример #2
0
        /// <summary>
        /// Doubles are encoded by XORing them with the previous value.  If
        /// XORing results in a zero value (value is the same as the previous
        /// value), only a single zero bit is stored, otherwise 1 bit is
        /// stored.
        ///
        /// For non-zero XORred results, there are two choices:
        ///
        /// 1) If the block of meaningful bits falls in between the block of
        ///    previous meaningful bits, i.e., there are at least as many
        ///    leading zeros and as many trailing zeros as with the previous
        ///    value, use that information for the block position and just
        ///    store the XORred value.
        ///
        /// 2) Length of the number of leading zeros is stored in the next 5
        ///    bits, then length of the XORred value is stored in the next 6
        ///    bits and finally the XORred value is stored.
        /// </summary>
        /// <param name="value"></param>
        public void AppendValue(double value)
        {
            long longValue       = BitConverter.DoubleToInt64Bits(value);
            long xorWithPrevious = _previousValue ^ longValue;

            if (xorWithPrevious == 0)
            {
                // It's the same value.
                _buffer.AddValue(0, 1);
                return;
            }

            _buffer.AddValue(1, 1);

            var currentBlockInfo = BlockInfo.CalulcateBlockInfo((ulong)xorWithPrevious);
            int expectedSize     = Constants.LeadingZerosLengthBits + Constants.BlockSizeLengthBits + currentBlockInfo.BlockSize;

            if (currentBlockInfo.LeadingZeros >= _previousBlockInfo.LeadingZeros &&
                currentBlockInfo.TrailingZeros >= _previousBlockInfo.TrailingZeros &&
                _previousBlockInfo.BlockSize < expectedSize)
            {
                // Control bit saying we should use the previous block information
                _buffer.AddValue(1, 1);

                // Write the parts of the value that changed.
                long blockValue = xorWithPrevious >> _previousBlockInfo.TrailingZeros;
                _buffer.AddValue(blockValue, _previousBlockInfo.BlockSize);
            }
            else
            {
                // Control bit saying we need to provide new block information
                _buffer.AddValue(0, 1);

                // Details about the new block information
                _buffer.AddValue(currentBlockInfo.LeadingZeros, Constants.LeadingZerosLengthBits);
                _buffer.AddValue(currentBlockInfo.BlockSize - Constants.BlockSizeAdjustment, Constants.BlockSizeLengthBits);

                // Write the parts of the value that changed.
                long blockValue = xorWithPrevious >> currentBlockInfo.TrailingZeros;
                _buffer.AddValue(blockValue, currentBlockInfo.BlockSize);

                _previousBlockInfo = currentBlockInfo;
            }

            _previousValue = longValue;
        }