NuCache - code cleanup
This commit is contained in:
@@ -3,7 +3,7 @@ using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Umbraco.Web.PublishedCache.NuCache
|
||||
{
|
||||
static class CacheKeys
|
||||
internal static class CacheKeys
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static string DraftOrPub(bool previewing)
|
||||
|
||||
@@ -6,7 +6,6 @@ using System.Xml.XPath;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.Xml;
|
||||
using Umbraco.Core.Xml.XPath;
|
||||
@@ -17,14 +16,14 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
{
|
||||
internal class ContentCache : PublishedCacheBase, IPublishedContentCache, INavigableData, IDisposable
|
||||
{
|
||||
private readonly ContentStore2.Snapshot _snapshot;
|
||||
private readonly ContentStore.Snapshot _snapshot;
|
||||
private readonly ICacheProvider _facadeCache;
|
||||
private readonly ICacheProvider _snapshotCache;
|
||||
private readonly DomainHelper _domainHelper;
|
||||
|
||||
#region Constructor
|
||||
|
||||
public ContentCache(bool previewDefault, ContentStore2.Snapshot snapshot, ICacheProvider facadeCache, ICacheProvider snapshotCache, DomainHelper domainHelper)
|
||||
public ContentCache(bool previewDefault, ContentStore.Snapshot snapshot, ICacheProvider facadeCache, ICacheProvider snapshotCache, DomainHelper domainHelper)
|
||||
: base(previewDefault)
|
||||
{
|
||||
_snapshot = snapshot;
|
||||
@@ -33,6 +32,9 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
_domainHelper = domainHelper;
|
||||
}
|
||||
|
||||
// fixme - inject settings
|
||||
private static bool HideTopLevelNodeFromPath => GlobalSettings.HideTopLevelNodeFromPath;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Routes
|
||||
@@ -53,16 +55,16 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
|
||||
public IPublishedContent GetByRoute(bool preview, string route, bool? hideTopLevelNode = null)
|
||||
{
|
||||
if (route == null) throw new ArgumentNullException("route");
|
||||
if (route == null) throw new ArgumentNullException(nameof(route));
|
||||
|
||||
var cache = (preview == false || FacadeService.FullCacheWhenPreviewing) ? _snapshotCache : _facadeCache;
|
||||
var cache = preview == false || FacadeService.FullCacheWhenPreviewing ? _snapshotCache : _facadeCache;
|
||||
var key = CacheKeys.ContentCacheContentByRoute(route, preview);
|
||||
return cache.GetCacheItem<IPublishedContent>(key, () => GetByRouteInternal(preview, route, hideTopLevelNode));
|
||||
}
|
||||
|
||||
private IPublishedContent GetByRouteInternal(bool preview, string route, bool? hideTopLevelNode)
|
||||
{
|
||||
hideTopLevelNode = hideTopLevelNode ?? GlobalSettings.HideTopLevelNodeFromPath; // default = settings
|
||||
hideTopLevelNode = hideTopLevelNode ?? HideTopLevelNodeFromPath; // default = settings
|
||||
|
||||
// the route always needs to be lower case because we only store the urlName attribute in lower case
|
||||
route = route.ToLowerInvariant();
|
||||
@@ -129,7 +131,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
if (node == null)
|
||||
return null;
|
||||
|
||||
hideTopLevelNode = hideTopLevelNode ?? GlobalSettings.HideTopLevelNodeFromPath; // default = settings
|
||||
hideTopLevelNode = hideTopLevelNode ?? HideTopLevelNodeFromPath; // default = settings
|
||||
|
||||
// walk up from that node until we hit a node with a domain,
|
||||
// or we reach the content root, collecting urls in the way
|
||||
@@ -154,7 +156,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
// assemble the route
|
||||
pathParts.Reverse();
|
||||
var path = "/" + string.Join("/", pathParts); // will be "/" or "/foo" or "/foo/bar" etc
|
||||
var route = (n == null ? "" : n.Id.ToString(CultureInfo.InvariantCulture)) + path;
|
||||
var route = (n?.Id.ToString(CultureInfo.InvariantCulture) ?? "") + path;
|
||||
|
||||
return route;
|
||||
}
|
||||
@@ -300,10 +302,8 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
if (iterator.MoveNext() == false) return null;
|
||||
|
||||
var xnav = iterator.Current as NavigableNavigator;
|
||||
if (xnav == null) return null;
|
||||
|
||||
var xcontent = xnav.UnderlyingObject as NavigableContent;
|
||||
return xcontent == null ? null : xcontent.InnerContent;
|
||||
var xcontent = xnav?.UnderlyingObject as NavigableContent;
|
||||
return xcontent?.InnerContent;
|
||||
}
|
||||
|
||||
public override IEnumerable<IPublishedContent> GetByXPath(bool preview, string xpath, XPathVariable[] vars)
|
||||
@@ -325,9 +325,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
while (iterator.MoveNext())
|
||||
{
|
||||
var xnav = iterator.Current as NavigableNavigator;
|
||||
if (xnav == null) continue;
|
||||
|
||||
var xcontent = xnav.UnderlyingObject as NavigableContent;
|
||||
var xcontent = xnav?.UnderlyingObject as NavigableContent;
|
||||
if (xcontent == null) continue;
|
||||
|
||||
yield return xcontent.InnerContent;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Web.PublishedCache.NuCache.DataSource;
|
||||
|
||||
@@ -73,7 +72,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
}
|
||||
|
||||
// clone parent
|
||||
private ContentNode(ContentNode origin, IFacadeAccessor facadeAccessor)
|
||||
private ContentNode(ContentNode origin)
|
||||
{
|
||||
// everything is the same, except for the child items
|
||||
// list which is a clone of the original list
|
||||
@@ -138,7 +137,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
|
||||
public ContentNode CloneParent(IFacadeAccessor facadeAccessor)
|
||||
{
|
||||
return new ContentNode(this, facadeAccessor);
|
||||
return new ContentNode(this);
|
||||
}
|
||||
|
||||
public ContentNodeKit ToKit()
|
||||
@@ -147,10 +146,9 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
{
|
||||
Node = this,
|
||||
ContentTypeId = ContentType.Id,
|
||||
// ReSharper disable MergeConditionalExpression
|
||||
DraftData = Draft == null ? null : ((PublishedContent) Draft)._contentData,
|
||||
PublishedData = Published == null ? null : ((PublishedContent) Published)._contentData
|
||||
// ReSharper restore MergeConditionalExpression
|
||||
|
||||
DraftData = ((PublishedContent) Draft)?._contentData,
|
||||
PublishedData = ((PublishedContent) Published)?._contentData
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ using Umbraco.Web.PublishedCache.NuCache.DataSource;
|
||||
namespace Umbraco.Web.PublishedCache.NuCache
|
||||
{
|
||||
// what's needed to actually build a content node
|
||||
struct ContentNodeKit
|
||||
internal struct ContentNodeKit
|
||||
{
|
||||
public ContentNode Node;
|
||||
public int ContentTypeId;
|
||||
|
||||
@@ -11,7 +11,7 @@ using Umbraco.Core.Models.PublishedContent;
|
||||
namespace Umbraco.Web.PublishedCache.NuCache
|
||||
{
|
||||
// stores content
|
||||
internal class ContentStore2
|
||||
internal class ContentStore
|
||||
{
|
||||
// this class is an extended version of SnapDictionary
|
||||
// most of the snapshots management code, etc is an exact copy
|
||||
@@ -41,7 +41,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
|
||||
#region Ctor
|
||||
|
||||
public ContentStore2(IFacadeAccessor facadeAccessor, ILogger logger, BPlusTree<int, ContentNodeKit> localDb = null)
|
||||
public ContentStore(IFacadeAccessor facadeAccessor, ILogger logger, BPlusTree<int, ContentNodeKit> localDb = null)
|
||||
{
|
||||
_facadeAccessor = facadeAccessor;
|
||||
_logger = logger;
|
||||
@@ -203,8 +203,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
_contentTypeNodes.Remove(id);
|
||||
}
|
||||
|
||||
LinkedNode<PublishedContentType> link;
|
||||
if (_contentTypesById.TryGetValue(id, out link) == false || link.Value == null)
|
||||
if (_contentTypesById.TryGetValue(id, out LinkedNode<PublishedContentType> link) == false || link.Value == null)
|
||||
continue;
|
||||
SetValueLocked(_contentTypesById, id, null);
|
||||
SetValueLocked(_contentTypesByAlias, link.Value.Alias, null);
|
||||
@@ -240,8 +239,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
foreach (var id in temp.Values.SelectMany(x => x))
|
||||
ClearBranchLocked(id);
|
||||
|
||||
if (_localDb != null)
|
||||
_localDb.Commit();
|
||||
_localDb?.Commit();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -268,9 +266,8 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
|
||||
foreach (var id in _contentTypeNodes[contentType.Id])
|
||||
{
|
||||
LinkedNode<ContentNode> link;
|
||||
_contentNodes.TryGetValue(id, out link);
|
||||
if (link == null || link.Value == null)
|
||||
_contentNodes.TryGetValue(id, out LinkedNode<ContentNode> link);
|
||||
if (link?.Value == null)
|
||||
continue;
|
||||
var node = new ContentNode(link.Value, contentType, _facadeAccessor);
|
||||
SetValueLocked(_contentNodes, id, node);
|
||||
@@ -279,8 +276,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
}
|
||||
}
|
||||
|
||||
if (_localDb != null)
|
||||
_localDb.Commit();
|
||||
_localDb?.Commit();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -290,10 +286,9 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
if (kit.DraftData == null && kit.PublishedData == null)
|
||||
return false;
|
||||
|
||||
LinkedNode<PublishedContentType> link;
|
||||
|
||||
// unknown = bad
|
||||
if (_contentTypesById.TryGetValue(kit.ContentTypeId, out link) == false || link.Value == null)
|
||||
if (_contentTypesById.TryGetValue(kit.ContentTypeId, out LinkedNode<PublishedContentType> link) == false || link.Value == null)
|
||||
return false;
|
||||
|
||||
// not checking ByAlias, assuming we don't have internal errors
|
||||
@@ -320,16 +315,12 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
|
||||
#region Set, Clear, Get
|
||||
|
||||
public int Count
|
||||
{
|
||||
get { return _contentNodes.Count; }
|
||||
}
|
||||
public int Count => _contentNodes.Count;
|
||||
|
||||
private LinkedNode<TValue> GetHead<TKey, TValue>(ConcurrentDictionary<TKey, LinkedNode<TValue>> dict, TKey key)
|
||||
private static LinkedNode<TValue> GetHead<TKey, TValue>(ConcurrentDictionary<TKey, LinkedNode<TValue>> dict, TKey key)
|
||||
where TValue : class
|
||||
{
|
||||
LinkedNode<TValue> link;
|
||||
dict.TryGetValue(key, out link); // else null
|
||||
dict.TryGetValue(key, out LinkedNode<TValue> link); // else null
|
||||
return link;
|
||||
}
|
||||
|
||||
@@ -337,19 +328,18 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
{
|
||||
// ReSharper disable LocalizableElement
|
||||
if (kit.IsEmpty)
|
||||
throw new ArgumentException("Kit is empty.", "kit");
|
||||
throw new ArgumentException("Kit is empty.", nameof(kit));
|
||||
if (kit.Node.ChildContentIds.Count > 0)
|
||||
throw new ArgumentException("Kit content cannot have children.", "kit");
|
||||
throw new ArgumentException("Kit content cannot have children.", nameof(kit));
|
||||
// ReSharper restore LocalizableElement
|
||||
|
||||
_logger.Debug<ContentStore2>("Set content ID:" + kit.Node.Id);
|
||||
_logger.Debug<ContentStore>("Set content ID:" + kit.Node.Id);
|
||||
|
||||
WriteLocked(() =>
|
||||
{
|
||||
// get existing
|
||||
LinkedNode<ContentNode> link;
|
||||
_contentNodes.TryGetValue(kit.Node.Id, out link);
|
||||
var existing = link == null ? null : link.Value;
|
||||
_contentNodes.TryGetValue(kit.Node.Id, out LinkedNode<ContentNode> link);
|
||||
var existing = link?.Value;
|
||||
|
||||
// else ignore, what else could we do?
|
||||
if (ParentExistsLocked(kit) == false || BuildKit(kit) == false)
|
||||
@@ -380,8 +370,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
AddToParentLocked(kit.Node);
|
||||
}
|
||||
|
||||
if (_localDb != null)
|
||||
_localDb.Commit();
|
||||
_localDb?.Commit();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -405,8 +394,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
AddToParentLocked(kit.Node);
|
||||
}
|
||||
|
||||
if (_localDb != null)
|
||||
_localDb.Commit();
|
||||
_localDb?.Commit();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -415,9 +403,8 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
WriteLocked(() =>
|
||||
{
|
||||
// get existing
|
||||
LinkedNode<ContentNode> link;
|
||||
_contentNodes.TryGetValue(rootContentId, out link);
|
||||
var existing = link == null ? null : link.Value;
|
||||
_contentNodes.TryGetValue(rootContentId, out LinkedNode<ContentNode> link);
|
||||
var existing = link?.Value;
|
||||
|
||||
// clear
|
||||
if (existing != null)
|
||||
@@ -436,8 +423,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
AddToParentLocked(kit.Node);
|
||||
}
|
||||
|
||||
if (_localDb != null)
|
||||
_localDb.Commit();
|
||||
_localDb?.Commit();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -447,12 +433,11 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
{
|
||||
// try to find the content
|
||||
// if it is not there, nothing to do
|
||||
LinkedNode<ContentNode> link;
|
||||
_contentNodes.TryGetValue(id, out link); // else null
|
||||
if (link == null || link.Value == null) return false;
|
||||
_contentNodes.TryGetValue(id, out LinkedNode<ContentNode> link); // else null
|
||||
if (link?.Value == null) return false;
|
||||
|
||||
var content = link.Value;
|
||||
_logger.Debug<ContentStore2>("Clear content ID:" + content.Id);
|
||||
_logger.Debug<ContentStore>("Clear content ID:" + content.Id);
|
||||
|
||||
// clear the entire branch
|
||||
ClearBranchLocked(content);
|
||||
@@ -468,7 +453,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
{
|
||||
LinkedNode<ContentNode> link;
|
||||
_contentNodes.TryGetValue(id, out link);
|
||||
if (link == null || link.Value == null)
|
||||
if (link?.Value == null)
|
||||
return;
|
||||
ClearBranchLocked(link.Value);
|
||||
}
|
||||
@@ -476,16 +461,11 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
private void ClearBranchLocked(ContentNode content)
|
||||
{
|
||||
SetValueLocked(_contentNodes, content.Id, null);
|
||||
if (_localDb != null)
|
||||
{
|
||||
ContentNodeKit kit;
|
||||
_localDb.TryRemove(content.Id, out kit);
|
||||
}
|
||||
_localDb?.TryRemove(content.Id, out ContentNodeKit unused);
|
||||
ReleaseContentTypeLocked(content);
|
||||
foreach (var childId in content.ChildContentIds)
|
||||
{
|
||||
LinkedNode<ContentNode> link;
|
||||
if (_contentNodes.TryGetValue(childId, out link) == false || link.Value == null) continue;
|
||||
if (_contentNodes.TryGetValue(childId, out LinkedNode<ContentNode> link) == false || link.Value == null) continue;
|
||||
ClearBranchLocked(link.Value);
|
||||
}
|
||||
}
|
||||
@@ -525,7 +505,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
if (kit.Node.ParentContentId < 0)
|
||||
return true;
|
||||
var link = GetParentLink(kit.Node);
|
||||
return link != null && link.Value != null;
|
||||
return link?.Value != null;
|
||||
}
|
||||
|
||||
private void AddToParentLocked(ContentNode content)
|
||||
@@ -777,7 +757,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
{
|
||||
// see notes in CreateSnapshot
|
||||
#if DEBUG
|
||||
_logger.Debug<ContentStore2>("Collect.");
|
||||
_logger.Debug<ContentStore>("Collect.");
|
||||
#endif
|
||||
GenRefRef genRefRef;
|
||||
while (_genRefRefs.TryPeek(out genRefRef) && (genRefRef.Count == 0 || genRefRef.WGenRef.IsAlive == false))
|
||||
@@ -785,7 +765,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
_genRefRefs.TryDequeue(out genRefRef); // cannot fail since TryPeek has succeeded
|
||||
_floorGen = genRefRef.Gen;
|
||||
#if DEBUG
|
||||
//_logger.Debug<ContentStore2>("_floorGen=" + _floorGen + ", _liveGen=" + _liveGen);
|
||||
//_logger.Debug<ContentStore>("_floorGen=" + _floorGen + ", _liveGen=" + _liveGen);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -815,7 +795,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
var link = kvp.Value;
|
||||
|
||||
#if DEBUG
|
||||
//_logger.Debug<ContentStore2>("Collect id:" + kvp.Key + ", gen:" + link.Gen +
|
||||
//_logger.Debug<ContentStore>("Collect id:" + kvp.Key + ", gen:" + link.Gen +
|
||||
// ", nxt:" + (link.Next == null ? "null" : "link") +
|
||||
// ", val:" + (link.Value == null ? "null" : "value"));
|
||||
#endif
|
||||
@@ -859,18 +839,9 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
await task;
|
||||
}
|
||||
|
||||
public long GenCount
|
||||
{
|
||||
get { return _genRefRefs.Count; }
|
||||
}
|
||||
public long GenCount => _genRefRefs.Count;
|
||||
|
||||
public long SnapCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return _genRefRefs.Sum(x => x.Count);
|
||||
}
|
||||
}
|
||||
public long SnapCount => _genRefRefs.Sum(x => x.Count);
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -881,22 +852,25 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
// note: nothing here is thread-safe
|
||||
internal class TestHelper
|
||||
{
|
||||
private readonly ContentStore2 _store;
|
||||
private readonly ContentStore _store;
|
||||
|
||||
public TestHelper(ContentStore2 store)
|
||||
public TestHelper(ContentStore store)
|
||||
{
|
||||
_store = store;
|
||||
}
|
||||
|
||||
public long LiveGen { get { return _store._liveGen; } }
|
||||
public long FloorGen { get { return _store._floorGen; } }
|
||||
public bool NextGen { get { return _store._nextGen; } }
|
||||
public bool CollectAuto { get { return _store._collectAuto; } set { _store._collectAuto = value; } }
|
||||
public long LiveGen => _store._liveGen;
|
||||
public long FloorGen => _store._floorGen;
|
||||
public bool NextGen => _store._nextGen;
|
||||
public bool CollectAuto
|
||||
{
|
||||
get => _store._collectAuto;
|
||||
set => _store._collectAuto = value;
|
||||
}
|
||||
|
||||
public Tuple<long, ContentNode>[] GetValues(int id)
|
||||
{
|
||||
LinkedNode<ContentNode> link;
|
||||
_store._contentNodes.TryGetValue(id, out link); // else null
|
||||
_store._contentNodes.TryGetValue(id, out LinkedNode<ContentNode> link); // else null
|
||||
|
||||
if (link == null)
|
||||
return new Tuple<long, ContentNode>[0];
|
||||
@@ -911,7 +885,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
}
|
||||
}
|
||||
|
||||
internal TestHelper Test { get { return _unitTesting ?? (_unitTesting = new TestHelper(this)); } }
|
||||
internal TestHelper Test => _unitTesting ?? (_unitTesting = new TestHelper(this));
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -937,7 +911,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
|
||||
public class Snapshot : IDisposable
|
||||
{
|
||||
private readonly ContentStore2 _store;
|
||||
private readonly ContentStore _store;
|
||||
private readonly GenRef _genRef;
|
||||
private long _gen;
|
||||
#if DEBUG
|
||||
@@ -947,7 +921,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
//private static int _count;
|
||||
//private readonly int _thisCount;
|
||||
|
||||
internal Snapshot(ContentStore2 store, GenRef genRef
|
||||
internal Snapshot(ContentStore store, GenRef genRef
|
||||
#if DEBUG
|
||||
, ILogger logger
|
||||
#endif
|
||||
@@ -6,7 +6,7 @@ using CSharpTest.Net.Serialization;
|
||||
|
||||
namespace Umbraco.Web.PublishedCache.NuCache.DataSource
|
||||
{
|
||||
class BTree
|
||||
internal class BTree
|
||||
{
|
||||
public static BPlusTree<int, ContentNodeKit> GetTree(string filepath, bool exists)
|
||||
{
|
||||
@@ -28,7 +28,7 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
|
||||
return tree;
|
||||
}
|
||||
|
||||
class ContentNodeKitSerializer : ISerializer<ContentNodeKit>
|
||||
private class ContentNodeKitSerializer : ISerializer<ContentNodeKit>
|
||||
{
|
||||
static readonly ContentDataSerializer DataSerializer = new ContentDataSerializer();
|
||||
//static readonly ListOfIntSerializer ChildContentIdsSerializer = new ListOfIntSerializer();
|
||||
@@ -82,7 +82,7 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
|
||||
|
||||
class ContentDataSerializer : ISerializer<ContentData>
|
||||
{
|
||||
private readonly static DictionaryOfValuesSerializer PropertiesSerializer = new DictionaryOfValuesSerializer();
|
||||
private static readonly DictionaryOfValuesSerializer PropertiesSerializer = new DictionaryOfValuesSerializer();
|
||||
|
||||
public ContentData ReadFrom(Stream stream)
|
||||
{
|
||||
@@ -131,7 +131,7 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
|
||||
}
|
||||
*/
|
||||
|
||||
class DictionaryOfValuesSerializer : ISerializer<IDictionary<string, object>>
|
||||
private class DictionaryOfValuesSerializer : ISerializer<IDictionary<string, object>>
|
||||
{
|
||||
public IDictionary<string, object> ReadFrom(Stream stream)
|
||||
{
|
||||
|
||||
@@ -4,7 +4,7 @@ using System.Collections.Generic;
|
||||
namespace Umbraco.Web.PublishedCache.NuCache.DataSource
|
||||
{
|
||||
// represents everything that is specific to draft or published version
|
||||
class ContentData
|
||||
internal class ContentData
|
||||
{
|
||||
public bool Published { get; set; }
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ using Umbraco.Web.Composing;
|
||||
namespace Umbraco.Web.PublishedCache.NuCache.DataSource
|
||||
{
|
||||
// provides efficient database access for NuCache
|
||||
class Database
|
||||
internal class Database
|
||||
{
|
||||
public ContentNodeKit GetContentSource(IScopeUnitOfWork uow, int id)
|
||||
{
|
||||
|
||||
@@ -4,7 +4,7 @@ using Umbraco.Web.Routing;
|
||||
|
||||
namespace Umbraco.Web.PublishedCache.NuCache
|
||||
{
|
||||
class DomainCache : IDomainCache
|
||||
internal class DomainCache : IDomainCache
|
||||
{
|
||||
private readonly SnapDictionary<int, Domain>.Snapshot _snapshot;
|
||||
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
using System;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
|
||||
namespace Umbraco.Web.PublishedCache.NuCache
|
||||
{
|
||||
// implements the facade
|
||||
class Facade : IFacade, IDisposable
|
||||
internal class Facade : IFacade, IDisposable
|
||||
{
|
||||
private readonly FacadeService _service;
|
||||
private bool _defaultPreview;
|
||||
@@ -51,7 +49,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
|
||||
#region Caches
|
||||
|
||||
public ICacheProvider FacadeCache { get; private set; }
|
||||
public ICacheProvider FacadeCache { get; }
|
||||
|
||||
public ICacheProvider SnapshotCache => Elements.SnapshotCache;
|
||||
|
||||
|
||||
@@ -44,8 +44,8 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
// volatile because we read it with no lock
|
||||
private volatile bool _isReady;
|
||||
|
||||
private readonly ContentStore2 _contentStore;
|
||||
private readonly ContentStore2 _mediaStore;
|
||||
private readonly ContentStore _contentStore;
|
||||
private readonly ContentStore _mediaStore;
|
||||
private readonly SnapDictionary<int, Domain> _domainStore;
|
||||
private readonly object _storesLock = new object();
|
||||
|
||||
@@ -130,13 +130,13 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
// stores are created with a db so they can write to it, but they do not read from it,
|
||||
// stores need to be populated, happens in OnResolutionFrozen which uses _localDbExists to
|
||||
// figure out whether it can read the dbs or it should populate them from sql
|
||||
_contentStore = new ContentStore2(facadeAccessor, logger, _localContentDb);
|
||||
_mediaStore = new ContentStore2(facadeAccessor, logger, _localMediaDb);
|
||||
_contentStore = new ContentStore(facadeAccessor, logger, _localContentDb);
|
||||
_mediaStore = new ContentStore(facadeAccessor, logger, _localMediaDb);
|
||||
}
|
||||
else
|
||||
{
|
||||
_contentStore = new ContentStore2(facadeAccessor, logger);
|
||||
_mediaStore = new ContentStore2(facadeAccessor, logger);
|
||||
_contentStore = new ContentStore(facadeAccessor, logger);
|
||||
_mediaStore = new ContentStore(facadeAccessor, logger);
|
||||
}
|
||||
|
||||
_domainStore = new SnapDictionary<int, Domain>();
|
||||
@@ -910,7 +910,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
// nothing like that...
|
||||
// for snapshot cache, StaticCacheProvider is a No-No, use something better.
|
||||
|
||||
ContentStore2.Snapshot contentSnap, mediaSnap;
|
||||
ContentStore.Snapshot contentSnap, mediaSnap;
|
||||
SnapDictionary<int, Domain>.Snapshot domainSnap;
|
||||
ICacheProvider snapshotCache;
|
||||
lock (_storesLock)
|
||||
@@ -1003,7 +1003,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
|
||||
private static bool HasChangesImpactingAllVersions(IContent icontent)
|
||||
{
|
||||
var content = (Core.Models.Content) icontent;
|
||||
var content = (Content) icontent;
|
||||
|
||||
// UpdateDate will be dirty
|
||||
// Published may be dirty if saving a Published entity
|
||||
@@ -1022,7 +1022,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
OnRepositoryRefreshed(db, content, false);
|
||||
|
||||
// if unpublishing, remove from table
|
||||
if (((Core.Models.Content) content).PublishedState == PublishedState.Unpublishing)
|
||||
if (((Content) content).PublishedState == PublishedState.Unpublishing)
|
||||
{
|
||||
db.Execute("DELETE FROM cmsContentNu WHERE nodeId=@id AND published=1", new { id = content.Id });
|
||||
return;
|
||||
|
||||
@@ -12,13 +12,13 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
{
|
||||
internal class MediaCache : PublishedCacheBase, IPublishedMediaCache, INavigableData, IDisposable
|
||||
{
|
||||
private readonly ContentStore2.Snapshot _snapshot;
|
||||
private readonly ContentStore.Snapshot _snapshot;
|
||||
private readonly ICacheProvider _facadeCache;
|
||||
private readonly ICacheProvider _snapshotCache;
|
||||
|
||||
#region Constructors
|
||||
|
||||
public MediaCache(bool previewDefault, ContentStore2.Snapshot snapshot, ICacheProvider facadeCache, ICacheProvider snapshotCache)
|
||||
public MediaCache(bool previewDefault, ContentStore.Snapshot snapshot, ICacheProvider facadeCache, ICacheProvider snapshotCache)
|
||||
: base(previewDefault)
|
||||
{
|
||||
_snapshot = snapshot;
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
|
||||
namespace Umbraco.Web.PublishedCache.NuCache.Navigable
|
||||
{
|
||||
interface INavigableData
|
||||
internal interface INavigableData
|
||||
{
|
||||
IPublishedContent GetById(bool preview, int contentId);
|
||||
IEnumerable<IPublishedContent> GetAtRoot(bool preview);
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.Xml.XPath;
|
||||
|
||||
namespace Umbraco.Web.PublishedCache.NuCache.Navigable
|
||||
{
|
||||
class NavigableContent : INavigableContent
|
||||
internal class NavigableContent : INavigableContent
|
||||
{
|
||||
private readonly IPublishedContent _icontent;
|
||||
private readonly PublishedContent _content;
|
||||
@@ -61,36 +60,21 @@ namespace Umbraco.Web.PublishedCache.NuCache.Navigable
|
||||
|
||||
#region INavigableContent
|
||||
|
||||
public IPublishedContent InnerContent
|
||||
{
|
||||
get { return _icontent; }
|
||||
}
|
||||
public IPublishedContent InnerContent => _icontent;
|
||||
|
||||
public int Id
|
||||
{
|
||||
get { return _content.Id; }
|
||||
}
|
||||
public int Id => _content.Id;
|
||||
|
||||
public int ParentId
|
||||
{
|
||||
get { return _content.ParentId; }
|
||||
}
|
||||
public int ParentId => _content.ParentId;
|
||||
|
||||
public INavigableContentType Type
|
||||
{
|
||||
get { return NavigableContentType.GetContentType(_content.ContentType); }
|
||||
}
|
||||
public INavigableContentType Type => NavigableContentType.GetContentType(_content.ContentType);
|
||||
|
||||
// returns all child ids, will be filtered by the source
|
||||
public IList<int> ChildIds
|
||||
{
|
||||
get { return _content.ChildIds; }
|
||||
}
|
||||
public IList<int> ChildIds => _content.ChildIds;
|
||||
|
||||
public object Value(int index)
|
||||
{
|
||||
if (index < 0)
|
||||
throw new ArgumentOutOfRangeException("index");
|
||||
throw new ArgumentOutOfRangeException(nameof(index));
|
||||
|
||||
if (index < NavigableContentType.BuiltinProperties.Length)
|
||||
{
|
||||
@@ -102,7 +86,7 @@ namespace Umbraco.Web.PublishedCache.NuCache.Navigable
|
||||
index -= NavigableContentType.BuiltinProperties.Length;
|
||||
var properties = _content.PropertiesArray;
|
||||
if (index >= properties.Length)
|
||||
throw new ArgumentOutOfRangeException("index");
|
||||
throw new ArgumentOutOfRangeException(nameof(index));
|
||||
|
||||
// custom property, ie element
|
||||
return properties[index].XPathValue;
|
||||
|
||||
@@ -7,7 +7,7 @@ using Umbraco.Core.Xml.XPath;
|
||||
|
||||
namespace Umbraco.Web.PublishedCache.NuCache.Navigable
|
||||
{
|
||||
class NavigableContentType : INavigableContentType
|
||||
internal class NavigableContentType : INavigableContentType
|
||||
{
|
||||
public static readonly INavigableFieldType[] BuiltinProperties;
|
||||
private readonly object _locko = new object();
|
||||
@@ -22,7 +22,7 @@ namespace Umbraco.Web.PublishedCache.NuCache.Navigable
|
||||
// changes, but they are replaced by a new instance, so our map here will clean itself automatically and
|
||||
// we don't have to manage cache - ConditionalWeakTable does not prevent keys from beeing GCed
|
||||
|
||||
static private readonly ConditionalWeakTable<PublishedContentType, NavigableContentType> TypesMap
|
||||
private static readonly ConditionalWeakTable<PublishedContentType, NavigableContentType> TypesMap
|
||||
= new ConditionalWeakTable<PublishedContentType,NavigableContentType>();
|
||||
|
||||
public static NavigableContentType GetContentType(PublishedContentType contentType)
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace Umbraco.Web.PublishedCache.NuCache.Navigable
|
||||
XmlStringConverter = xmlStringConverter;
|
||||
}
|
||||
|
||||
public string Name { get; private set; }
|
||||
public Func<object, string> XmlStringConverter { get; private set; }
|
||||
public string Name { get; }
|
||||
public Func<object, string> XmlStringConverter { get; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ using Umbraco.Core.Xml.XPath;
|
||||
|
||||
namespace Umbraco.Web.PublishedCache.NuCache.Navigable
|
||||
{
|
||||
class RootContent : INavigableContent
|
||||
internal class RootContent : INavigableContent
|
||||
{
|
||||
private static readonly RootContentType ContentType = new RootContentType();
|
||||
private readonly int[] _childIds;
|
||||
@@ -14,25 +14,13 @@ namespace Umbraco.Web.PublishedCache.NuCache.Navigable
|
||||
_childIds = childIds.ToArray();
|
||||
}
|
||||
|
||||
public int Id
|
||||
{
|
||||
get { return -1; }
|
||||
}
|
||||
public int Id => -1;
|
||||
|
||||
public int ParentId
|
||||
{
|
||||
get { return -1; }
|
||||
}
|
||||
public int ParentId => -1;
|
||||
|
||||
public INavigableContentType Type
|
||||
{
|
||||
get { return ContentType; }
|
||||
}
|
||||
public INavigableContentType Type => ContentType;
|
||||
|
||||
public IList<int> ChildIds
|
||||
{
|
||||
get { return _childIds; }
|
||||
}
|
||||
public IList<int> ChildIds => _childIds;
|
||||
|
||||
public object Value(int index)
|
||||
{
|
||||
@@ -40,17 +28,11 @@ namespace Umbraco.Web.PublishedCache.NuCache.Navigable
|
||||
return index == 0 ? "-1" : null;
|
||||
}
|
||||
|
||||
class RootContentType : INavigableContentType
|
||||
private class RootContentType : INavigableContentType
|
||||
{
|
||||
public string Name
|
||||
{
|
||||
get { return "root"; }
|
||||
}
|
||||
public string Name => "root";
|
||||
|
||||
public INavigableFieldType[] FieldTypes
|
||||
{
|
||||
get { return NavigableContentType.BuiltinProperties; }
|
||||
}
|
||||
public INavigableFieldType[] FieldTypes => NavigableContentType.BuiltinProperties;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ using Umbraco.Core.Xml.XPath;
|
||||
|
||||
namespace Umbraco.Web.PublishedCache.NuCache.Navigable
|
||||
{
|
||||
class Source : INavigableSource
|
||||
internal class Source : INavigableSource
|
||||
{
|
||||
private readonly INavigableData _data;
|
||||
private readonly bool _preview;
|
||||
@@ -26,14 +26,8 @@ namespace Umbraco.Web.PublishedCache.NuCache.Navigable
|
||||
return content == null ? null : new NavigableContent(content);
|
||||
}
|
||||
|
||||
public int LastAttributeIndex
|
||||
{
|
||||
get { return NavigableContentType.BuiltinProperties.Length - 1; }
|
||||
}
|
||||
public int LastAttributeIndex => NavigableContentType.BuiltinProperties.Length - 1;
|
||||
|
||||
public INavigableContent Root
|
||||
{
|
||||
get { return _root; }
|
||||
}
|
||||
public INavigableContent Root => _root;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
{
|
||||
[Serializable]
|
||||
[XmlType(Namespace = "http://umbraco.org/webservices/")]
|
||||
class Property : PublishedPropertyBase
|
||||
internal class Property : PublishedPropertyBase
|
||||
{
|
||||
private readonly IFacadeAccessor _facadeAccessor;
|
||||
private readonly object _sourceValue;
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.ServiceModel.Security;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Web.PublishedCache.NuCache.DataSource;
|
||||
@@ -13,7 +11,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
// the whole PublishedMember thing should be refactored because as soon as a member
|
||||
// is wrapped on in a model, the inner IMember and all associated properties are lost
|
||||
|
||||
class PublishedMember : PublishedContent //, IPublishedMember
|
||||
internal class PublishedMember : PublishedContent //, IPublishedMember
|
||||
{
|
||||
private readonly IMember _member;
|
||||
|
||||
@@ -87,65 +85,29 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
|
||||
#region IPublishedMember
|
||||
|
||||
public IMember Member
|
||||
{
|
||||
get { return _member; }
|
||||
}
|
||||
public IMember Member => _member;
|
||||
|
||||
public string Email
|
||||
{
|
||||
get { return _member.Email; }
|
||||
}
|
||||
public string Email => _member.Email;
|
||||
|
||||
public string UserName
|
||||
{
|
||||
get { return _member.Username; }
|
||||
}
|
||||
public string UserName => _member.Username;
|
||||
|
||||
public string PasswordQuestion
|
||||
{
|
||||
get { return _member.PasswordQuestion; }
|
||||
}
|
||||
public string PasswordQuestion => _member.PasswordQuestion;
|
||||
|
||||
public string Comments
|
||||
{
|
||||
get { return _member.Comments; }
|
||||
}
|
||||
public string Comments => _member.Comments;
|
||||
|
||||
public bool IsApproved
|
||||
{
|
||||
get { return _member.IsApproved; }
|
||||
}
|
||||
public bool IsApproved => _member.IsApproved;
|
||||
|
||||
public bool IsLockedOut
|
||||
{
|
||||
get { return _member.IsLockedOut; }
|
||||
}
|
||||
public bool IsLockedOut => _member.IsLockedOut;
|
||||
|
||||
public DateTime LastLockoutDate
|
||||
{
|
||||
get { return _member.LastLockoutDate; }
|
||||
}
|
||||
public DateTime LastLockoutDate => _member.LastLockoutDate;
|
||||
|
||||
public DateTime CreationDate
|
||||
{
|
||||
get { return _member.CreateDate; }
|
||||
}
|
||||
public DateTime CreationDate => _member.CreateDate;
|
||||
|
||||
public DateTime LastLoginDate
|
||||
{
|
||||
get { return _member.LastLoginDate; }
|
||||
}
|
||||
public DateTime LastLoginDate => _member.LastLoginDate;
|
||||
|
||||
public DateTime LastActivityDate
|
||||
{
|
||||
get { return _member.LastLoginDate; }
|
||||
}
|
||||
public DateTime LastActivityDate => _member.LastLoginDate;
|
||||
|
||||
public DateTime LastPasswordChangedDate
|
||||
{
|
||||
get { return _member.LastPasswordChangeDate; }
|
||||
}
|
||||
public DateTime LastPasswordChangedDate => _member.LastPasswordChangeDate;
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -164,10 +164,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
|
||||
#region Set, Clear, Get, Has
|
||||
|
||||
public int Count
|
||||
{
|
||||
get { return _items.Count; }
|
||||
}
|
||||
public int Count => _items.Count;
|
||||
|
||||
private LinkedNode GetHead(TKey key)
|
||||
{
|
||||
@@ -187,7 +184,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
// already in the dict
|
||||
if (link.Gen != _liveGen)
|
||||
{
|
||||
// for an older gen - if value is different then insert a new
|
||||
// for an older gen - if value is different then insert a new
|
||||
// link for the new gen, with the new value
|
||||
if (link.Value != value)
|
||||
_items.TryUpdate(key, new LinkedNode(value, _liveGen, link), link);
|
||||
@@ -349,7 +346,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
{
|
||||
if (_collectTask != null)
|
||||
return _collectTask;
|
||||
|
||||
|
||||
// ReSharper disable InconsistentlySynchronizedField
|
||||
var task = _collectTask = Task.Run(() => Collect());
|
||||
_collectTask.ContinueWith(_ =>
|
||||
@@ -398,7 +395,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
var link = kvp.Value;
|
||||
|
||||
//Console.WriteLine("Collect id=" + kvp.Key + " gen=" + link.Gen
|
||||
// + " nxt=" + (link.Next == null ? null : "next")
|
||||
// + " nxt=" + (link.Next == null ? null : "next")
|
||||
// + " val=" + link.Value);
|
||||
|
||||
// reasons to collect the head:
|
||||
@@ -409,7 +406,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
if (link.Gen < liveGen && link.Value == null
|
||||
&& (link.Next == null || link.Gen <= _floorGen))
|
||||
{
|
||||
// not live, null value, no next link = remove that one -- but only if
|
||||
// not live, null value, no next link = remove that one -- but only if
|
||||
// the dict has not been updated, have to do it via ICollection<> (thanks
|
||||
// Mr Toub) -- and if the dict has been updated there is nothing to collect
|
||||
var idict = dict as ICollection<KeyValuePair<TKey, LinkedNode>>;
|
||||
@@ -442,18 +439,9 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
// await task;
|
||||
}
|
||||
|
||||
public long GenCount
|
||||
{
|
||||
get { return _generationObjects.Count; }
|
||||
}
|
||||
public long GenCount => _generationObjects.Count;
|
||||
|
||||
public long SnapCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return _generationObjects.Sum(x => x.Count);
|
||||
}
|
||||
}
|
||||
public long SnapCount => _generationObjects.Sum(x => x.Count);
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -471,12 +459,17 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
_dict = dict;
|
||||
}
|
||||
|
||||
public long LiveGen { get { return _dict._liveGen; } }
|
||||
public long FloorGen { get { return _dict._floorGen; } }
|
||||
public bool NextGen { get { return _dict._nextGen; } }
|
||||
public bool CollectAuto { get { return _dict._collectAuto; } set { _dict._collectAuto = value; } }
|
||||
public long LiveGen => _dict._liveGen;
|
||||
public long FloorGen => _dict._floorGen;
|
||||
public bool NextGen => _dict._nextGen;
|
||||
|
||||
public ConcurrentQueue<GenerationObject> GenerationObjects { get { return _dict._generationObjects; } }
|
||||
public bool CollectAuto
|
||||
{
|
||||
get => _dict._collectAuto;
|
||||
set => _dict._collectAuto = value;
|
||||
}
|
||||
|
||||
public ConcurrentQueue<GenerationObject> GenerationObjects => _dict._generationObjects;
|
||||
|
||||
public GenVal[] GetValues(TKey key)
|
||||
{
|
||||
@@ -503,13 +496,13 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public long Gen { get; private set; }
|
||||
public TValue Value { get; private set; }
|
||||
public long Gen { get; }
|
||||
public TValue Value { get; }
|
||||
}
|
||||
}
|
||||
|
||||
internal TestHelper Test { get { return _unitTesting ?? (_unitTesting = new TestHelper(this)); } }
|
||||
|
||||
internal TestHelper Test => _unitTesting ?? (_unitTesting = new TestHelper(this));
|
||||
|
||||
#endregion
|
||||
|
||||
#region Classes
|
||||
|
||||
@@ -228,7 +228,7 @@
|
||||
<Compile Include="PublishedCache\NuCache\ContentCache.cs" />
|
||||
<Compile Include="PublishedCache\NuCache\ContentNode.cs" />
|
||||
<Compile Include="PublishedCache\NuCache\ContentNodeKit.cs" />
|
||||
<Compile Include="PublishedCache\NuCache\ContentStore2.cs" />
|
||||
<Compile Include="PublishedCache\NuCache\ContentStore.cs" />
|
||||
<Compile Include="PublishedCache\NuCache\DataSource\BTree.cs" />
|
||||
<Compile Include="PublishedCache\NuCache\DataSource\ContentData.cs" />
|
||||
<Compile Include="PublishedCache\NuCache\DataSource\ContentSourceDto.cs" />
|
||||
|
||||
Reference in New Issue
Block a user