示例#1
0
            private int ReadTimeStamp(BitsBuffer bitsBuffer)
            {
                if (_bitsPosisition == 0)
                {
                    _previousTimeStamp      = (int)bitsBuffer.ReadValue(ref _bitsPosisition, BitsForFirstTimestamp);
                    _previousTimeStampDelta = DefaultDelta;
                    return(_previousTimeStamp);
                }

                var type = bitsBuffer.FindTheFirstZeroBit(ref _bitsPosisition, TimestampEncodingDetails.MaxControlBitLength);

                if (type > 0)
                {
                    var     index        = type - 1;
                    ref var encoding     = ref TimestampEncodingDetails.Encodings[index];
                    long    decodedValue = (long)bitsBuffer.ReadValue(ref _bitsPosisition, encoding.BitsForValue);
                    // [0, 255] becomes [-128, 127]
                    decodedValue -= encoding.MaxValueForEncoding;
                    if (decodedValue >= 0)
                    {
                        // [-128, 127] becomes [-128, 128] without the zero in the middle
                        decodedValue++;
                    }
                    _previousTimeStampDelta += (int)decodedValue;
                }
示例#2
0
            private void ReadValues(Span <StatefulTimeStampValue> values, ref BitsBuffer bitsBuffer)
            {
                for (int i = 0; i < values.Length; i++)
                {
                    var nonZero = bitsBuffer.ReadValue(ref _bitsPosisition, 1);
                    if (nonZero == 0)
                    {
                        continue; // no change since last time
                    }
                    var  usePreviousBlockInfo = bitsBuffer.ReadValue(ref _bitsPosisition, 1);
                    long xorValue;

                    if (usePreviousBlockInfo == 1)
                    {
                        xorValue   = (long)bitsBuffer.ReadValue(ref _bitsPosisition, 64 - values[i].LeadingZeroes - values[i].TrailingZeroes);
                        xorValue <<= values[i].TrailingZeroes;
                    }
                    else
                    {
                        int leadingZeros  = (int)bitsBuffer.ReadValue(ref _bitsPosisition, LeadingZerosLengthBits);
                        int blockSize     = (int)bitsBuffer.ReadValue(ref _bitsPosisition, BlockSizeLengthBits) + BlockSizeAdjustment;
                        int trailingZeros = 64 - blockSize - leadingZeros;

                        xorValue   = (long)bitsBuffer.ReadValue(ref _bitsPosisition, blockSize);
                        xorValue <<= trailingZeros;

                        values[i].TrailingZeroes = (byte)trailingZeros;
                        values[i].LeadingZeroes  = (byte)leadingZeros;
                    }

                    values[i].LongValue = values[i].LongValue ^ xorValue;
                }
            }
示例#3
0
        private static void AddValue(ref StatefulTimeStampValue prev, ref BitsBuffer bitsBuffer, double dblVal)
        {
            long  val             = BitConverter.DoubleToInt64Bits(dblVal);
            ulong xorWithPrevious = (ulong)(prev.LongValue ^ val);

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

            bitsBuffer.AddValue(1, 1);

            var leadingZeroes  = Bits.LeadingZeroes(xorWithPrevious);
            var trailingZeroes = Bits.TrailingZeroesInBytes(xorWithPrevious);

            if (leadingZeroes > MaxLeadingZerosLength)
            {
                leadingZeroes = MaxLeadingZerosLength;
            }

            var useful     = 64 - leadingZeroes - trailingZeroes;
            var prevUseful = 64 - prev.LeadingZeroes - prev.TrailingZeroes;

            var expectedSize = LeadingZerosLengthBits + BlockSizeLengthBits + useful;

            if (leadingZeroes >= prev.LeadingZeroes &&
                trailingZeroes >= prev.TrailingZeroes &&
                prevUseful < expectedSize)
            {
                // Control bit saying we should use the previous block information
                bitsBuffer.AddValue(1, 1);

                // Write the parts of the value that changed.
                ulong blockValue = xorWithPrevious >> prev.TrailingZeroes;
                bitsBuffer.AddValue(blockValue, prevUseful);
            }
            else
            {
                bitsBuffer.AddValue(0, 1);
                bitsBuffer.AddValue((ulong)leadingZeroes, LeadingZerosLengthBits);
                bitsBuffer.AddValue((ulong)(useful - BlockSizeAdjustment), BlockSizeLengthBits);
                ulong blockValue = xorWithPrevious >> trailingZeroes;
                bitsBuffer.AddValue(blockValue, useful);
                prev.LeadingZeroes  = (byte)leadingZeroes;
                prev.TrailingZeroes = (byte)trailingZeroes;
            }
            prev.DoubleValue = dblVal;
        }
示例#4
0
        public bool Append(int deltaFromStart, Span <double> vals, Span <byte> tag)
        {
            if (vals.Length != Header->NumberOfValues)
            {
                ThrowInvalidNumberOfValues(vals);
            }

            var actualBitsBuffer = GetBitsBuffer();

            var maximumSize =
                sizeof(BitsBufferHeader) +
                sizeof(int) + // max timestamp
                sizeof(double) * vals.Length +
                tag.Length + 1 +
                1 + // alignment to current buffer
                8;  // extra buffer that should never be used
            var tempBuffer = stackalloc byte[maximumSize];
            var tempHeader = stackalloc SegmentHeader[1];

            *tempHeader = *Header;

            var tempBitsBuffer = new BitsBuffer(tempBuffer, maximumSize);

            var prevs = new Span <StatefulTimeStampValue>(_buffer + sizeof(SegmentHeader), Header->NumberOfValues);

            AddTimeStamp(deltaFromStart, ref tempBitsBuffer, tempHeader);

            for (int i = 0; i < vals.Length; i++)
            {
                AddValue(ref prevs[i], ref tempBitsBuffer, vals[i]);
            }

            WriteTag(tag, ref tempBitsBuffer, tempHeader, actualBitsBuffer.NumberOfBits);

            Debug.Assert(tempBitsBuffer.NumberOfBits / 8 < maximumSize - 8, "Wrote PAST END OF BUFFER!");

            tempHeader->PreviousTimeStamp = deltaFromStart;
            tempHeader->NumberOfEntries++;

            if (actualBitsBuffer.AddBits(tempBitsBuffer) == false)
            {
                return(false);
            }

            *Header = *tempHeader;

            return(true);
        }
示例#5
0
        internal bool AddBits(BitsBuffer tempBitsBuffer)
        {
            if (HasAdditionalBits(tempBitsBuffer.NumberOfBits) == false)
            {
                return(false);
            }

            int read = 0;

            while (read < tempBitsBuffer.NumberOfBits)
            {
                var toRead = Math.Min(64, tempBitsBuffer.NumberOfBits - read);
                var result = tempBitsBuffer.ReadValue(ref read, toRead);
                AddValue(result, toRead);
            }

            return(true);
        }
示例#6
0
        private static void AddTimeStamp(int deltaFromStart, ref BitsBuffer bitsBuffer, SegmentHeader *tempHeader)
        {
            if (tempHeader->NumberOfEntries == 0)
            {
                bitsBuffer.AddValue((ulong)deltaFromStart, BitsForFirstTimestamp);
                tempHeader->PreviousDelta = DefaultDelta;
                return;
            }

            int delta        = deltaFromStart - tempHeader->PreviousTimeStamp;
            int deltaOfDelta = delta - tempHeader->PreviousDelta;

            if (deltaOfDelta == 0)
            {
                bitsBuffer.AddValue(0, 1);
                return;
            }
            if (deltaOfDelta > 0)
            {
                // There are no zeros. Shift by one to fit in x number of bits
                deltaOfDelta--;
            }

            int absValue = Math.Abs(deltaOfDelta);

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

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

                    break;
                }
            }
            tempHeader->PreviousTimeStamp = deltaFromStart;
            tempHeader->PreviousDelta     = delta;
        }
示例#7
0
 public TagEnumerator(BitsBuffer bitsBuffer, int previousTagPos)
 {
     _bitsBuffer     = bitsBuffer;
     _previousTagPos = previousTagPos;
 }
示例#8
0
        private void WriteTag(Span <byte> tag, ref BitsBuffer tempBitsBuffer, SegmentHeader *tempHeader, int baseNumberOfBits)
        {
            if (tag.Length > byte.MaxValue)
            {
                ThrowInvalidTagLength();
            }

            var actualBitsBuffer = GetBitsBuffer();
            int a       = 136;
            var r       = actualBitsBuffer.ReadValue(ref a, 11);
            var tagEnum = new TagEnumerator(actualBitsBuffer /* need to read the previous values */,
                                            tempHeader->PreviousTagPosition);

            if (tagEnum.TryGetPrevious(out var prevTag, out var previousIndex))
            {
                if (prevTag.SequenceEqual(tag))
                {
                    tempBitsBuffer.AddValue(0, 1); // reuse previous buffer
                    return;
                }
                // go back a maximum of 8 tags, to avoid N**2 operations
                // after 8 tags, we'll just write the tag again
                for (int i = 0; i < 8; i++)
                {
                    if (tagEnum.TryGetPrevious(out prevTag, out previousIndex) == false)
                    {
                        break;
                    }
                    if (prevTag.SequenceEqual(tag))
                    {
                        tempBitsBuffer.AddValue(1, 1);
                        tempBitsBuffer.AddValue((ulong)previousIndex, BitsForTagLen);
                        if (previousIndex != 0)
                        {
                            // re-arrange the previous pointer for the previous value
                            // to point to the current one
                            actualBitsBuffer.SetBits(
                                (previousIndex + 1 + tag.Length) * 8,
                                tempHeader->PreviousTagPosition,
                                BitsForTagLen
                                );
                            tempHeader->PreviousTagPosition = (ushort)previousIndex;
                        }
                        return;
                    }
                }
            }
            tempBitsBuffer.AddValue(1, 1);

            int currentBitPosition = baseNumberOfBits + tempBitsBuffer.NumberOfBits + BitsForTagLen;
            int currentTagPosition = GetByteIndex(currentBitPosition);
            var bitsToSkip         = ToByteAlignment(currentBitPosition);

            tempBitsBuffer.AddValue((ulong)currentTagPosition, BitsForTagLen);


            tempBitsBuffer.Header->BitsPosition += (ushort)bitsToSkip;

            tempBitsBuffer.AddValue((ulong)tag.Length, 8);
            for (int i = 0; i < tag.Length; i++)
            {
                tempBitsBuffer.AddValue(tag[i], 8);
            }
            tempBitsBuffer.AddValue(tempHeader->PreviousTagPosition, BitsForTagLen);
            tempHeader->PreviousTagPosition = (ushort)(currentTagPosition);
        }