mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
Ensuring ITagCache thread safety
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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>();
|
||||
}
|
||||
}
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user