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; }
private int GetNumberOfBytes(SegmentHeader *header) { var bitsHeader = GetBitsBuffer(Header); return(bitsHeader.NumberOfBytes + GetDataStart(Header)); }
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); }