Browse Source

Sync aspnetcore-corert with aspnetcore (#5614)

Mostly applies changes from #5579.
Michal Strehovský 5 years ago
parent
commit
6433a2bbc2

+ 10 - 0
frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/AsciiString.cs

@@ -12,6 +12,8 @@ namespace PlatformBenchmarks
 
 
         public AsciiString(string s) => _data = Encoding.ASCII.GetBytes(s);
         public AsciiString(string s) => _data = Encoding.ASCII.GetBytes(s);
 
 
+        private AsciiString(byte[] b) => _data = b;
+
         public int Length => _data.Length;
         public int Length => _data.Length;
 
 
         public ReadOnlySpan<byte> AsSpan() => _data;
         public ReadOnlySpan<byte> AsSpan() => _data;
@@ -31,6 +33,14 @@ namespace PlatformBenchmarks
         public static bool operator !=(AsciiString a, AsciiString b) => !a.Equals(b);
         public static bool operator !=(AsciiString a, AsciiString b) => !a.Equals(b);
         public override bool Equals(object other) => (other is AsciiString) && Equals((AsciiString)other);
         public override bool Equals(object other) => (other is AsciiString) && Equals((AsciiString)other);
 
 
+        public static AsciiString operator +(AsciiString a, AsciiString b)
+        {
+            var result = new byte[a.Length + b.Length];
+            a._data.CopyTo(result, 0);
+            b._data.CopyTo(result, a.Length);
+            return new AsciiString(result);
+        }
+
         public override int GetHashCode()
         public override int GetHashCode()
         {
         {
             // Copied from x64 version of string.GetLegacyNonRandomizedHashCode()
             // Copied from x64 version of string.GetLegacyNonRandomizedHashCode()

+ 87 - 17
frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/BenchmarkApplication.HttpConnection.cs

@@ -48,23 +48,67 @@ namespace PlatformBenchmarks
             return HtmlEncoder.Create(settings);
             return HtmlEncoder.Create(settings);
         }
         }
 
 
+#if !DATABASE
         private async Task ProcessRequestsAsync()
         private async Task ProcessRequestsAsync()
         {
         {
             while (true)
             while (true)
             {
             {
-                var task = Reader.ReadAsync();
+                var readResult = await Reader.ReadAsync();
 
 
-                if (!task.IsCompleted)
+                if (!HandleRequest(readResult))
                 {
                 {
-                    // No more data in the input
-                    await OnReadCompletedAsync();
+                    return;
                 }
                 }
 
 
-                var result = await task;
-                var buffer = result.Buffer;
+                await Writer.FlushAsync();
+            }
+        }
+
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        private bool HandleRequest(in ReadResult result)
+        {
+            var buffer = result.Buffer;
+            var writer = GetWriter(Writer);
+
+            while (true)
+            {
+                if (!ParseHttpRequest(ref buffer, result.IsCompleted, out var examined))
+                {
+                    return false;
+                }
+
+                if (_state == State.Body)
+                {
+                    ProcessRequest(ref writer);
+
+                    _state = State.StartLine;
+
+                    if (!buffer.IsEmpty)
+                    {
+                        // More input data to parse
+                        continue;
+                    }
+                }
+
+                // No more input or incomplete data, Advance the Reader
+                Reader.AdvanceTo(buffer.Start, examined);
+                break;
+            }
+
+            writer.Commit();
+            return true;
+        }
+#else
+        private async Task ProcessRequestsAsync()
+        {
+            while (true)
+            {
+                var readResult = await Reader.ReadAsync();
+
+                var buffer = readResult.Buffer;
                 while (true)
                 while (true)
                 {
                 {
-                    if (!ParseHttpRequest(ref buffer, result.IsCompleted, out var examined))
+                    if (!ParseHttpRequest(ref buffer, readResult.IsCompleted, out var examined))
                     {
                     {
                         return;
                         return;
                     }
                     }
@@ -86,18 +130,19 @@ namespace PlatformBenchmarks
                     Reader.AdvanceTo(buffer.Start, examined);
                     Reader.AdvanceTo(buffer.Start, examined);
                     break;
                     break;
                 }
                 }
+
+                await Writer.FlushAsync();
             }
             }
         }
         }
-
+#endif
         private bool ParseHttpRequest(ref ReadOnlySequence<byte> buffer, bool isCompleted, out SequencePosition examined)
         private bool ParseHttpRequest(ref ReadOnlySequence<byte> buffer, bool isCompleted, out SequencePosition examined)
         {
         {
             examined = buffer.End;
             examined = buffer.End;
-
-            var consumed = buffer.Start;
             var state = _state;
             var state = _state;
 
 
             if (!buffer.IsEmpty)
             if (!buffer.IsEmpty)
             {
             {
+                SequencePosition consumed;
                 if (state == State.StartLine)
                 if (state == State.StartLine)
                 {
                 {
                     if (Parser.ParseRequestLine(new ParsingAdapter(this), buffer, out consumed, out examined))
                     if (Parser.ParseRequestLine(new ParsingAdapter(this), buffer, out consumed, out examined))
@@ -141,18 +186,30 @@ namespace PlatformBenchmarks
             return true;
             return true;
         }
         }
 
 
-        public void OnHeader(Span<byte> name, Span<byte> value)
+#if NETCOREAPP5_0
+
+        public void OnStaticIndexedHeader(int index)
         {
         {
         }
         }
 
 
-        public void OnHeadersComplete()
+        public void OnStaticIndexedHeader(int index, ReadOnlySpan<byte> value)
         {
         {
         }
         }
 
 
-        public async ValueTask OnReadCompletedAsync()
+        public void OnHeader(ReadOnlySpan<byte> name, ReadOnlySpan<byte> value)
+        {
+        }
+        public void OnHeadersComplete(bool endStream)
+        {
+        }
+#else
+        public void OnHeader(Span<byte> name, Span<byte> value)
         {
         {
-            await Writer.FlushAsync();
         }
         }
+        public void OnHeadersComplete()
+        {
+        }
+#endif
 
 
         private static void ThrowUnexpectedEndOfData()
         private static void ThrowUnexpectedEndOfData()
         {
         {
@@ -194,14 +251,27 @@ namespace PlatformBenchmarks
             public ParsingAdapter(BenchmarkApplication requestHandler)
             public ParsingAdapter(BenchmarkApplication requestHandler)
                 => RequestHandler = requestHandler;
                 => RequestHandler = requestHandler;
 
 
+#if NETCOREAPP5_0
+            public void OnStaticIndexedHeader(int index) 
+                => RequestHandler.OnStaticIndexedHeader(index);
+
+            public void OnStaticIndexedHeader(int index, ReadOnlySpan<byte> value)
+                => RequestHandler.OnStaticIndexedHeader(index, value);
+
+            public void OnHeader(ReadOnlySpan<byte> name, ReadOnlySpan<byte> value)
+                => RequestHandler.OnHeader(name, value);
+
+            public void OnHeadersComplete(bool endStream)
+                => RequestHandler.OnHeadersComplete(endStream);
+#else
             public void OnHeader(Span<byte> name, Span<byte> value)
             public void OnHeader(Span<byte> name, Span<byte> value)
                 => RequestHandler.OnHeader(name, value);
                 => RequestHandler.OnHeader(name, value);
+            public void OnHeadersComplete()
+                => RequestHandler.OnHeadersComplete();
+#endif
 
 
             public void OnStartLine(HttpMethod method, HttpVersion version, Span<byte> target, Span<byte> path, Span<byte> query, Span<byte> customMethod, bool pathEncoded)
             public void OnStartLine(HttpMethod method, HttpVersion version, Span<byte> target, Span<byte> path, Span<byte> query, Span<byte> customMethod, bool pathEncoded)
                 => RequestHandler.OnStartLine(method, version, target, path, query, customMethod, pathEncoded);
                 => RequestHandler.OnStartLine(method, version, target, path, query, customMethod, pathEncoded);
-
-            public void OnHeadersComplete()
-                => RequestHandler.OnHeadersComplete();
         }
         }
     }
     }
 }
 }

+ 11 - 21
frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/BenchmarkApplication.Json.cs

@@ -1,41 +1,31 @@
 // Copyright (c) .NET Foundation. All rights reserved.
 // Copyright (c) .NET Foundation. All rights reserved.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 
-using System.IO.Pipelines;
-using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
 using Utf8Json;
 using Utf8Json;
 
 
 namespace PlatformBenchmarks
 namespace PlatformBenchmarks
 {
 {
     public partial class BenchmarkApplication
     public partial class BenchmarkApplication
     {
     {
-        private static void Json(PipeWriter pipeWriter)
-        {
-            var writer = GetWriter(pipeWriter);
+        private static readonly uint _jsonPayloadSize = (uint)JsonSerializer.SerializeUnsafe(new JsonMessage { message = "Hello, World!" }).Count;
 
 
-            // HTTP 1.1 OK
-            writer.Write(_http11OK);
+        private readonly static AsciiString _jsonPreamble =
+            _http11OK +
+            _headerServer + _crlf +
+            _headerContentTypeJson + _crlf +
+            _headerContentLength + _jsonPayloadSize.ToString();
 
 
-            // Server headers
-            writer.Write(_headerServer);
+        private static void Json(ref BufferWriter<WriterAdapter> writer)
+        {
+            writer.Write(_jsonPreamble);
 
 
             // Date header
             // Date header
-            writer.Write(DateHeader.HeaderBytes);
+            writer.Write(DateHeader.HeaderBytes);            
 
 
-            // Content-Type header
-            writer.Write(_headerContentTypeJson);
+            writer.Commit();
 
 
-            // Content-Length header
-            writer.Write(_headerContentLength);
             var jsonPayload = JsonSerializer.SerializeUnsafe(new JsonMessage { message = "Hello, World!" });
             var jsonPayload = JsonSerializer.SerializeUnsafe(new JsonMessage { message = "Hello, World!" });
-            writer.WriteNumeric((uint)jsonPayload.Count);
-
-            // End of headers
-            writer.Write(_eoh);
-
-            // Body
             writer.Write(jsonPayload);
             writer.Write(jsonPayload);
-            writer.Commit();
         }
         }
     }
     }
 }
 }

+ 8 - 22
frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/BenchmarkApplication.Plaintext.cs

@@ -1,39 +1,25 @@
 // Copyright (c) .NET Foundation. All rights reserved.
 // Copyright (c) .NET Foundation. All rights reserved.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 
-using System.IO.Pipelines;
-using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
-
 namespace PlatformBenchmarks
 namespace PlatformBenchmarks
 {
 {
     public partial class BenchmarkApplication
     public partial class BenchmarkApplication
     {
     {
-        private static void PlainText(PipeWriter pipeWriter)
-        {
-            var writer = GetWriter(pipeWriter);
+        private readonly static AsciiString _plaintextPreamble =
+            _http11OK +
+            _headerServer + _crlf +
+            _headerContentTypeText + _crlf +
+            _headerContentLength + _plainTextBody.Length.ToString();
 
 
-            // HTTP 1.1 OK
-            writer.Write(_http11OK);
-
-            // Server headers
-            writer.Write(_headerServer);
+        private static void PlainText(ref BufferWriter<WriterAdapter> writer)
+        {
+            writer.Write(_plaintextPreamble);
 
 
             // Date header
             // Date header
             writer.Write(DateHeader.HeaderBytes);
             writer.Write(DateHeader.HeaderBytes);
 
 
-            // Content-Type header
-            writer.Write(_headerContentTypeText);
-
-            // Content-Length header
-            writer.Write(_headerContentLength);
-            writer.WriteNumeric((uint)_plainTextBody.Length);
-
-            // End of headers
-            writer.Write(_eoh);
-
             // Body
             // Body
             writer.Write(_plainTextBody);
             writer.Write(_plainTextBody);
-            writer.Commit();
         }
         }
     }
     }
 }
 }

+ 90 - 39
frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/BenchmarkApplication.cs

@@ -17,12 +17,18 @@ namespace PlatformBenchmarks
         private readonly static AsciiString _crlf = "\r\n";
         private readonly static AsciiString _crlf = "\r\n";
         private readonly static AsciiString _eoh = "\r\n\r\n"; // End Of Headers
         private readonly static AsciiString _eoh = "\r\n\r\n"; // End Of Headers
         private readonly static AsciiString _http11OK = "HTTP/1.1 200 OK\r\n";
         private readonly static AsciiString _http11OK = "HTTP/1.1 200 OK\r\n";
-        private readonly static AsciiString _headerServer = "Server: Custom";
+        private readonly static AsciiString _headerServer = "Server: K";
         private readonly static AsciiString _headerContentLength = "Content-Length: ";
         private readonly static AsciiString _headerContentLength = "Content-Length: ";
-        private readonly static AsciiString _headerContentLengthZero = "Content-Length: 0\r\n";
-        private readonly static AsciiString _headerContentTypeText = "Content-Type: text/plain\r\n";
-        private readonly static AsciiString _headerContentTypeJson = "Content-Type: application/json\r\n";
-        private readonly static AsciiString _headerContentTypeHtml = "Content-Type: text/html; charset=UTF-8\r\n";
+        private readonly static AsciiString _headerContentLengthZero = "Content-Length: 0";
+        private readonly static AsciiString _headerContentTypeText = "Content-Type: text/plain";
+        private readonly static AsciiString _headerContentTypeJson = "Content-Type: application/json";
+        private readonly static AsciiString _headerContentTypeHtml = "Content-Type: text/html; charset=UTF-8";
+
+        private readonly static AsciiString _dbPreamble =
+            _http11OK +
+            _headerServer + _crlf +
+            _headerContentTypeJson + _crlf +
+            _headerContentLength;
 
 
         private readonly static AsciiString _plainTextBody = "Hello, World!";
         private readonly static AsciiString _plainTextBody = "Hello, World!";
 
 
@@ -33,53 +39,88 @@ namespace PlatformBenchmarks
         private readonly static AsciiString _fortunesTableEnd = "</table></body></html>";
         private readonly static AsciiString _fortunesTableEnd = "</table></body></html>";
         private readonly static AsciiString _contentLengthGap = new string(' ', 4);
         private readonly static AsciiString _contentLengthGap = new string(' ', 4);
 
 
+#if DATABASE
+        public static RawDb Db { get; set; }
+#endif
+
         public static class Paths
         public static class Paths
         {
         {
             public readonly static AsciiString SingleQuery = "/db";
             public readonly static AsciiString SingleQuery = "/db";
-            public readonly static AsciiString Json = "/json";
+            public readonly static AsciiString Json = "/j";
             public readonly static AsciiString Fortunes = "/fortunes";
             public readonly static AsciiString Fortunes = "/fortunes";
-            public readonly static AsciiString Plaintext = "/plaintext";
+            public readonly static AsciiString Plaintext = "/p";
             public readonly static AsciiString Updates = "/updates/queries=";
             public readonly static AsciiString Updates = "/updates/queries=";
+            public readonly static AsciiString MultipleQueries = "/queries/queries=";
         }
         }
 
 
         private RequestType _requestType;
         private RequestType _requestType;
+#if DATABASE
         private int _queries;
         private int _queries;
-
+#endif
         public void OnStartLine(HttpMethod method, HttpVersion version, Span<byte> target, Span<byte> path, Span<byte> query, Span<byte> customMethod, bool pathEncoded)
         public void OnStartLine(HttpMethod method, HttpVersion version, Span<byte> target, Span<byte> path, Span<byte> query, Span<byte> customMethod, bool pathEncoded)
         {
         {
             var requestType = RequestType.NotRecognized;
             var requestType = RequestType.NotRecognized;
             if (method == HttpMethod.Get)
             if (method == HttpMethod.Get)
             {
             {
+#if !DATABASE
+                if (path.Length >= 2 && path[0] == '/')
+                {
+                    if (path[1] == 'j')
+                    {
+                        requestType = RequestType.Json;
+                    }
+                    else if (path[1] == 'p')
+                    {
+                        requestType = RequestType.PlainText;
+                    }
+                }
+#else
                 var pathLength = path.Length;
                 var pathLength = path.Length;
                 if (Paths.SingleQuery.Length <= pathLength && path.StartsWith(Paths.SingleQuery))
                 if (Paths.SingleQuery.Length <= pathLength && path.StartsWith(Paths.SingleQuery))
                 {
                 {
                     requestType = RequestType.SingleQuery;
                     requestType = RequestType.SingleQuery;
                 }
                 }
-                else if (Paths.Json.Length <= pathLength && path.StartsWith(Paths.Json))
-                {
-                    requestType = RequestType.Json;
-                }
                 else if (Paths.Fortunes.Length <= pathLength && path.StartsWith(Paths.Fortunes))
                 else if (Paths.Fortunes.Length <= pathLength && path.StartsWith(Paths.Fortunes))
                 {
                 {
                     requestType = RequestType.Fortunes;
                     requestType = RequestType.Fortunes;
                 }
                 }
-                else if (Paths.Plaintext.Length <= pathLength && path.StartsWith(Paths.Plaintext))
-                {
-                    requestType = RequestType.PlainText;
-                }
                 else if (Paths.Updates.Length <= pathLength && path.StartsWith(Paths.Updates))
                 else if (Paths.Updates.Length <= pathLength && path.StartsWith(Paths.Updates))
                 {
                 {
-                    _queries = ParseQueries(path);
+                    _queries = ParseQueries(path, Paths.Updates.Length);
                     requestType = RequestType.Updates;
                     requestType = RequestType.Updates;
                 }
                 }
+                else if (Paths.MultipleQueries.Length <= pathLength && path.StartsWith(Paths.MultipleQueries))
+                {
+                    _queries = ParseQueries(path, Paths.MultipleQueries.Length);
+                    requestType = RequestType.MultipleQueries;
+                }
+#endif
             }
             }
 
 
             _requestType = requestType;
             _requestType = requestType;
         }
         }
 
 
-        private static int ParseQueries(Span<byte> path)
+
+#if !DATABASE
+        private void ProcessRequest(ref BufferWriter<WriterAdapter> writer)
         {
         {
-            if (!Utf8Parser.TryParse(path.Slice(Paths.Updates.Length), out int queries, out _) || queries < 1)
+            if (_requestType == RequestType.PlainText)
+            {
+                PlainText(ref writer);
+            }
+            else if (_requestType == RequestType.Json)
+            {
+                Json(ref writer);
+            }
+            else
+            {
+                Default(ref writer);
+            }
+        }
+#else
+        private static int ParseQueries(Span<byte> path, int pathLength)
+        {
+            if (!Utf8Parser.TryParse(path.Slice(pathLength), out int queries, out _) || queries < 1)
             {
             {
                 queries = 1;
                 queries = 1;
             }
             }
@@ -91,21 +132,30 @@ namespace PlatformBenchmarks
             return queries;
             return queries;
         }
         }
 
 
-        public Task ProcessRequestAsync()
+        private Task ProcessRequestAsync()
         {
         {
+            Task task;
             var requestType = _requestType;
             var requestType = _requestType;
-            var task = Task.CompletedTask;
-            if (requestType == RequestType.PlainText)
+            if (requestType == RequestType.Fortunes)
+            {
+                task = Fortunes(Writer);
+            }
+            else if (requestType == RequestType.SingleQuery)
+            {
+                task = SingleQuery(Writer);
+            }
+            else if (requestType == RequestType.Updates)
             {
             {
-                PlainText(Writer);
+                task = Updates(Writer, _queries);
             }
             }
-            else if (requestType == RequestType.Json)
+            else if (requestType == RequestType.MultipleQueries)
             {
             {
-                Json(Writer);
+                task = MultipleQueries(Writer, _queries);
             }
             }
             else
             else
             {
             {
                 Default(Writer);
                 Default(Writer);
+                task = Task.CompletedTask;
             }
             }
 
 
             return task;
             return task;
@@ -114,22 +164,22 @@ namespace PlatformBenchmarks
         private static void Default(PipeWriter pipeWriter)
         private static void Default(PipeWriter pipeWriter)
         {
         {
             var writer = GetWriter(pipeWriter);
             var writer = GetWriter(pipeWriter);
-
-            // HTTP 1.1 OK
-            writer.Write(_http11OK);
-
-            // Server headers
-            writer.Write(_headerServer);
+            Default(ref writer);
+            writer.Commit();
+        }
+#endif
+        private readonly static AsciiString _defaultPreamble =
+            _http11OK +
+            _headerServer + _crlf +
+            _headerContentTypeText + _crlf +
+            _headerContentLengthZero;
+
+        private static void Default(ref BufferWriter<WriterAdapter> writer)
+        {
+            writer.Write(_defaultPreamble);
 
 
             // Date header
             // Date header
             writer.Write(DateHeader.HeaderBytes);
             writer.Write(DateHeader.HeaderBytes);
-
-            // Content-Length 0
-            writer.Write(_headerContentLengthZero);
-
-            // End of headers
-            writer.Write(_crlf);
-            writer.Commit();
         }
         }
 
 
         private enum RequestType
         private enum RequestType
@@ -139,7 +189,8 @@ namespace PlatformBenchmarks
             Json,
             Json,
             Fortunes,
             Fortunes,
             SingleQuery,
             SingleQuery,
-            Updates
+            Updates,
+            MultipleQueries
         }
         }
     }
     }
 }
 }

+ 3 - 3
frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/BenchmarkConfigurationHelpers.cs

@@ -23,8 +23,8 @@ namespace PlatformBenchmarks
             var threadCountRaw = builder.GetSetting("threadCount");
             var threadCountRaw = builder.GetSetting("threadCount");
             int? theadCount = null;
             int? theadCount = null;
 
 
-            if (!string.IsNullOrEmpty(threadCountRaw) && 
-                Int32.TryParse(threadCountRaw, out var value))
+            if (!string.IsNullOrEmpty(threadCountRaw) &&
+                int.TryParse(threadCountRaw, out var value))
             {
             {
                 theadCount = value;
                 theadCount = value;
             }
             }
@@ -49,7 +49,7 @@ namespace PlatformBenchmarks
 
 
             return builder;
             return builder;
         }
         }
-        
+
         public static IPEndPoint CreateIPEndPoint(this IConfiguration config)
         public static IPEndPoint CreateIPEndPoint(this IConfiguration config)
         {
         {
             var url = config["server.urls"] ?? config["urls"];
             var url = config["server.urls"] ?? config["urls"];

+ 0 - 2
frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/BufferExtensions.cs

@@ -3,9 +3,7 @@
 
 
 using System;
 using System;
 using System.Buffers;
 using System.Buffers;
-using System.Buffers.Text;
 using System.Runtime.CompilerServices;
 using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
 using System.Text;
 using System.Text;
 
 
 namespace PlatformBenchmarks
 namespace PlatformBenchmarks

+ 3 - 1
frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/BufferWriter.cs

@@ -17,13 +17,15 @@ namespace PlatformBenchmarks
         {
         {
             _buffered = 0;
             _buffered = 0;
             _output = output;
             _output = output;
-            _span = output.GetSpan();
+            _span = output.GetSpan(sizeHint: 16 * 160);
         }
         }
 
 
         public Span<byte> Span => _span;
         public Span<byte> Span => _span;
 
 
         public int Buffered => _buffered;
         public int Buffered => _buffered;
 
 
+        public T Output => _output;
+
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         public void Commit()
         public void Commit()
         {
         {

+ 9 - 3
frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/DateHeader.cs

@@ -23,18 +23,24 @@ namespace PlatformBenchmarks
             SetDateValues(DateTimeOffset.UtcNow);
             SetDateValues(DateTimeOffset.UtcNow);
         }, null, 1000, 1000);
         }, null, 1000, 1000);
 
 
-        private static byte[] s_headerBytesMaster = new byte[prefixLength + dateTimeRLength + suffixLength];
-        private static byte[] s_headerBytesScratch = new byte[prefixLength + dateTimeRLength + suffixLength];
+        private static byte[] s_headerBytesMaster = new byte[prefixLength + dateTimeRLength + 2 * suffixLength];
+        private static byte[] s_headerBytesScratch = new byte[prefixLength + dateTimeRLength + 2 * suffixLength];
 
 
         static DateHeader()
         static DateHeader()
         {
         {
             var utf8 = Encoding.ASCII.GetBytes("\r\nDate: ").AsSpan();
             var utf8 = Encoding.ASCII.GetBytes("\r\nDate: ").AsSpan();
+
             utf8.CopyTo(s_headerBytesMaster);
             utf8.CopyTo(s_headerBytesMaster);
             utf8.CopyTo(s_headerBytesScratch);
             utf8.CopyTo(s_headerBytesScratch);
             s_headerBytesMaster[suffixIndex] = (byte)'\r';
             s_headerBytesMaster[suffixIndex] = (byte)'\r';
             s_headerBytesMaster[suffixIndex + 1] = (byte)'\n';
             s_headerBytesMaster[suffixIndex + 1] = (byte)'\n';
+            s_headerBytesMaster[suffixIndex + 2] = (byte)'\r';
+            s_headerBytesMaster[suffixIndex + 3] = (byte)'\n';
             s_headerBytesScratch[suffixIndex] = (byte)'\r';
             s_headerBytesScratch[suffixIndex] = (byte)'\r';
             s_headerBytesScratch[suffixIndex + 1] = (byte)'\n';
             s_headerBytesScratch[suffixIndex + 1] = (byte)'\n';
+            s_headerBytesScratch[suffixIndex + 2] = (byte)'\r';
+            s_headerBytesScratch[suffixIndex + 3] = (byte)'\n';
+
             SetDateValues(DateTimeOffset.UtcNow);
             SetDateValues(DateTimeOffset.UtcNow);
             SyncDateTimer();
             SyncDateTimer();
         }
         }
@@ -47,7 +53,7 @@ namespace PlatformBenchmarks
         {
         {
             lock (s_headerBytesScratch)
             lock (s_headerBytesScratch)
             {
             {
-                if (!Utf8Formatter.TryFormat(value, s_headerBytesScratch.AsSpan(prefixLength), out int written, 'R'))
+                if (!Utf8Formatter.TryFormat(value, s_headerBytesScratch.AsSpan(prefixLength), out var written, 'R'))
                 {
                 {
                     throw new Exception("date time format failed");
                     throw new Exception("date time format failed");
                 }
                 }

+ 0 - 1
frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/IHttpConnection.cs

@@ -12,6 +12,5 @@ namespace PlatformBenchmarks
         PipeReader Reader { get; set; }
         PipeReader Reader { get; set; }
         PipeWriter Writer { get; set; }
         PipeWriter Writer { get; set; }
         Task ExecuteAsync();
         Task ExecuteAsync();
-        ValueTask OnReadCompletedAsync();
     }
     }
 }
 }

+ 35 - 6
frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/Program.cs

@@ -4,8 +4,11 @@
 using System;
 using System;
 using System.Net;
 using System.Net;
 using Microsoft.AspNetCore.Hosting;
 using Microsoft.AspNetCore.Hosting;
-using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
 using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.Configuration;
+#if DATABASE
+using Npgsql;
+using MySql.Data.MySqlClient;
+#endif
 
 
 namespace PlatformBenchmarks
 namespace PlatformBenchmarks
 {
 {
@@ -15,17 +18,29 @@ namespace PlatformBenchmarks
 
 
         public static void Main(string[] args)
         public static void Main(string[] args)
         {
         {
+            Utf8Json.Resolvers.CompositeResolver.RegisterAndSetAsDefault(    
+                Utf8Json.Resolvers.GeneratedResolver.Instance);
+
             Args = args;
             Args = args;
 
 
             Console.WriteLine(BenchmarkApplication.ApplicationName);
             Console.WriteLine(BenchmarkApplication.ApplicationName);
+#if !DATABASE
             Console.WriteLine(BenchmarkApplication.Paths.Plaintext);
             Console.WriteLine(BenchmarkApplication.Paths.Plaintext);
             Console.WriteLine(BenchmarkApplication.Paths.Json);
             Console.WriteLine(BenchmarkApplication.Paths.Json);
+#else
+            Console.WriteLine(BenchmarkApplication.Paths.Fortunes);
+            Console.WriteLine(BenchmarkApplication.Paths.SingleQuery);
+            Console.WriteLine(BenchmarkApplication.Paths.Updates);
+            Console.WriteLine(BenchmarkApplication.Paths.MultipleQueries);
+#endif
             DateHeader.SyncDateTimer();
             DateHeader.SyncDateTimer();
 
 
-            Utf8Json.Resolvers.CompositeResolver.RegisterAndSetAsDefault(    
-                Utf8Json.Resolvers.GeneratedResolver.Instance);
-
-            BuildWebHost(args).Run();
+            var host = BuildWebHost(args);
+#if DATABASE
+            var config = (IConfiguration)host.Services.GetService(typeof(IConfiguration));
+            BatchUpdateString.DatabaseServer = config.Get<AppSettings>().Database;
+#endif
+            host.Run();
         }
         }
 
 
         public static IWebHost BuildWebHost(string[] args)
         public static IWebHost BuildWebHost(string[] args)
@@ -36,11 +51,25 @@ namespace PlatformBenchmarks
                 .AddCommandLine(args)
                 .AddCommandLine(args)
                 .Build();
                 .Build();
 
 
+#if DATABASE
+            var appSettings = config.Get<AppSettings>();
+            Console.WriteLine($"Database: {appSettings.Database}");
+
+            if (appSettings.Database == DatabaseServer.PostgreSql)
+            {
+                BenchmarkApplication.Db = new RawDb(new ConcurrentRandom(), NpgsqlFactory.Instance, appSettings);
+            }
+            else if (appSettings.Database == DatabaseServer.MySql)
+            {
+                BenchmarkApplication.Db = new RawDb(new ConcurrentRandom(), MySqlClientFactory.Instance, appSettings);
+            }
+#endif
+
             var host = new WebHostBuilder()
             var host = new WebHostBuilder()
                 .UseBenchmarksConfiguration(config)
                 .UseBenchmarksConfiguration(config)
                 .UseKestrel((context, options) =>
                 .UseKestrel((context, options) =>
                 {
                 {
-                    IPEndPoint endPoint = context.Configuration.CreateIPEndPoint();
+                    var endPoint = context.Configuration.CreateIPEndPoint();
 
 
                     options.Listen(endPoint, builder =>
                     options.Listen(endPoint, builder =>
                     {
                     {

+ 4 - 4
frameworks/CSharp/aspnetcore-corert/benchmark_config.json

@@ -2,8 +2,8 @@
   "framework": "aspcore-corert",
   "framework": "aspcore-corert",
   "tests": [{
   "tests": [{
     "default": {
     "default": {
-      "plaintext_url": "/plaintext",
-      "json_url": "/json",
+      "plaintext_url": "/p",
+      "json_url": "/j",
       "port": 8080,
       "port": 8080,
       "approach": "Stripped",
       "approach": "Stripped",
       "classification": "Platform",
       "classification": "Platform",
@@ -21,8 +21,8 @@
       "versus": "aspcore"
       "versus": "aspcore"
     },
     },
     "rhtx": {
     "rhtx": {
-      "plaintext_url": "/plaintext",
-      "json_url": "/json",
+      "plaintext_url": "/p",
+      "json_url": "/j",
       "port": 8080,
       "port": 8080,
       "approach": "Stripped",
       "approach": "Stripped",
       "classification": "Platform",
       "classification": "Platform",