{"action":"created","comment":{"url":"https://api.github.com/repos/aspnet/Routing/pulls/comments/213127357","pull_request_review_id":149898600,"id":213127357,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIxMzEyNzM1Nw==","diff_hunk":"@@ -0,0 +1,548 @@\n+﻿// Copyright (c) .NET Foundation. All rights reserved.\n+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.\n+#if NET462 || NETCOREAPP2_0\n+\n+using System;\n+using System.Diagnostics;\n+using System.Linq;\n+using System.Reflection;\n+using System.Reflection.Emit;\n+using System.Runtime.CompilerServices;\n+using System.Runtime.InteropServices;\n+\n+namespace Microsoft.AspNetCore.Routing.Matching\n+{\n+    internal class VectorizedRefEmitTrieJumpTable : JumpTable\n+    {\n+        // Sentinel value returns when text is not ASCII\n+        private const int NotAscii = int.MinValue;\n+\n+        private readonly int _defaultDestination;\n+        private readonly int _exitDestination;\n+        private readonly (string text, int destination)[] _entries;\n+\n+        private readonly Func<string, int, int, int> _delegate;\n+\n+        public VectorizedRefEmitTrieJumpTable(\n+            int defaultDestination,\n+            int exitDestination,\n+            (string text, int destination)[] entries)\n+        {\n+            _defaultDestination = defaultDestination;\n+            _exitDestination = exitDestination;\n+            _entries = entries;\n+\n+            _delegate = GenerateDelegate();\n+        }\n+\n+        public override int GetDestination(string path, PathSegment segment)\n+        {\n+            if (path.Length == 0)\n+            {\n+                return _exitDestination;\n+            }\n+\n+            return _delegate(path, segment.Start, segment.Length);\n+        }\n+\n+        private Func<string, int, int, int> GenerateDelegate()\n+        {\n+#if NET462\n+            var assemblyName = new AssemblyName(\"DynamicRoutingJumpTable\");\n+            var assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);\n+            var module = assembly.DefineDynamicModule(assemblyName.Name, assemblyName.Name + \".dll\");\n+            var type = module.DefineType(\"Test\", TypeAttributes.Public);\n+            var method = type.DefineMethod(\n+                \"GeneratedGetDestination\",\n+                MethodAttributes.Public | MethodAttributes.Static,\n+                typeof(int),\n+                new[] { typeof(string), typeof(int), typeof(int), });\n+#else\n+            var method = new DynamicMethod(\n+                \"GeneratedGetDestination\",\n+                typeof(int),\n+                new [] { typeof(string), typeof(int), typeof(int), });\n+\n+#endif\n+            var il = method.GetILGenerator();\n+            \n+            // See comments on Locals for details\n+            var locals = new Locals()\n+            {\n+                P = il.DeclareLocal(typeof(byte).MakeByRefType()),\n+\n+                UInt16Value = il.DeclareLocal(typeof(ushort)),\n+\n+                UInt64Value = il.DeclareLocal(typeof(ulong)),\n+                UInt64LowerIndicator = il.DeclareLocal(typeof(ulong)),\n+                UInt64UpperIndicator = il.DeclareLocal(typeof(ulong)),\n+\n+                Span = il.DeclareLocal(typeof(ReadOnlySpan<char>)),\n+            };\n+\n+            // See comments on Labels for details\n+            var labels = new Labels()\n+            {\n+                ReturnDefault = il.DefineLabel(),\n+                ReturnNotAscii = il.DefineLabel(),\n+            };\n+\n+            // See comments on Methods for details\n+            var methods = new Methods();\n+\n+            // Initializing top-level locals - this is similar to...\n+            // ReadOnlySpan<char> span = arg0.AsSpan(arg1, arg2);\n+            // ref byte p = ref Unsafe.As<char, byte>(MemoryMarshal.GetReference<char>(span))\n+\n+            // arg0.AsSpan(arg1, arg2)\n+            il.Emit(OpCodes.Ldarg_0);\n+            il.Emit(OpCodes.Ldarg_1);\n+            il.Emit(OpCodes.Ldarg_2);\n+            il.Emit(OpCodes.Call, methods.AsSpan);\n+\n+            // ReadOnlySpan<char> = ...\n+            il.Emit(OpCodes.Stloc, locals.Span);\n+\n+            // MemoryMarshal.GetReference<char>(span)\n+            il.Emit(OpCodes.Ldloc, locals.Span);\n+            il.Emit(OpCodes.Call, methods.GetReference);\n+\n+            // Unsafe.As<char, byte>(...)\n+            il.Emit(OpCodes.Call, methods.As);\n+\n+            // ref byte p = ...\n+            il.Emit(OpCodes.Stloc_0, locals.P);\n+\n+            var groups = _entries.GroupBy(e => e.text.Length).ToArray();\n+            for (var i = 0; i < groups.Length; i++)\n+            {\n+                var group = groups[i];\n+\n+                // Similar to 'if (length != X) { ... }\n+                var inside = il.DefineLabel();\n+                var next = il.DefineLabel();\n+                il.Emit(OpCodes.Ldarg_2);\n+                il.Emit(OpCodes.Ldc_I4, group.Key);\n+                il.Emit(OpCodes.Beq, inside);\n+                il.Emit(OpCodes.Br, next);\n+\n+                // Process the group\n+                il.MarkLabel(inside);\n+                EmitTable(il, group.ToArray(), 0, group.Key, locals, labels, methods);\n+                il.MarkLabel(next);\n+            }\n+\n+            // Exit point - we end up here when the text doesn't match\n+            il.MarkLabel(labels.ReturnDefault);\n+            il.Emit(OpCodes.Ldc_I4, _defaultDestination);\n+            il.Emit(OpCodes.Ret);\n+\n+            // Exit point - we end up here with the text contains non-ASCII text\n+            il.MarkLabel(labels.ReturnNotAscii);\n+            il.Emit(OpCodes.Ldc_I4, NotAscii);\n+            il.Emit(OpCodes.Ret);\n+\n+#if NET462\n+            var t = type.CreateType();\n+            assembly.Save(assemblyName.Name + \".dll\");\n+            return (Func<string, int, int, int>)t.GetMethod(\"GeneratedGetDestination\").CreateDelegate(typeof(Func<string, int, int, int>));\n+#else\n+            return (Func<string, int, int, int>)method.CreateDelegate(typeof(Func<string, int, int, int>));\n+#endif\n+        }\n+\n+        private static void EmitTable(\n+            ILGenerator il,\n+            (string text, int destination)[] entries,\n+            int index,\n+            int length,\n+            Locals locals,\n+            Labels labels,\n+            Methods methods)\n+        {\n+            // We've reached the end of the string.\n+            if (index == length)\n+            {\n+                EmitReturnDestination(il, entries);\n+                return;\n+            }\n+\n+            // If 4 or more characters remain, we should process 4 characters at a time.\n+            if (length - index >= 4)\n+            {\n+                EmitVectorizedTable(il, entries, index, length, locals, labels, methods);\n+                return;\n+            }\n+\n+            // Fall back to processing a character at a time.\n+            EmitSingleCharacterTable(il, entries, index, length, locals, labels, methods);\n+        }\n+\n+        private static void EmitVectorizedTable(\n+            ILGenerator il,\n+            (string text, int destination)[] entries,\n+            int index,\n+            int length,\n+            Locals locals,\n+            Labels labels,\n+            Methods methods)\n+        {\n+            // Emits code similar to:\n+            //\n+            // uint64Value = Unsafe.ReadUnaligned<ulong>(ref p);\n+            // p = ref Unsafe.Add(ref p, 8);\n+            //\n+            // if ((uint64Value & ~0x007F007F007F007FUL) == 0)\n+            // {\n+            //     return NotAscii;\n+            // }\n+            // uint64LowerIndicator = value + (0x0080008000800080UL - 0x0041004100410041UL);\n+            // uint64UpperIndicator = value + (0x0080008000800080UL - 0x005B005B005B005BUL);\n+            // ulong temp1 = uint64LowerIndicator ^ uint64UpperIndicator\n+            // ulong temp2 = temp1 & 0x0080008000800080UL;\n+            // ulong temp3 = (temp2) >> 2;\n+            // uint64Value = uint64Value ^ temp3;\n+            //\n+            // This is a vectorized non-branching technique for processing 4 utf16 characters\n+            // at a time inside a single uint64.\n+            //\n+            // Similar to:\n+            // https://github.com/GrabYourPitchforks/coreclr/commit/a3c1df25c4225995ffd6b18fd0fc39d6b81fd6a5#diff-d89b6ca07ea349899e45eed5f688a7ebR81\n+            // https://github.com/WojciechMula/toys/blob/master/changecase_swar/tolower.cpp\n+            //\n+            // Basically we need to check if the text is non-ASCII first and bail if it is.\n+            // The rest of the steps will convert the text to lowercase by checking all characters\n+            // at a time to see if they are in the A-Z range, that's where 0x0041 and 0x005B come in.\n+\n+            // Unsafe.ReadUnaligned<ulong>(ref p)\n+            il.Emit(OpCodes.Ldloc, locals.P);\n+            il.Emit(OpCodes.Call, methods.ReadUnalignedUInt64);\n+\n+            // uint64Value = ...\n+            il.Emit(OpCodes.Stloc, locals.UInt64Value);\n+\n+            // Unsafe.Add(ref p, 8)\n+            il.Emit(OpCodes.Ldloc, locals.P);\n+            il.Emit(OpCodes.Ldc_I4, 8); // 8 bytes were read\n+            il.Emit(OpCodes.Call, methods.Add);\n+\n+            // p = ref ...\n+            il.Emit(OpCodes.Stloc, locals.P);\n+\n+            // if ((uint64Value & ~0x007F007F007F007FUL) == 0)\n+            // {\n+            //     goto: NotAscii;\n+            // }\n+            il.Emit(OpCodes.Ldloc, locals.UInt64Value);\n+            il.Emit(OpCodes.Ldc_I8, unchecked((long)~0x007F007F007F007FUL));\n+            il.Emit(OpCodes.And);\n+            il.Emit(OpCodes.Brtrue, labels.ReturnNotAscii);\n+\n+            // uint64Value + (0x0080008000800080UL - 0x0041004100410041UL)\n+            il.Emit(OpCodes.Ldloc, locals.UInt64Value);\n+            il.Emit(OpCodes.Ldc_I8, unchecked((long)(0x0080008000800080UL - 0x0041004100410041UL)));\n+            il.Emit(OpCodes.Add);\n+\n+            // uint64LowerIndicator = ...\n+            il.Emit(OpCodes.Stloc, locals.UInt64LowerIndicator);\n+\n+            // value + (0x0080008000800080UL - 0x005B005B005B005BUL)\n+            il.Emit(OpCodes.Ldloc, locals.UInt64Value);\n+            il.Emit(OpCodes.Ldc_I8, unchecked((long)(0x0080008000800080UL - 0x005B005B005B005BUL)));\n+            il.Emit(OpCodes.Add);\n+\n+            // uint64UpperIndicator = ...\n+            il.Emit(OpCodes.Stloc, locals.UInt64UpperIndicator);\n+\n+            // ulongLowerIndicator ^ ulongUpperIndicator\n+            il.Emit(OpCodes.Ldloc, locals.UInt64LowerIndicator);\n+            il.Emit(OpCodes.Ldloc, locals.UInt64UpperIndicator);\n+            il.Emit(OpCodes.Xor);\n+\n+            // ... & 0x0080008000800080UL\n+            il.Emit(OpCodes.Ldc_I8, unchecked((long)0x0080008000800080UL));\n+            il.Emit(OpCodes.And);\n+\n+            // ... >> 2;\n+            il.Emit(OpCodes.Ldc_I4, 2);\n+            il.Emit(OpCodes.Shr_Un);\n+\n+            // ...  ^ uint64Value\n+            il.Emit(OpCodes.Ldloc, locals.UInt64Value);\n+            il.Emit(OpCodes.Xor);\n+\n+            // uint64Value = ...\n+            il.Emit(OpCodes.Stloc, locals.UInt64Value);\n+            \n+            // Now we generate an 'if' ladder with an entry for each of the unique 64 bit sections\n+            // of the text.\n+            var groups = entries.GroupBy(e => GetUInt64Key(e.text, index));\n+            foreach (var group in groups)\n+            {\n+                // if (uint64Value == 0x.....) { ... }\n+                var next = il.DefineLabel();\n+                il.Emit(OpCodes.Ldloc, locals.UInt64Value);\n+                il.Emit(OpCodes.Ldc_I8, unchecked((long)group.Key));\n+                il.Emit(OpCodes.Bne_Un, next);\n+\n+                // Process the group\n+                EmitTable(il, group.ToArray(), index + 4, length, locals, labels, methods);\n+                il.MarkLabel(next);\n+            }\n+\n+            // goto: defaultDestination\n+            il.Emit(OpCodes.Br, labels.ReturnDefault);\n+        }\n+\n+        private static void EmitSingleCharacterTable(\n+            ILGenerator il,\n+            (string text, int destination)[] entries,\n+            int index,\n+            int length,\n+            Locals locals,\n+            Labels labels,\n+            Methods methods)\n+        {\n+            // See the vectorized code path for a much more thorough explanation.\n+\n+            // Unsafe.ReadUnaligned<ushort>(ref p)\n+            il.Emit(OpCodes.Ldloc, locals.P);\n+            il.Emit(OpCodes.Call, methods.ReadUnalignedUInt16);\n+\n+            // uint16Value = ...\n+            il.Emit(OpCodes.Stloc, locals.UInt16Value);\n+\n+            // Unsafe.Add(ref p, 2)\n+            il.Emit(OpCodes.Ldloc, locals.P);\n+            il.Emit(OpCodes.Ldc_I4, 2); // 2 bytes were read\n+            il.Emit(OpCodes.Call, methods.Add);\n+\n+            // p = ref ...\n+            il.Emit(OpCodes.Stloc, locals.P);\n+\n+            // if ((uInt16Value & ~0x007FUL) == 0)\n+            // {\n+            //     goto: NotAscii;\n+            // }\n+            il.Emit(OpCodes.Ldloc, locals.UInt16Value);\n+            il.Emit(OpCodes.Ldc_I4, ~0x007F);\n+            il.Emit(OpCodes.And);\n+            il.Emit(OpCodes.Brtrue, labels.ReturnNotAscii);\n+\n+            // Since we're handling a single character at a time, it's easier to just\n+            // generate an 'if' with two comparisons instead of doing complicated conversion\n+            // logic.\n+\n+            // Now we generate an 'if' ladder with an entry for each of the unique\n+            // characters in the group. \n+            var groups = entries.GroupBy(e => GetUInt16Key(e.text, index));\n+            foreach (var group in groups)\n+            {\n+                // if (uInt16Value == 'A' || uint16Value == 'a') { ... }\n+                var next = il.DefineLabel();\n+                var inside = il.DefineLabel();\n+                il.Emit(OpCodes.Ldloc, locals.UInt16Value);\n+                il.Emit(OpCodes.Ldc_I4, unchecked((int)((uint)group.Key)));\n+                il.Emit(OpCodes.Beq, inside);\n+\n+                var upper = (ushort)char.ToUpperInvariant((char)group.Key);\n+                if (upper != group.Key)\n+                {\n+                    il.Emit(OpCodes.Ldloc, locals.UInt16Value);\n+                    il.Emit(OpCodes.Ldc_I4, unchecked((int)((uint)upper)));\n+                    il.Emit(OpCodes.Beq, inside);\n+                }\n+\n+                il.Emit(OpCodes.Br, next);\n+\n+                // Process the group\n+                il.MarkLabel(inside);\n+                EmitTable(il, group.ToArray(), index + 1, length, locals, labels, methods);\n+                il.MarkLabel(next);\n+            }\n+\n+            // goto: defaultDestination\n+            il.Emit(OpCodes.Br, labels.ReturnDefault);\n+        }\n+\n+        public static void EmitReturnDestination(ILGenerator il, (string text, int destination)[] entries)\n+        {\n+            Debug.Assert(entries.Length == 1, \"We should have a single entry\");\n+            il.Emit(OpCodes.Ldc_I4, entries[0].destination);\n+            il.Emit(OpCodes.Ret);\n+        }\n+\n+        private static ulong GetUInt64Key(string text, int index)\n+        {\n+            Debug.Assert(index + 4 <= text.Length);\n+            var span = text.ToLowerInvariant().AsSpan(index);\n+            ref var p = ref Unsafe.As<char, byte>(ref MemoryMarshal.GetReference(span));\n+            return Unsafe.ReadUnaligned<ulong>(ref p);\n+        }\n+\n+        private static ushort GetUInt16Key(string text, int index)\n+        {\n+            Debug.Assert(index + 1 <= text.Length);\n+            return (ushort)char.ToLowerInvariant(text[index]);\n+        }\n+\n+        private class Locals\n+        {\n+            /// <summary>\n+            /// Holds current character when processing a character at a time.\n+            /// </summary>\n+            public LocalBuilder UInt16Value { get; set; }\n+\n+            /// <summary>\n+            /// Holds current character when processing 4 characters at a time.\n+            /// </summary>\n+            public LocalBuilder UInt64Value { get; set; }\n+\n+            /// <summary>\n+            /// Used to covert casing. See comments where it's used.\n+            /// </summary>\n+            public LocalBuilder UInt64LowerIndicator { get; set; }\n+\n+            /// <summary>\n+            /// Used to covert casing. See comments where it's used.\n+            /// </summary>\n+            public LocalBuilder UInt64UpperIndicator { get; set; }\n+\n+            /// <summary>\n+            /// Holds a 'ref byte' reference to the current character (in bytes).\n+            /// </summary>\n+            public LocalBuilder P { get; set; }\n+\n+            /// <summary>\n+            /// Holds the relevant portion of the path as a Span[byte].\n+            /// </summary>\n+            public LocalBuilder Span { get; set; }\n+        }\n+\n+        private class Labels\n+        {\n+            /// <summary>\n+            /// Label to goto that will return the default destination (not a match).\n+            /// </summary>\n+            public Label ReturnDefault { get; set; }\n+\n+            /// <summary>\n+            /// Label to goto that will return a sentinel value for non-ascii text.\n+            /// </summary>\n+            public Label ReturnNotAscii { get; set; }\n+        }\n+\n+        private class Methods","path":"src/Microsoft.AspNetCore.Routing/Matching/VectorizedRefEmitTrieJumpTable.cs","position":435,"original_position":435,"commit_id":"7e757b7814ceab2fea63ba6678fa392aebaeda31","original_commit_id":"7e757b7814ceab2fea63ba6678fa392aebaeda31","user":{"login":"rynowak","id":1430011,"node_id":"MDQ6VXNlcjE0MzAwMTE=","avatar_url":"https://avatars1.githubusercontent.com/u/1430011?v=4","gravatar_id":"","url":"https://api.github.com/users/rynowak","html_url":"https://github.com/rynowak","followers_url":"https://api.github.com/users/rynowak/followers","following_url":"https://api.github.com/users/rynowak/following{/other_user}","gists_url":"https://api.github.com/users/rynowak/gists{/gist_id}","starred_url":"https://api.github.com/users/rynowak/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rynowak/subscriptions","organizations_url":"https://api.github.com/users/rynowak/orgs","repos_url":"https://api.github.com/users/rynowak/repos","events_url":"https://api.github.com/users/rynowak/events{/privacy}","received_events_url":"https://api.github.com/users/rynowak/received_events","type":"User","site_admin":false},"body":"I'm going to use a cached instance ","created_at":"2018-08-27T21:50:24Z","updated_at":"2018-08-27T21:50:24Z","html_url":"https://github.com/aspnet/Routing/pull/730#discussion_r213127357","pull_request_url":"https://api.github.com/repos/aspnet/Routing/pulls/730","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/aspnet/Routing/pulls/comments/213127357"},"html":{"href":"https://github.com/aspnet/Routing/pull/730#discussion_r213127357"},"pull_request":{"href":"https://api.github.com/repos/aspnet/Routing/pulls/730"}},"in_reply_to_id":211138347},"pull_request":{"url":"https://api.github.com/repos/aspnet/Routing/pulls/730","id":209045075,"node_id":"MDExOlB1bGxSZXF1ZXN0MjA5MDQ1MDc1","html_url":"https://github.com/aspnet/Routing/pull/730","diff_url":"https://github.com/aspnet/Routing/pull/730.diff","patch_url":"https://github.com/aspnet/Routing/pull/730.patch","issue_url":"https://api.github.com/repos/aspnet/Routing/issues/730","number":730,"state":"open","locked":false,"title":"I'll try ref-emit, that's a good trick!","user":{"login":"rynowak","id":1430011,"node_id":"MDQ6VXNlcjE0MzAwMTE=","avatar_url":"https://avatars1.githubusercontent.com/u/1430011?v=4","gravatar_id":"","url":"https://api.github.com/users/rynowak","html_url":"https://github.com/rynowak","followers_url":"https://api.github.com/users/rynowak/followers","following_url":"https://api.github.com/users/rynowak/following{/other_user}","gists_url":"https://api.github.com/users/rynowak/gists{/gist_id}","starred_url":"https://api.github.com/users/rynowak/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rynowak/subscriptions","organizations_url":"https://api.github.com/users/rynowak/orgs","repos_url":"https://api.github.com/users/rynowak/repos","events_url":"https://api.github.com/users/rynowak/events{/privacy}","received_events_url":"https://api.github.com/users/rynowak/received_events","type":"User","site_admin":false},"body":"","created_at":"2018-08-17T04:51:29Z","updated_at":"2018-08-27T21:50:24Z","closed_at":null,"merged_at":null,"merge_commit_sha":"80acc1abf48079ad2996d02cee10d676af6e264a","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/aspnet/Routing/pulls/730/commits","review_comments_url":"https://api.github.com/repos/aspnet/Routing/pulls/730/comments","review_comment_url":"https://api.github.com/repos/aspnet/Routing/pulls/comments{/number}","comments_url":"https://api.github.com/repos/aspnet/Routing/issues/730/comments","statuses_url":"https://api.github.com/repos/aspnet/Routing/statuses/7e757b7814ceab2fea63ba6678fa392aebaeda31","head":{"label":"aspnet:rynowak/trieing-harder","ref":"rynowak/trieing-harder","sha":"7e757b7814ceab2fea63ba6678fa392aebaeda31","user":{"login":"aspnet","id":6476660,"node_id":"MDEyOk9yZ2FuaXphdGlvbjY0NzY2NjA=","avatar_url":"https://avatars3.githubusercontent.com/u/6476660?v=4","gravatar_id":"","url":"https://api.github.com/users/aspnet","html_url":"https://github.com/aspnet","followers_url":"https://api.github.com/users/aspnet/followers","following_url":"https://api.github.com/users/aspnet/following{/other_user}","gists_url":"https://api.github.com/users/aspnet/gists{/gist_id}","starred_url":"https://api.github.com/users/aspnet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aspnet/subscriptions","organizations_url":"https://api.github.com/users/aspnet/orgs","repos_url":"https://api.github.com/users/aspnet/repos","events_url":"https://api.github.com/users/aspnet/events{/privacy}","received_events_url":"https://api.github.com/users/aspnet/received_events","type":"Organization","site_admin":false},"repo":{"id":16300347,"node_id":"MDEwOlJlcG9zaXRvcnkxNjMwMDM0Nw==","name":"Routing","full_name":"aspnet/Routing","owner":{"login":"aspnet","id":6476660,"node_id":"MDEyOk9yZ2FuaXphdGlvbjY0NzY2NjA=","avatar_url":"https://avatars3.githubusercontent.com/u/6476660?v=4","gravatar_id":"","url":"https://api.github.com/users/aspnet","html_url":"https://github.com/aspnet","followers_url":"https://api.github.com/users/aspnet/followers","following_url":"https://api.github.com/users/aspnet/following{/other_user}","gists_url":"https://api.github.com/users/aspnet/gists{/gist_id}","starred_url":"https://api.github.com/users/aspnet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aspnet/subscriptions","organizations_url":"https://api.github.com/users/aspnet/orgs","repos_url":"https://api.github.com/users/aspnet/repos","events_url":"https://api.github.com/users/aspnet/events{/privacy}","received_events_url":"https://api.github.com/users/aspnet/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/aspnet/Routing","description":"Middleware for routing requests to application logic.","fork":false,"url":"https://api.github.com/repos/aspnet/Routing","forks_url":"https://api.github.com/repos/aspnet/Routing/forks","keys_url":"https://api.github.com/repos/aspnet/Routing/keys{/key_id}","collaborators_url":"https://api.github.com/repos/aspnet/Routing/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/aspnet/Routing/teams","hooks_url":"https://api.github.com/repos/aspnet/Routing/hooks","issue_events_url":"https://api.github.com/repos/aspnet/Routing/issues/events{/number}","events_url":"https://api.github.com/repos/aspnet/Routing/events","assignees_url":"https://api.github.com/repos/aspnet/Routing/assignees{/user}","branches_url":"https://api.github.com/repos/aspnet/Routing/branches{/branch}","tags_url":"https://api.github.com/repos/aspnet/Routing/tags","blobs_url":"https://api.github.com/repos/aspnet/Routing/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/aspnet/Routing/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/aspnet/Routing/git/refs{/sha}","trees_url":"https://api.github.com/repos/aspnet/Routing/git/trees{/sha}","statuses_url":"https://api.github.com/repos/aspnet/Routing/statuses/{sha}","languages_url":"https://api.github.com/repos/aspnet/Routing/languages","stargazers_url":"https://api.github.com/repos/aspnet/Routing/stargazers","contributors_url":"https://api.github.com/repos/aspnet/Routing/contributors","subscribers_url":"https://api.github.com/repos/aspnet/Routing/subscribers","subscription_url":"https://api.github.com/repos/aspnet/Routing/subscription","commits_url":"https://api.github.com/repos/aspnet/Routing/commits{/sha}","git_commits_url":"https://api.github.com/repos/aspnet/Routing/git/commits{/sha}","comments_url":"https://api.github.com/repos/aspnet/Routing/comments{/number}","issue_comment_url":"https://api.github.com/repos/aspnet/Routing/issues/comments{/number}","contents_url":"https://api.github.com/repos/aspnet/Routing/contents/{+path}","compare_url":"https://api.github.com/repos/aspnet/Routing/compare/{base}...{head}","merges_url":"https://api.github.com/repos/aspnet/Routing/merges","archive_url":"https://api.github.com/repos/aspnet/Routing/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/aspnet/Routing/downloads","issues_url":"https://api.github.com/repos/aspnet/Routing/issues{/number}","pulls_url":"https://api.github.com/repos/aspnet/Routing/pulls{/number}","milestones_url":"https://api.github.com/repos/aspnet/Routing/milestones{/number}","notifications_url":"https://api.github.com/repos/aspnet/Routing/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/aspnet/Routing/labels{/name}","releases_url":"https://api.github.com/repos/aspnet/Routing/releases{/id}","deployments_url":"https://api.github.com/repos/aspnet/Routing/deployments","created_at":"2014-01-28T02:50:39Z","updated_at":"2018-08-23T21:11:16Z","pushed_at":"2018-08-26T19:27:48Z","git_url":"git://github.com/aspnet/Routing.git","ssh_url":"git@github.com:aspnet/Routing.git","clone_url":"https://github.com/aspnet/Routing.git","svn_url":"https://github.com/aspnet/Routing","homepage":"","size":5723,"stargazers_count":256,"watchers_count":256,"language":"C#","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":114,"mirror_url":null,"archived":false,"open_issues_count":28,"license":{"key":"other","name":"Other","spdx_id":null,"url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":114,"open_issues":28,"watchers":256,"default_branch":"release/2.2"}},"base":{"label":"aspnet:release/2.2","ref":"release/2.2","sha":"0986f74264d0e17f82b4548ed63c38f12969e9c9","user":{"login":"aspnet","id":6476660,"node_id":"MDEyOk9yZ2FuaXphdGlvbjY0NzY2NjA=","avatar_url":"https://avatars3.githubusercontent.com/u/6476660?v=4","gravatar_id":"","url":"https://api.github.com/users/aspnet","html_url":"https://github.com/aspnet","followers_url":"https://api.github.com/users/aspnet/followers","following_url":"https://api.github.com/users/aspnet/following{/other_user}","gists_url":"https://api.github.com/users/aspnet/gists{/gist_id}","starred_url":"https://api.github.com/users/aspnet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aspnet/subscriptions","organizations_url":"https://api.github.com/users/aspnet/orgs","repos_url":"https://api.github.com/users/aspnet/repos","events_url":"https://api.github.com/users/aspnet/events{/privacy}","received_events_url":"https://api.github.com/users/aspnet/received_events","type":"Organization","site_admin":false},"repo":{"id":16300347,"node_id":"MDEwOlJlcG9zaXRvcnkxNjMwMDM0Nw==","name":"Routing","full_name":"aspnet/Routing","owner":{"login":"aspnet","id":6476660,"node_id":"MDEyOk9yZ2FuaXphdGlvbjY0NzY2NjA=","avatar_url":"https://avatars3.githubusercontent.com/u/6476660?v=4","gravatar_id":"","url":"https://api.github.com/users/aspnet","html_url":"https://github.com/aspnet","followers_url":"https://api.github.com/users/aspnet/followers","following_url":"https://api.github.com/users/aspnet/following{/other_user}","gists_url":"https://api.github.com/users/aspnet/gists{/gist_id}","starred_url":"https://api.github.com/users/aspnet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aspnet/subscriptions","organizations_url":"https://api.github.com/users/aspnet/orgs","repos_url":"https://api.github.com/users/aspnet/repos","events_url":"https://api.github.com/users/aspnet/events{/privacy}","received_events_url":"https://api.github.com/users/aspnet/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/aspnet/Routing","description":"Middleware for routing requests to application logic.","fork":false,"url":"https://api.github.com/repos/aspnet/Routing","forks_url":"https://api.github.com/repos/aspnet/Routing/forks","keys_url":"https://api.github.com/repos/aspnet/Routing/keys{/key_id}","collaborators_url":"https://api.github.com/repos/aspnet/Routing/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/aspnet/Routing/teams","hooks_url":"https://api.github.com/repos/aspnet/Routing/hooks","issue_events_url":"https://api.github.com/repos/aspnet/Routing/issues/events{/number}","events_url":"https://api.github.com/repos/aspnet/Routing/events","assignees_url":"https://api.github.com/repos/aspnet/Routing/assignees{/user}","branches_url":"https://api.github.com/repos/aspnet/Routing/branches{/branch}","tags_url":"https://api.github.com/repos/aspnet/Routing/tags","blobs_url":"https://api.github.com/repos/aspnet/Routing/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/aspnet/Routing/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/aspnet/Routing/git/refs{/sha}","trees_url":"https://api.github.com/repos/aspnet/Routing/git/trees{/sha}","statuses_url":"https://api.github.com/repos/aspnet/Routing/statuses/{sha}","languages_url":"https://api.github.com/repos/aspnet/Routing/languages","stargazers_url":"https://api.github.com/repos/aspnet/Routing/stargazers","contributors_url":"https://api.github.com/repos/aspnet/Routing/contributors","subscribers_url":"https://api.github.com/repos/aspnet/Routing/subscribers","subscription_url":"https://api.github.com/repos/aspnet/Routing/subscription","commits_url":"https://api.github.com/repos/aspnet/Routing/commits{/sha}","git_commits_url":"https://api.github.com/repos/aspnet/Routing/git/commits{/sha}","comments_url":"https://api.github.com/repos/aspnet/Routing/comments{/number}","issue_comment_url":"https://api.github.com/repos/aspnet/Routing/issues/comments{/number}","contents_url":"https://api.github.com/repos/aspnet/Routing/contents/{+path}","compare_url":"https://api.github.com/repos/aspnet/Routing/compare/{base}...{head}","merges_url":"https://api.github.com/repos/aspnet/Routing/merges","archive_url":"https://api.github.com/repos/aspnet/Routing/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/aspnet/Routing/downloads","issues_url":"https://api.github.com/repos/aspnet/Routing/issues{/number}","pulls_url":"https://api.github.com/repos/aspnet/Routing/pulls{/number}","milestones_url":"https://api.github.com/repos/aspnet/Routing/milestones{/number}","notifications_url":"https://api.github.com/repos/aspnet/Routing/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/aspnet/Routing/labels{/name}","releases_url":"https://api.github.com/repos/aspnet/Routing/releases{/id}","deployments_url":"https://api.github.com/repos/aspnet/Routing/deployments","created_at":"2014-01-28T02:50:39Z","updated_at":"2018-08-23T21:11:16Z","pushed_at":"2018-08-26T19:27:48Z","git_url":"git://github.com/aspnet/Routing.git","ssh_url":"git@github.com:aspnet/Routing.git","clone_url":"https://github.com/aspnet/Routing.git","svn_url":"https://github.com/aspnet/Routing","homepage":"","size":5723,"stargazers_count":256,"watchers_count":256,"language":"C#","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":114,"mirror_url":null,"archived":false,"open_issues_count":28,"license":{"key":"other","name":"Other","spdx_id":null,"url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":114,"open_issues":28,"watchers":256,"default_branch":"release/2.2"}},"_links":{"self":{"href":"https://api.github.com/repos/aspnet/Routing/pulls/730"},"html":{"href":"https://github.com/aspnet/Routing/pull/730"},"issue":{"href":"https://api.github.com/repos/aspnet/Routing/issues/730"},"comments":{"href":"https://api.github.com/repos/aspnet/Routing/issues/730/comments"},"review_comments":{"href":"https://api.github.com/repos/aspnet/Routing/pulls/730/comments"},"review_comment":{"href":"https://api.github.com/repos/aspnet/Routing/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/aspnet/Routing/pulls/730/commits"},"statuses":{"href":"https://api.github.com/repos/aspnet/Routing/statuses/7e757b7814ceab2fea63ba6678fa392aebaeda31"}},"author_association":"MEMBER"}}
{"actor":{"display_login":"rynowak"}}