1
1
// Copyright (c) .NET Foundation. All rights reserved.
2
2
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3
3
4
+ using System ;
5
+ using System . Threading ;
6
+
4
7
namespace Microsoft . AspNet . Http . Features . Internal
5
8
{
6
9
public class HttpRequestIdentifierFeature : IHttpRequestIdentifierFeature
7
10
{
8
- public virtual string TraceIdentifier { get ; set ; }
11
+ // Base64 encoding - but in ascii sort order for easy text based sorting
12
+ private static readonly string _encode32Chars = "0123456789ABCDEFGHIJKLMNOPQRSTUV" ;
13
+ // Seed the _requestId for this application instance with
14
+ // the number of 100-nanosecond intervals that have elapsed since 12:00:00 midnight, January 1, 0001
15
+ // for a roughly increasing _requestId over restarts
16
+ private static long _requestId = DateTime . UtcNow . Ticks ;
17
+
18
+ private string _id = null ;
19
+
20
+ public string TraceIdentifier
21
+ {
22
+ get
23
+ {
24
+ // Don't incur the cost of generating the request ID until it's asked for
25
+ if ( _id == null )
26
+ {
27
+ _id = GenerateRequestId ( Interlocked . Increment ( ref _requestId ) ) ;
28
+ }
29
+ return _id ;
30
+ }
31
+ set
32
+ {
33
+ _id = value ;
34
+ }
35
+ }
36
+
37
+ private static unsafe string GenerateRequestId ( long id )
38
+ {
39
+ // The following routine is ~310% faster than calling long.ToString() on x64
40
+ // and ~600% faster than calling long.ToString() on x86 in tight loops of 1 million+ iterations
41
+ // See: https://github.com/aspnet/Hosting/pull/385
42
+
43
+ // stackalloc to allocate array on stack rather than heap
44
+ char * charBuffer = stackalloc char [ 13 ] ;
45
+
46
+ charBuffer [ 0 ] = _encode32Chars [ ( int ) ( id >> 60 ) & 31 ] ;
47
+ charBuffer [ 1 ] = _encode32Chars [ ( int ) ( id >> 55 ) & 31 ] ;
48
+ charBuffer [ 2 ] = _encode32Chars [ ( int ) ( id >> 50 ) & 31 ] ;
49
+ charBuffer [ 3 ] = _encode32Chars [ ( int ) ( id >> 45 ) & 31 ] ;
50
+ charBuffer [ 4 ] = _encode32Chars [ ( int ) ( id >> 40 ) & 31 ] ;
51
+ charBuffer [ 5 ] = _encode32Chars [ ( int ) ( id >> 35 ) & 31 ] ;
52
+ charBuffer [ 6 ] = _encode32Chars [ ( int ) ( id >> 30 ) & 31 ] ;
53
+ charBuffer [ 7 ] = _encode32Chars [ ( int ) ( id >> 25 ) & 31 ] ;
54
+ charBuffer [ 8 ] = _encode32Chars [ ( int ) ( id >> 20 ) & 31 ] ;
55
+ charBuffer [ 9 ] = _encode32Chars [ ( int ) ( id >> 15 ) & 31 ] ;
56
+ charBuffer [ 10 ] = _encode32Chars [ ( int ) ( id >> 10 ) & 31 ] ;
57
+ charBuffer [ 11 ] = _encode32Chars [ ( int ) ( id >> 5 ) & 31 ] ;
58
+ charBuffer [ 12 ] = _encode32Chars [ ( int ) id & 31 ] ;
59
+
60
+ // string ctor overload that takes char*
61
+ return new string ( charBuffer , 0 , 13 ) ;
62
+ }
9
63
}
10
64
}
0 commit comments