// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.AspNet.FileProviders;
using Microsoft.AspNet.Razor.Generator.Compiler;
using Microsoft.Framework.Caching.Memory;
using Microsoft.Framework.Internal;
namespace Microsoft.AspNet.Mvc.Razor.Directives
{
///
/// Default implementation of .
///
public class DefaultCodeTreeCache : ICodeTreeCache
{
private static readonly MemoryCacheOptions MemoryCacheOptions = new MemoryCacheOptions
{
CompactOnMemoryPressure = false
};
private static readonly TimeSpan SlidingExpirationDuration = TimeSpan.FromMinutes(1);
private readonly IFileProvider _fileProvider;
private readonly IMemoryCache _codeTreeCache;
///
/// Initializes a new instance of .
///
/// The application's .
public DefaultCodeTreeCache(IFileProvider fileProvider)
: this(fileProvider, MemoryCacheOptions)
{
}
// Internal for unit testing
internal DefaultCodeTreeCache(IFileProvider fileProvider,
MemoryCacheOptions options)
{
_fileProvider = fileProvider;
_codeTreeCache = new MemoryCache(options);
}
///
public CodeTree GetOrAdd([NotNull] string pagePath,
[NotNull] Func getCodeTree)
{
CodeTree codeTree;
if (!_codeTreeCache.TryGetValue(pagePath, out codeTree))
{
// GetOrAdd is invoked for each _GlobalImport that might potentially exist in the path.
// We can avoid performing file system lookups for files that do not exist by caching
// negative results and adding a Watch for that file.
var options = new MemoryCacheEntryOptions()
.AddExpirationTrigger(_fileProvider.Watch(pagePath))
.SetSlidingExpiration(SlidingExpirationDuration);
var file = _fileProvider.GetFileInfo(pagePath);
codeTree = file.Exists ? getCodeTree(file) : null;
_codeTreeCache.Set(pagePath, codeTree, options);
}
return codeTree;
}
}
}