|
1 | | -// Copyright (C) 2003-2010 Xtensive LLC. |
2 | | -// All rights reserved. |
3 | | -// For conditions of distribution and use, see license. |
| 1 | +// Copyright (C) 2009-2020 Xtensive LLC. |
| 2 | +// This code is distributed under MIT license terms. |
| 3 | +// See the License.txt file in the project root for more information. |
4 | 4 | // Created by: Denis Krjuchkov |
5 | 5 | // Created: 2009.05.06 |
6 | 6 |
|
7 | 7 | using System; |
| 8 | +using System.Collections.Concurrent; |
8 | 9 | using System.Linq.Expressions; |
9 | | -using Xtensive.Collections; |
10 | 10 | using Xtensive.Core; |
11 | 11 |
|
12 | | - |
13 | 12 | namespace Xtensive.Linq |
14 | 13 | { |
15 | 14 | internal sealed class CachingExpressionCompiler |
16 | 15 | { |
17 | | - private static readonly object _lock = new object(); |
18 | | - private static volatile CachingExpressionCompiler instance; |
19 | | - |
20 | | - public static CachingExpressionCompiler Instance { |
21 | | - get { |
22 | | - if (instance==null) lock (_lock) if (instance==null) |
23 | | - instance = new CachingExpressionCompiler(); |
24 | | - return instance; |
25 | | - } |
26 | | - } |
| 16 | + public static CachingExpressionCompiler Instance { get; } = new CachingExpressionCompiler(); |
| 17 | + |
| 18 | + private readonly ConcurrentDictionary<ExpressionTree, Delegate> cache = |
| 19 | + new ConcurrentDictionary<ExpressionTree, Delegate>(); |
| 20 | + |
| 21 | + private static readonly Func<ExpressionTree, Delegate> expressionTreeCompiler = CompileExpressionTree; |
27 | 22 |
|
28 | | - private readonly ThreadSafeDictionary<ExpressionTree, Delegate> cache = |
29 | | - ThreadSafeDictionary<ExpressionTree, Delegate>.Create(new object()); |
| 23 | + private static Delegate CompileExpressionTree(ExpressionTree tree) => |
| 24 | + ((LambdaExpression) tree.ToExpression()).Compile(); |
30 | 25 |
|
31 | 26 | public Pair<Delegate, object[]> Compile(LambdaExpression lambda) |
32 | 27 | { |
33 | 28 | var constantExtractor = new ConstantExtractor(lambda); |
34 | | - var tree = constantExtractor.Process().ToExpressionTree(); |
| 29 | + var expressionTree = constantExtractor.Process().ToExpressionTree(); |
35 | 30 | var constants = constantExtractor.GetConstants(); |
36 | | - var compiled = cache.GetValue(tree, _tree => ((LambdaExpression) _tree.ToExpression()).Compile()); |
37 | | -// var compiled = ((LambdaExpression) tree.ToExpression()).Compile(); |
| 31 | + |
| 32 | + var compiled = cache.GetOrAdd(expressionTree, expressionTreeCompiler); |
38 | 33 | return new Pair<Delegate, object[]>(compiled, constants); |
39 | 34 | } |
40 | 35 |
|
41 | 36 | // For testing only |
42 | | - public void ClearCache() |
43 | | - { |
44 | | - cache.Clear(); |
45 | | - } |
| 37 | + public void ClearCache() => cache.Clear(); |
46 | 38 |
|
47 | 39 |
|
48 | 40 | // Constructors |
|
0 commit comments