Ejemplo n.º 1
0
        public static int GetPadding(TrackingPipeWriter writer, NettraceBlock block)
        {
            // Get padding size
            var offset  = (writer.WrittenCount + sizeof(int)) % 4;
            var padding = (int)((4 - offset) % 4);

            return(padding);
        }
Ejemplo n.º 2
0
 public ValueTask ProcessBlockAsync(NettraceBlock block, CancellationToken token = default)
 {
     if (!_initialized)
     {
         Initialize();
     }
     Debug.Assert(_writer is not null);
     return(new (BlockHelpers.ProcessBlock(_writer, block, token).AsTask()));
 }
Ejemplo n.º 3
0
        public TraceBlock(NettraceBlock block) : this()
        {
            if (!Equals(block.Type.Name, KnownTypeNames.Trace))
            {
                throw new ArgumentException("Requires a Trace block");
            }
            var reader = new SequenceReader <byte>(block.BlockBody);
            var span   = MemoryMarshal.Cast <TraceBlock, byte>(MemoryMarshal.CreateSpan(ref this, 1));

            _ = reader.TryCopyTo(span);
            reader.Advance(span.Length);
        }
Ejemplo n.º 4
0
        private static void WriteBlockBodyPreamble(TrackingPipeWriter writer, NettraceBlock block)
        {
            if (block.Type.Name == KnownTypeNames.Trace)
            {
                return;
            }

            // padding should run before writing block size
            var padding = GetPadding(writer, block);

            // Write block size
            writer.WriteInt(block.Size);
            // Write padding
            Span <byte> span = stackalloc byte[padding];

            writer.Write(span);
        }
Ejemplo n.º 5
0
        public SequencePointBlock(NettraceBlock block)
        {
            if (!Equals(block.Type.Name, KnownTypeNames.SPBlock))
            {
                throw new ArgumentException("Requires a SPBlock");
            }
            var reader = new SequenceReader <byte>(block.BlockBody);

            _       = reader.TryReadLittleEndian(out Timestamp);
            _       = reader.TryReadLittleEndian(out ThreadCount);
            Threads = new SequencePointThread[ThreadCount];
            for (int i = 0; i < Threads.Length; i++)
            {
                var span = MemoryMarshal.Cast <SequencePointThread, byte>(MemoryMarshal.CreateSpan(ref Threads[i], 1));
                _ = reader.TryCopyTo(span);
                reader.Advance(span.Length);
            }
        }
Ejemplo n.º 6
0
        public static bool WriteBlockAndPreamble(TrackingPipeWriter writer, NettraceBlock block)
        {
            if (block.Type.Name != KnownTypeNames.EventBlockCompressed && block.Type.Name != KnownTypeNames.StackBlockCompressed)
            {
                return(false);
            }

            var padding      = BlockHelpers.GetPadding(writer, block);
            var prefixLength = padding + sizeof(int);

            using var decoder = new BrotliDecoder();

            var source = ArrayPool <byte> .Shared.Rent((int)block.BlockBody.Length);

            block.BlockBody.CopyTo(source);
            var           written = 0;
            Memory <byte> memory;

            try
            {
                var length = prefixLength + (int)block.BlockBody.Length;
                memory = writer.GetMemory(length);
                while (!BrotliDecoder.TryDecompress(source.AsSpan(0, (int)block.BlockBody.Length), memory.Slice(prefixLength).Span, out written))
                {
                    length = memory.Length * 2;
                    memory = writer.GetMemory(length);
                }
            }
            finally
            {
                ArrayPool <byte> .Shared.Return(source);
            }

            // Write size
            BitConverter.TryWriteBytes(memory.Span, written);
            // clear padding bits
            memory.Slice(sizeof(int), padding).Span.Clear();
            writer.Advance(written + prefixLength);

            return(true);
        }
Ejemplo n.º 7
0
        public static bool WriteBlockAndPreamble(TrackingPipeWriter writer, NettraceBlock block)
        {
            if (block.Type.Name != KnownTypeNames.EventBlock && block.Type.Name != KnownTypeNames.StackBlock)
            {
                return(false);
            }

            var blockSequence = block.BlockBody;
            var maxLength     = BrotliEncoder.GetMaxCompressedLength((int)blockSequence.Length);
            var padding       = BlockHelpers.GetPadding(writer !, block);
            var prefixLength  = padding + sizeof(int);
            var memory        = writer !.GetMemory(maxLength + prefixLength);

            // clear padding bits
            memory.Slice(0, prefixLength).Span.Clear();
            using var encoder = new BrotliEncoder(quality: 9, window: 10);

            var             slicedMemory = memory.Slice(prefixLength);
            var             totalWritten = 0;
            OperationStatus status;

            foreach (var sequence in blockSequence)
            {
                status = encoder.Compress(sequence.Span, slicedMemory.Span, out var consumed, out var written, false);
                Debug.Assert(consumed == sequence.Span.Length);
                Debug.Assert(status == OperationStatus.Done);
                slicedMemory  = slicedMemory.Slice(written);
                totalWritten += written;
            }
            status = encoder.Compress(ReadOnlySpan <byte> .Empty, slicedMemory.Span, out var _, out var written2, true);
            Debug.Assert(status == OperationStatus.Done);
            totalWritten += written2;

            // Write size
            BitConverter.TryWriteBytes(memory.Span, totalWritten);
            writer.Advance(totalWritten + prefixLength);

            return(true);
        }
Ejemplo n.º 8
0
        public static ValueTask <FlushResult> ProcessBlock(TrackingPipeWriter writer, NettraceBlock block, CancellationToken token)
        {
            // Write opening tag
            writer.WriteByte((byte)Tags.BeginPrivateObject);

            WriteBlockHeader(writer, block.Type);

            var written = compress && CompressBlockHelper.WriteBlockAndPreamble(writer, block);

            if (!written)
            {
                written = decompress && DecompressBlockHelper.WriteBlockAndPreamble(writer, block);
            }
            if (!written)
            {
                WriteBlockBodyPreamble(writer, block);

                WriteBlockBody(writer, block.BlockBody);
            }

            // Write closing tag
            writer.WriteByte((byte)Tags.EndObject);

            return(writer.FlushAsync(token));
        }