Ensuring ITagCache thread safety

This commit is contained in:
Sebastien Ros
2014-03-11 17:17:47 -07:00
parent 70908980cd
commit b1d4905431
3 changed files with 28 additions and 15 deletions

View File

@@ -37,11 +37,8 @@ namespace Orchard.OutputCache.Services {
}
public void RemoveByTag(string tag) {
Collection<string> itemKeys;
if (_tagCache.TryGetValue(tag, out itemKeys)) {
foreach (var key in itemKeys) {
_cacheStorageProvider.Remove(key);
}
foreach(var key in _tagCache.GetTaggedItems(tag)) {
_cacheStorageProvider.Remove(key);
}
}

View File

@@ -1,24 +1,41 @@
using System;
using System.Collections.Concurrent;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Linq;
using Orchard.OutputCache.Models;
using Orchard.Utility.Extensions;
namespace Orchard.OutputCache.Services {
/// <summary>
/// Tenant wide case insensitive reverse index for <see cref="CacheItem"/> tags.
/// </summary>
public class DefaultTagCache : ConcurrentDictionary<string, Collection<string>>, ITagCache {
public DefaultTagCache() : base(StringComparer.OrdinalIgnoreCase) {
public class DefaultTagCache : ITagCache {
private readonly ConcurrentDictionary<string, HashSet<string>> _dictionary;
public DefaultTagCache() {
_dictionary = new ConcurrentDictionary<string, HashSet<string>>(StringComparer.OrdinalIgnoreCase);
}
public void Tag(string tag, params string[] keys) {
var collection = GetOrAdd(tag, x => new Collection<string>());
var set = _dictionary.GetOrAdd(tag, x => new HashSet<string>());
foreach (var key in keys) {
if (!collection.Contains(key)) {
collection.Add(key);
lock (set) {
foreach (var key in keys) {
set.Add(key);
}
}
}
public IEnumerable<string> GetTaggedItems(string tag) {
HashSet<string> set;
if (_dictionary.TryGetValue(tag, out set)) {
lock (set) {
return set.ToReadOnlyCollection();
}
}
return Enumerable.Empty<string>();
}
}
}

View File

@@ -1,9 +1,8 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Orchard;
namespace Orchard.OutputCache.Services {
public interface ITagCache : IDictionary<string, Collection<string>>, ISingletonDependency {
public interface ITagCache : ISingletonDependency {
void Tag(string tag, params string[] keys);
IEnumerable<string> GetTaggedItems(string tag);
}
}