@@ -4,65 +4,52 @@ namespace FastCloner.Code;
4
4
5
5
internal static class FastClonerCache
6
6
{
7
- private static readonly ConcurrentDictionary < Type , object > _typeCache = new ConcurrentDictionary < Type , object > ( ) ;
8
-
9
- private static readonly ConcurrentDictionary < Type , object > _typeCacheDeepTo = new ConcurrentDictionary < Type , object > ( ) ;
10
-
11
- private static readonly ConcurrentDictionary < Type , object > _typeCacheShallowTo = new ConcurrentDictionary < Type , object > ( ) ;
12
-
13
- private static readonly ConcurrentDictionary < Type , object > _structAsObjectCache = new ConcurrentDictionary < Type , object > ( ) ;
14
-
15
- private static readonly ConcurrentDictionary < Tuple < Type , Type > , object > _typeConvertCache = new ConcurrentDictionary < Tuple < Type , Type > , object > ( ) ;
16
-
17
- public static object GetOrAddClass < T > ( Type type , Func < Type , T > adder )
7
+ private static readonly ConcurrentDictionary < Type , Lazy < object > > classCache = new ConcurrentDictionary < Type , Lazy < object > > ( ) ;
8
+ private static readonly ConcurrentDictionary < Type , Lazy < object > > structCache = new ConcurrentDictionary < Type , Lazy < object > > ( ) ;
9
+ private static readonly ConcurrentDictionary < Type , Lazy < object > > deepClassToCache = new ConcurrentDictionary < Type , Lazy < object > > ( ) ;
10
+ private static readonly ConcurrentDictionary < Type , Lazy < object > > shallowClassToCache = new ConcurrentDictionary < Type , Lazy < object > > ( ) ;
11
+ private static readonly ConcurrentDictionary < Tuple < Type , Type > , Lazy < object > > typeConvertCache = new ConcurrentDictionary < Tuple < Type , Type > , Lazy < object > > ( ) ;
12
+
13
+ public static object GetOrAddClass ( Type type , Func < Type , object > valueFactory )
18
14
{
19
- // return _typeCache.GetOrAdd(type, x => adder(x));
20
-
21
- // this implementation is slightly faster than getoradd
22
- if ( _typeCache . TryGetValue ( type , out object ? value ) ) return value ;
23
-
24
- value = _typeCache . GetOrAdd ( type , t => adder ( t ) ) ;
25
- return value ;
15
+ Lazy < object > lazy = classCache . GetOrAdd ( type , t => new Lazy < object > ( ( ) => valueFactory ( t ) , LazyThreadSafetyMode . ExecutionAndPublication ) ) ;
16
+ return lazy . Value ;
26
17
}
27
18
28
- public static object GetOrAddDeepClassTo < T > ( Type type , Func < Type , T > adder )
19
+ public static object GetOrAddStructAsObject ( Type type , Func < Type , object > valueFactory )
29
20
{
30
- if ( _typeCacheDeepTo . TryGetValue ( type , out object ? value ) ) return value ;
31
-
32
- value = _typeCacheDeepTo . GetOrAdd ( type , t => adder ( t ) ) ;
33
- return value ;
21
+ Lazy < object > lazy = structCache . GetOrAdd ( type , t => new Lazy < object > ( ( ) => valueFactory ( t ) , LazyThreadSafetyMode . ExecutionAndPublication ) ) ;
22
+ return lazy . Value ;
34
23
}
35
24
36
- public static object GetOrAddShallowClassTo < T > ( Type type , Func < Type , T > adder )
25
+ public static object GetOrAddDeepClassTo ( Type type , Func < Type , object > valueFactory )
37
26
{
38
- if ( _typeCacheShallowTo . TryGetValue ( type , out object ? value ) ) return value ;
39
-
40
- value = _typeCacheShallowTo . GetOrAdd ( type , t => adder ( t ) ) ;
41
- return value ;
27
+ Lazy < object > lazy = deepClassToCache . GetOrAdd ( type , t => new Lazy < object > ( ( ) => valueFactory ( t ) , LazyThreadSafetyMode . ExecutionAndPublication ) ) ;
28
+ return lazy . Value ;
42
29
}
43
30
44
- public static object GetOrAddStructAsObject < T > ( Type type , Func < Type , T ? > adder )
31
+ public static object GetOrAddShallowClassTo ( Type type , Func < Type , object > valueFactory )
45
32
{
46
- // return _typeCache.GetOrAdd(type, x => adder(x));
47
-
48
- // this implementation is slightly faster than getoradd
49
- if ( _structAsObjectCache . TryGetValue ( type , out object ? value ) ) return value ;
50
-
51
- value = _structAsObjectCache . GetOrAdd ( type , t => adder ( t ) ) ;
52
- return value ;
33
+ Lazy < object > lazy = shallowClassToCache . GetOrAdd ( type , t => new Lazy < object > ( ( ) => valueFactory ( t ) , LazyThreadSafetyMode . ExecutionAndPublication ) ) ;
34
+ return lazy . Value ;
53
35
}
54
36
55
- public static T GetOrAddConvertor < T > ( Type from , Type to , Func < Type , Type , T > adder ) => ( T ) _typeConvertCache . GetOrAdd ( new Tuple < Type , Type > ( from , to ) , ( tuple ) => adder ( tuple . Item1 , tuple . Item2 ) ) ;
37
+ public static T GetOrAddConvertor < T > ( Type from , Type to , Func < Type , Type , T > adder )
38
+ {
39
+ Tuple < Type , Type > key = new Tuple < Type , Type > ( from , to ) ;
40
+ Lazy < object > lazy = typeConvertCache . GetOrAdd ( key , tuple => new Lazy < object > ( ( ) => adder ( tuple . Item1 , tuple . Item2 ) , LazyThreadSafetyMode . ExecutionAndPublication ) ) ;
41
+ return ( T ) lazy . Value ;
42
+ }
56
43
57
44
/// <summary>
58
45
/// This method can be used when we switch between safe / unsafe variants (for testing)
59
46
/// </summary>
60
47
public static void ClearCache ( )
61
48
{
62
- _typeCache . Clear ( ) ;
63
- _typeCacheDeepTo . Clear ( ) ;
64
- _typeCacheShallowTo . Clear ( ) ;
65
- _structAsObjectCache . Clear ( ) ;
66
- _typeConvertCache . Clear ( ) ;
49
+ classCache . Clear ( ) ;
50
+ structCache . Clear ( ) ;
51
+ deepClassToCache . Clear ( ) ;
52
+ shallowClassToCache . Clear ( ) ;
53
+ typeConvertCache . Clear ( ) ;
67
54
}
68
55
}
0 commit comments