Skip to content

Commit a533d62

Browse files
committed
* Perf: several optimizations
* Minor CacheManager refactoring
1 parent 3a7f645 commit a533d62

27 files changed

Lines changed: 373 additions & 336 deletions

File tree

src/Libraries/SmartStore.Core/Caching/AspNetCache.cs

Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -35,36 +35,26 @@ where key.StartsWith(REGION_NAME)
3535
}
3636
}
3737

38-
public T Get<T>(string key, Func<T> acquirer, int? cacheTime)
38+
public object Get(string key)
3939
{
4040
if (_context is FakeHttpContext)
41-
return default(T);
41+
return null;
4242

43-
key = BuildKey(key);
43+
return _context.Cache.Get(BuildKey(key));
44+
}
4445

45-
var entry = _context.Cache.Get(key);
46+
public void Set(string key, object value, int? cacheTime)
47+
{
48+
key = BuildKey(key);
4649

47-
if (entry != null)
48-
{
49-
return (T)entry;
50-
}
51-
else
52-
{
53-
var value = acquirer();
54-
if (value != null)
55-
{
56-
var absoluteExpiration = Cache.NoAbsoluteExpiration;
57-
if (cacheTime.GetValueOrDefault() > 0)
58-
{
59-
absoluteExpiration = DateTime.UtcNow + TimeSpan.FromMinutes(cacheTime.Value);
60-
}
50+
var absoluteExpiration = Cache.NoAbsoluteExpiration;
51+
if (cacheTime.GetValueOrDefault() > 0)
52+
{
53+
absoluteExpiration = DateTime.UtcNow + TimeSpan.FromMinutes(cacheTime.Value);
54+
}
6155

62-
_context.Cache.Insert(key, value, null, absoluteExpiration, Cache.NoSlidingExpiration);
63-
}
64-
65-
return value;
66-
}
67-
}
56+
_context.Cache.Insert(key, value, null, absoluteExpiration, Cache.NoSlidingExpiration);
57+
}
6858

6959
public bool Contains(string key)
7060
{
@@ -87,6 +77,11 @@ public static string BuildKey(string key)
8777
return key.HasValue() ? REGION_NAME + key : null;
8878
}
8979

80+
public bool IsSingleton
81+
{
82+
get { return false; }
83+
}
84+
9085
}
9186

9287
}

src/Libraries/SmartStore.Core/Caching/DefaultCacheManager.cs

Lines changed: 69 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,88 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Text.RegularExpressions;
4+
using System.Threading;
5+
using SmartStore.Utilities;
6+
using SmartStore.Utilities.Threading;
47

58
namespace SmartStore.Core.Caching
69
{
710

11+
public static class ICacheManagerExtensions
12+
{
13+
public static T Get<T>(this ICacheManager cacheManager, string key)
14+
{
15+
return cacheManager.Get<T>(key, () => { return default(T); });
16+
}
17+
}
18+
819
public partial class CacheManager<TCache> : ICacheManager where TCache : ICache
920
{
10-
private readonly ICache _cache;
21+
private readonly ReaderWriterLockSlim _rwLock = new ReaderWriterLockSlim();
22+
private readonly ICache _cache;
1123

1224
public CacheManager(Func<Type, ICache> fn)
1325
{
1426
this._cache = fn(typeof(TCache));
1527
}
1628

17-
public T Get<T>(string key, Func<T> acquirer, int? cacheTime = 60)
29+
public T Get<T>(string key, Func<T> acquirer, int? cacheTime = null)
1830
{
19-
return _cache.Get(key, acquirer, cacheTime);
31+
Guard.ArgumentNotEmpty(() => key);
32+
33+
if (_cache.Contains(key))
34+
{
35+
return (T)_cache.Get(key);
36+
}
37+
else
38+
{
39+
using (GetReadLock())
40+
{
41+
if (!_cache.Contains(key))
42+
{
43+
var value = acquirer();
44+
this.Set(key, value, cacheTime);
45+
46+
return value;
47+
}
48+
}
49+
50+
return (T)_cache.Get(key);
51+
}
2052
}
2153

54+
public void Set(string key, object value, int? cacheTime = null)
55+
{
56+
Guard.ArgumentNotEmpty(() => key);
57+
58+
if (value == null)
59+
return;
60+
61+
using (GetWriteLock())
62+
{
63+
_cache.Set(key, value, cacheTime);
64+
}
65+
}
66+
2267
public bool Contains(string key)
2368
{
24-
return _cache.Contains(key);
69+
Guard.ArgumentNotEmpty(() => key);
70+
71+
return _cache.Contains(key);
2572
}
2673

2774
public void Remove(string key)
2875
{
29-
_cache.Remove(key);
76+
Guard.ArgumentNotEmpty(() => key);
77+
78+
_cache.Remove(key);
3079
}
3180

3281
public void RemoveByPattern(string pattern)
3382
{
34-
var regex = new Regex(pattern, RegexOptions.Singleline | RegexOptions.Compiled | RegexOptions.IgnoreCase);
83+
Guard.ArgumentNotEmpty(() => pattern);
84+
85+
var regex = new Regex(pattern, RegexOptions.Singleline | RegexOptions.Compiled | RegexOptions.IgnoreCase);
3586
var keysToRemove = new List<String>();
3687

3788
foreach (var item in _cache.Entries)
@@ -61,5 +112,16 @@ public void Clear()
61112
_cache.Remove(key);
62113
}
63114
}
64-
}
115+
116+
private IDisposable GetReadLock()
117+
{
118+
return _cache.IsSingleton ? _rwLock.GetUpgradeableReadLock() : ActionDisposable.Empty;
119+
}
120+
121+
private IDisposable GetWriteLock()
122+
{
123+
return _cache.IsSingleton ? _rwLock.GetWriteLock() : ActionDisposable.Empty;
124+
}
125+
126+
}
65127
}

src/Libraries/SmartStore.Core/Caching/Extensions.cs

Lines changed: 0 additions & 46 deletions
This file was deleted.

src/Libraries/SmartStore.Core/Caching/ICache.cs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,19 @@ public interface ICache
1616
IEnumerable<KeyValuePair<string, object>> Entries { get; }
1717

1818
/// <summary>
19-
/// Gets a cache item associated with the specified key or adds the item
20-
/// if it doesn't exist in the cache.
19+
/// Gets a cache item associated with the specified key
2120
/// </summary>
22-
/// <typeparam name="T">The type of the item to get or add</typeparam>
2321
/// <param name="key">The cache item key</param>
24-
/// <param name="acquirer">Func which returns value to be added to the cache</param>
25-
/// <param name="cacheTime">Expiration time in minutes</param>
2622
/// <returns>Cached item value</returns>
27-
T Get<T>(string key, Func<T> acquirer, int? cacheTime);
23+
object Get(string key);
24+
25+
/// <summary>
26+
/// Adds the cache item with the specified key
27+
/// </summary>
28+
/// <param name="key">Key</param>
29+
/// <param name="data">Data</param>
30+
/// <param name="cacheTime">Cache time in minutes</param>
31+
void Set(string key, object value, int? cacheTime);
2832

2933
/// <summary>
3034
/// Gets a value indicating whether an item associated with the specified key exists in the cache
@@ -39,6 +43,11 @@ public interface ICache
3943
/// <param name="key">/key</param>
4044
void Remove(string key);
4145

46+
/// <summary>
47+
/// Gets a value indicating whether reads and writes to this cache should be thread safe
48+
/// </summary>
49+
bool IsSingleton { get; }
50+
4251
}
4352

4453
}

src/Libraries/SmartStore.Core/Caching/ICacheManager.cs

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,14 @@ public interface ICacheManager
1616
/// <param name="cacheTime">Expiration time in minutes</param>
1717
/// <returns>Cached item value</returns>
1818
T Get<T>(string key, Func<T> acquirer, int? cacheTime = null);
19-
20-
///// <summary>
21-
///// Gets or sets the value associated with the specified key.
22-
///// </summary>
23-
///// <typeparam name="T">Type</typeparam>
24-
///// <param name="key">The key of the value to get.</param>
25-
///// <returns>The value associated with the specified key.</returns>
26-
//T Get<T>(string key);
2719

28-
///// <summary>
29-
///// Adds the specified key and object to the cache.
30-
///// </summary>
31-
///// <param name="key">key</param>
32-
///// <param name="data">Data</param>
33-
///// <param name="cacheTime">Cache time</param>
34-
//void Set(string key, object data, int cacheTime);
20+
/// <summary>
21+
/// Adds a cache item with the specified key
22+
/// </summary>
23+
/// <param name="key">Key</param>
24+
/// <param name="value">Value</param>
25+
/// <param name="cacheTime">Cache time in minutes</param>
26+
void Set(string key, object value, int? cacheTime = null);
3527

3628
/// <summary>
3729
/// Gets a value indicating whether the value associated with the specified key is cached

src/Libraries/SmartStore.Core/Caching/NullCache.cs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,15 @@ public static ICacheManager Instance
1414
get { return s_instance; }
1515
}
1616

17-
public T Get<T>(string key, Func<T> acquirer, int? cacheTime = 60)
18-
{
19-
return acquirer();
20-
}
17+
public T Get<T>(string key, Func<T> acquirer, int? cacheTime = null)
18+
{
19+
return default(T);
20+
}
21+
22+
23+
public void Set(string key, object value, int? cacheTime = null)
24+
{
25+
}
2126

2227
/// <summary>
2328
/// Gets a value indicating whether the value associated with the specified key is cached
@@ -51,5 +56,6 @@ public void RemoveByPattern(string pattern)
5156
public void Clear()
5257
{
5358
}
54-
}
59+
60+
}
5561
}

src/Libraries/SmartStore.Core/Caching/RequestCache.cs

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -47,30 +47,32 @@ public IEnumerable<KeyValuePair<string, object>> Entries
4747
}
4848
}
4949

50-
public T Get<T>(string key, Func<T> acquirer, int? cacheTime)
50+
public object Get(string key)
5151
{
5252
var items = GetItems();
5353
if (items == null)
54-
return default(T);
55-
56-
key = BuildKey(key);
54+
return null;
5755

58-
if (items.Contains(key))
59-
{
60-
return (T)items[key];
61-
}
62-
else
63-
{
64-
var value = acquirer();
65-
if (value != null)
66-
{
67-
items.Add(key, value);
68-
}
69-
70-
return value;
71-
}
56+
return items[BuildKey(key)];
7257
}
7358

59+
public void Set(string key, object value, int? cacheTime)
60+
{
61+
var items = GetItems();
62+
if (items == null)
63+
return;
64+
65+
key = BuildKey(key);
66+
67+
if (value != null)
68+
{
69+
if (items.Contains(key))
70+
items[key] = value;
71+
else
72+
items.Add(key, value);
73+
}
74+
}
75+
7476
public bool Contains(string key)
7577
{
7678
var items = GetItems();
@@ -94,6 +96,11 @@ private string BuildKey(string key)
9496
return key.HasValue() ? REGION_NAME + key : null;
9597
}
9698

97-
}
99+
public bool IsSingleton
100+
{
101+
get { return false; }
102+
}
103+
104+
}
98105

99106
}

0 commit comments

Comments
 (0)