You've already forked linux-packaging-mono
Imported Upstream version 4.6.0.125
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
This commit is contained in:
parent
a569aebcfd
commit
e79aa3c0ed
@@ -0,0 +1,24 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="AssemblyInfo.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Reflection;
|
||||
using System.Resources;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Permissions;
|
||||
using System.Security;
|
||||
|
||||
// We can't make it SecurityTransparent due to performance implications
|
||||
//[assembly: SecurityTransparent]
|
||||
#pragma warning disable 618
|
||||
[assembly: SecurityPermission(SecurityAction.RequestMinimum, Execution = true)]
|
||||
#pragma warning restore 618
|
||||
|
||||
[assembly: SuppressMessage("Microsoft.Design", "CA2210:AssembliesShouldHaveValidStrongNames",
|
||||
Justification = "Assembly is delay-signed.")]
|
||||
|
||||
244
mcs/class/referencesource/System.Runtime.Caching/Resources/R.Designer.cs
generated
Normal file
244
mcs/class/referencesource/System.Runtime.Caching/Resources/R.Designer.cs
generated
Normal file
@@ -0,0 +1,244 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.20414.0
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.Runtime.Caching.Resources {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class R {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Grandfathered suppression from original caching code checkin")]
|
||||
internal R() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("System.Runtime.Caching.Resources.R", typeof(R).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to '{0}' must be greater than or equal to '{1}' and less than or equal to '{2}'..
|
||||
/// </summary>
|
||||
internal static string Argument_out_of_range {
|
||||
get {
|
||||
return ResourceManager.GetString("Argument_out_of_range", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The collection '{0}' contains a null element..
|
||||
/// </summary>
|
||||
internal static string Collection_contains_null_element {
|
||||
get {
|
||||
return ResourceManager.GetString("Collection_contains_null_element", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The collection '{0}' contains a null or empty string..
|
||||
/// </summary>
|
||||
internal static string Collection_contains_null_or_empty_string {
|
||||
get {
|
||||
return ResourceManager.GetString("Collection_contains_null_or_empty_string", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Unable to retrieve configuration section '{0}'..
|
||||
/// </summary>
|
||||
internal static string Config_unable_to_get_section {
|
||||
get {
|
||||
return ResourceManager.GetString("Config_unable_to_get_section", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Default is a reserved MemoryCache name..
|
||||
/// </summary>
|
||||
internal static string Default_is_reserved {
|
||||
get {
|
||||
return ResourceManager.GetString("Default_is_reserved", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The collection '{0}' is empty..
|
||||
/// </summary>
|
||||
internal static string Empty_collection {
|
||||
get {
|
||||
return ResourceManager.GetString("Empty_collection", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Initialization has not completed yet. The InitializationComplete method must be invoked before Dispose is invoked..
|
||||
/// </summary>
|
||||
internal static string Init_not_complete {
|
||||
get {
|
||||
return ResourceManager.GetString("Init_not_complete", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to One of the following parameters must be specified: dependencies, absoluteExpiration, slidingExpiration..
|
||||
/// </summary>
|
||||
internal static string Invalid_argument_combination {
|
||||
get {
|
||||
return ResourceManager.GetString("Invalid_argument_combination", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Only one callback can be specified. Either RemovedCallback or UpdateCallback must be null..
|
||||
/// </summary>
|
||||
internal static string Invalid_callback_combination {
|
||||
get {
|
||||
return ResourceManager.GetString("Invalid_callback_combination", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to AbsoluteExpiration must be DateTimeOffset.MaxValue or SlidingExpiration must be TimeSpan.Zero..
|
||||
/// </summary>
|
||||
internal static string Invalid_expiration_combination {
|
||||
get {
|
||||
return ResourceManager.GetString("Invalid_expiration_combination", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Invalid state..
|
||||
/// </summary>
|
||||
internal static string Invalid_state {
|
||||
get {
|
||||
return ResourceManager.GetString("Invalid_state", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The method has already been invoked, and can only be invoked once..
|
||||
/// </summary>
|
||||
internal static string Method_already_invoked {
|
||||
get {
|
||||
return ResourceManager.GetString("Method_already_invoked", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The property has already been set, and can only be set once..
|
||||
/// </summary>
|
||||
internal static string Property_already_set {
|
||||
get {
|
||||
return ResourceManager.GetString("Property_already_set", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Invalid configuration: {0}="{1}". The {0} value must be a time interval that can be parsed by System.TimeSpan.Parse..
|
||||
/// </summary>
|
||||
internal static string TimeSpan_invalid_format {
|
||||
get {
|
||||
return ResourceManager.GetString("TimeSpan_invalid_format", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CacheItemUpdateCallback must be null..
|
||||
/// </summary>
|
||||
internal static string Update_callback_must_be_null {
|
||||
get {
|
||||
return ResourceManager.GetString("Update_callback_must_be_null", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Invalid configuration: {0}="{1}". The {0} value must be a non-negative 32-bit integer..
|
||||
/// </summary>
|
||||
internal static string Value_must_be_non_negative_integer {
|
||||
get {
|
||||
return ResourceManager.GetString("Value_must_be_non_negative_integer", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Invalid configuration: {0}="{1}". The {0} value must be a positive 32-bit integer..
|
||||
/// </summary>
|
||||
internal static string Value_must_be_positive_integer {
|
||||
get {
|
||||
return ResourceManager.GetString("Value_must_be_positive_integer", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Invalid configuration: {0}="{1}". The {0} value cannot be greater than '{2}'..
|
||||
/// </summary>
|
||||
internal static string Value_too_big {
|
||||
get {
|
||||
return ResourceManager.GetString("Value_too_big", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to An empty string is invalid..
|
||||
/// </summary>
|
||||
internal static string Empty_string_invalid {
|
||||
get {
|
||||
return ResourceManager.GetString("Empty_string_invalid", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The parameter regionName must be null..
|
||||
/// </summary>
|
||||
internal static string RegionName_not_supported {
|
||||
get {
|
||||
return ResourceManager.GetString("RegionName_not_supported", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
|
||||
namespace System.Runtime.Caching.Resources
|
||||
{
|
||||
internal static class RH
|
||||
{
|
||||
public static string Format(string resource, params object[] args) {
|
||||
return String.Format(CultureInfo.CurrentCulture, resource, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// <copyright file="CacheEntryChangeMonitor.cs" company="Microsoft">
|
||||
// Copyright (c) 2009 Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace System.Runtime.Caching {
|
||||
public abstract class CacheEntryChangeMonitor : ChangeMonitor {
|
||||
public abstract ReadOnlyCollection<string> CacheKeys { get; }
|
||||
public abstract DateTimeOffset LastModified { get; }
|
||||
public abstract String RegionName { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
// <copyright file="CacheEntryRemovedArguments.cs" company="Microsoft">
|
||||
// Copyright (c) 2009 Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace System.Runtime.Caching {
|
||||
public class CacheEntryRemovedArguments {
|
||||
private CacheItem _cacheItem;
|
||||
private ObjectCache _source;
|
||||
private CacheEntryRemovedReason _reason;
|
||||
|
||||
public CacheItem CacheItem {
|
||||
get { return _cacheItem; }
|
||||
}
|
||||
|
||||
public CacheEntryRemovedReason RemovedReason {
|
||||
get { return _reason; }
|
||||
}
|
||||
|
||||
public ObjectCache Source {
|
||||
get { return _source; }
|
||||
}
|
||||
|
||||
public CacheEntryRemovedArguments(ObjectCache source, CacheEntryRemovedReason reason, CacheItem cacheItem) {
|
||||
if (source == null) {
|
||||
throw new ArgumentNullException("source");
|
||||
}
|
||||
if (cacheItem == null) {
|
||||
throw new ArgumentNullException("cacheItem");
|
||||
}
|
||||
_source = source;
|
||||
_reason = reason;
|
||||
_cacheItem = cacheItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
// <copyright file="CacheEntryUpdateRemoved.cs" company="Microsoft">
|
||||
// Copyright (c) 2009 Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
using System;
|
||||
|
||||
namespace System.Runtime.Caching {
|
||||
public delegate void CacheEntryRemovedCallback(CacheEntryRemovedArguments arguments);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// <copyright file="CacheEntryRemovedReason.cs" company="Microsoft">
|
||||
// Copyright (c) 2009 Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
using System;
|
||||
|
||||
namespace System.Runtime.Caching {
|
||||
public enum CacheEntryRemovedReason {
|
||||
Removed = 0, //Explicitly removed via API call
|
||||
Expired,
|
||||
Evicted, //Evicted to free up space
|
||||
ChangeMonitorChanged, //An associated programmatic dependency triggered eviction
|
||||
CacheSpecificEviction //Catch-all for custom providers
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
// <copyright file="CacheEntryUpdateArguments.cs" company="Microsoft">
|
||||
// Copyright (c) 2009 Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
using System;
|
||||
|
||||
namespace System.Runtime.Caching {
|
||||
public class CacheEntryUpdateArguments {
|
||||
private String _key;
|
||||
private CacheEntryRemovedReason _reason;
|
||||
private String _regionName;
|
||||
private ObjectCache _source;
|
||||
private CacheItem _updatedCacheItem;
|
||||
private CacheItemPolicy _updatedCacheItemPolicy;
|
||||
|
||||
public String Key {
|
||||
get { return _key; }
|
||||
}
|
||||
|
||||
public CacheEntryRemovedReason RemovedReason {
|
||||
get { return _reason; }
|
||||
}
|
||||
|
||||
public String RegionName {
|
||||
get { return _regionName; }
|
||||
}
|
||||
|
||||
public ObjectCache Source {
|
||||
get { return _source; }
|
||||
}
|
||||
|
||||
public CacheItem UpdatedCacheItem {
|
||||
get { return _updatedCacheItem; }
|
||||
set { _updatedCacheItem = value; }
|
||||
}
|
||||
|
||||
public CacheItemPolicy UpdatedCacheItemPolicy {
|
||||
get { return _updatedCacheItemPolicy; }
|
||||
set { _updatedCacheItemPolicy = value; }
|
||||
}
|
||||
|
||||
public CacheEntryUpdateArguments(ObjectCache source, CacheEntryRemovedReason reason, String key, String regionName) {
|
||||
if (source == null) {
|
||||
throw new ArgumentNullException("source");
|
||||
}
|
||||
if (key == null) {
|
||||
throw new ArgumentNullException("key");
|
||||
}
|
||||
_source = source;
|
||||
_reason = reason;
|
||||
_key = key;
|
||||
_regionName = regionName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
// <copyright file="CacheEntryUpdateCallback.cs" company="Microsoft">
|
||||
// Copyright (c) 2009 Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
using System;
|
||||
|
||||
namespace System.Runtime.Caching {
|
||||
public delegate void CacheEntryUpdateCallback(CacheEntryUpdateArguments arguments);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// <copyright file="CacheItem.cs" company="Microsoft">
|
||||
// Copyright (c) 2009 Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
|
||||
using System;
|
||||
|
||||
namespace System.Runtime.Caching {
|
||||
public class CacheItem {
|
||||
public string Key { get; set; }
|
||||
public object Value { get; set; }
|
||||
public string RegionName { get; set; }
|
||||
|
||||
private CacheItem() { } // hide default constructor
|
||||
|
||||
public CacheItem(string key) {
|
||||
Key = key;
|
||||
}
|
||||
|
||||
public CacheItem(string key, object value) : this(key) {
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public CacheItem(string key, object value, string regionName) : this(key, value) {
|
||||
RegionName = regionName;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
// <copyright file="CacheItemPolicy.cs" company="Microsoft">
|
||||
// Copyright (c) 2009 Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace System.Runtime.Caching {
|
||||
public class CacheItemPolicy {
|
||||
private DateTimeOffset _absExpiry;
|
||||
private TimeSpan _sldExpiry;
|
||||
private Collection<ChangeMonitor> _changeMonitors;
|
||||
private CacheItemPriority _priority;
|
||||
private CacheEntryRemovedCallback _removedCallback;
|
||||
private CacheEntryUpdateCallback _updateCallback;
|
||||
|
||||
public DateTimeOffset AbsoluteExpiration {
|
||||
get { return _absExpiry; }
|
||||
set { _absExpiry = value; }
|
||||
}
|
||||
|
||||
public Collection<ChangeMonitor> ChangeMonitors {
|
||||
get {
|
||||
if (_changeMonitors == null) {
|
||||
_changeMonitors = new Collection<ChangeMonitor>();
|
||||
}
|
||||
return _changeMonitors;
|
||||
}
|
||||
}
|
||||
|
||||
public CacheItemPriority Priority {
|
||||
get { return _priority; }
|
||||
set { _priority = value; }
|
||||
}
|
||||
|
||||
public CacheEntryRemovedCallback RemovedCallback {
|
||||
get { return _removedCallback; }
|
||||
set { _removedCallback = value; }
|
||||
}
|
||||
|
||||
public TimeSpan SlidingExpiration {
|
||||
get { return _sldExpiry; }
|
||||
set { _sldExpiry = value; }
|
||||
}
|
||||
|
||||
public CacheEntryUpdateCallback UpdateCallback {
|
||||
get { return _updateCallback; }
|
||||
set { _updateCallback = value; }
|
||||
}
|
||||
|
||||
public CacheItemPolicy() {
|
||||
_absExpiry = ObjectCache.InfiniteAbsoluteExpiration;
|
||||
_sldExpiry = ObjectCache.NoSlidingExpiration;
|
||||
_priority = CacheItemPriority.Default;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// <copyright file="CacheItemPriority.cs" company="Microsoft">
|
||||
// Copyright (c) 2009 Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
using System;
|
||||
|
||||
namespace System.Runtime.Caching {
|
||||
public enum CacheItemPriority {
|
||||
Default = 0,
|
||||
NotRemovable
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,259 @@
|
||||
// <copyright file="CacheMemoryMonitor.cs" company="Microsoft">
|
||||
// Copyright (c) 2009 Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
using System;
|
||||
using System.Runtime.Caching.Configuration;
|
||||
using System.Runtime.Caching.Hosting;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Security;
|
||||
using System.Security.Permissions;
|
||||
using System.Threading;
|
||||
|
||||
namespace System.Runtime.Caching {
|
||||
// CacheMemoryMonitor uses the internal System.SizedReference type to determine
|
||||
// the size of the cache itselt, and helps us know when to drop entries to avoid
|
||||
// exceeding the cache's memory limit. The limit is configurable (see ConfigUtil.cs).
|
||||
internal sealed class CacheMemoryMonitor : MemoryMonitor, IDisposable {
|
||||
const long PRIVATE_BYTES_LIMIT_2GB = 800 * MEGABYTE;
|
||||
const long PRIVATE_BYTES_LIMIT_3GB = 1800 * MEGABYTE;
|
||||
const long PRIVATE_BYTES_LIMIT_64BIT = 1L * TERABYTE;
|
||||
const int SAMPLE_COUNT = 2;
|
||||
|
||||
private static IMemoryCacheManager s_memoryCacheManager;
|
||||
private static long s_autoPrivateBytesLimit = -1;
|
||||
private static long s_effectiveProcessMemoryLimit = -1;
|
||||
|
||||
private MemoryCache _memoryCache;
|
||||
private long[] _cacheSizeSamples;
|
||||
private DateTime[] _cacheSizeSampleTimes;
|
||||
private int _idx;
|
||||
private SRef _sizedRef;
|
||||
private int _gen2Count;
|
||||
private long _memoryLimit;
|
||||
|
||||
internal long MemoryLimit {
|
||||
get { return _memoryLimit; }
|
||||
}
|
||||
|
||||
private CacheMemoryMonitor() {
|
||||
// hide default ctor
|
||||
}
|
||||
|
||||
internal CacheMemoryMonitor(MemoryCache memoryCache, int cacheMemoryLimitMegabytes) {
|
||||
_memoryCache = memoryCache;
|
||||
_gen2Count = GC.CollectionCount(2);
|
||||
_cacheSizeSamples = new long[SAMPLE_COUNT];
|
||||
_cacheSizeSampleTimes = new DateTime[SAMPLE_COUNT];
|
||||
InitMemoryCacheManager();
|
||||
InitDisposableMembers(cacheMemoryLimitMegabytes);
|
||||
}
|
||||
|
||||
private void InitDisposableMembers(int cacheMemoryLimitMegabytes) {
|
||||
bool dispose = true;
|
||||
try {
|
||||
_sizedRef = new SRef(_memoryCache);
|
||||
SetLimit(cacheMemoryLimitMegabytes);
|
||||
InitHistory();
|
||||
dispose = false;
|
||||
}
|
||||
finally {
|
||||
if (dispose) {
|
||||
Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Auto-generate the private bytes limit:
|
||||
// - On 64bit, the auto value is MIN(60% physical_ram, 1 TB)
|
||||
// - On x86, for 2GB, the auto value is MIN(60% physical_ram, 800 MB)
|
||||
// - On x86, for 3GB, the auto value is MIN(60% physical_ram, 1800 MB)
|
||||
//
|
||||
// - If it's not a hosted environment (e.g. console app), the 60% in the above
|
||||
// formulas will become 100% because in un-hosted environment we don't launch
|
||||
// other processes such as compiler, etc.
|
||||
private static long AutoPrivateBytesLimit {
|
||||
get {
|
||||
long memoryLimit = s_autoPrivateBytesLimit;
|
||||
if (memoryLimit == -1) {
|
||||
|
||||
bool is64bit = (IntPtr.Size == 8);
|
||||
|
||||
long totalPhysical = TotalPhysical;
|
||||
long totalVirtual = TotalVirtual;
|
||||
if (totalPhysical != 0) {
|
||||
long recommendedPrivateByteLimit;
|
||||
if (is64bit) {
|
||||
recommendedPrivateByteLimit = PRIVATE_BYTES_LIMIT_64BIT;
|
||||
}
|
||||
else {
|
||||
// Figure out if it's 2GB or 3GB
|
||||
|
||||
if (totalVirtual > 2 * GIGABYTE) {
|
||||
recommendedPrivateByteLimit = PRIVATE_BYTES_LIMIT_3GB;
|
||||
}
|
||||
else {
|
||||
recommendedPrivateByteLimit = PRIVATE_BYTES_LIMIT_2GB;
|
||||
}
|
||||
}
|
||||
|
||||
// use 60% of physical RAM
|
||||
long usableMemory = totalPhysical * 3 / 5;
|
||||
memoryLimit = Math.Min(usableMemory, recommendedPrivateByteLimit);
|
||||
}
|
||||
else {
|
||||
// If GlobalMemoryStatusEx fails, we'll use these as our auto-gen private bytes limit
|
||||
memoryLimit = is64bit ? PRIVATE_BYTES_LIMIT_64BIT : PRIVATE_BYTES_LIMIT_2GB;
|
||||
}
|
||||
Interlocked.Exchange(ref s_autoPrivateBytesLimit, memoryLimit);
|
||||
}
|
||||
|
||||
return memoryLimit;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
SRef sref = _sizedRef;
|
||||
if (sref != null && Interlocked.CompareExchange(ref _sizedRef, null, sref) == sref) {
|
||||
sref.Dispose();
|
||||
}
|
||||
IMemoryCacheManager memoryCacheManager = s_memoryCacheManager;
|
||||
if (memoryCacheManager != null) {
|
||||
memoryCacheManager.ReleaseCache(_memoryCache);
|
||||
}
|
||||
}
|
||||
|
||||
internal static long EffectiveProcessMemoryLimit {
|
||||
get {
|
||||
long memoryLimit = s_effectiveProcessMemoryLimit;
|
||||
if (memoryLimit == -1) {
|
||||
memoryLimit = AutoPrivateBytesLimit;
|
||||
Interlocked.Exchange(ref s_effectiveProcessMemoryLimit, memoryLimit);
|
||||
}
|
||||
return memoryLimit;
|
||||
}
|
||||
}
|
||||
|
||||
protected override int GetCurrentPressure() {
|
||||
// Call GetUpdatedTotalCacheSize to update the total
|
||||
// cache size, if there has been a recent Gen 2 Collection.
|
||||
// This update must happen, otherwise the CacheManager won't
|
||||
// know the total cache size.
|
||||
int gen2Count = GC.CollectionCount(2);
|
||||
SRef sref = _sizedRef;
|
||||
if (gen2Count != _gen2Count && sref != null) {
|
||||
// update _gen2Count
|
||||
_gen2Count = gen2Count;
|
||||
|
||||
// the SizedRef is only updated after a Gen2 Collection
|
||||
|
||||
// increment the index (it's either 1 or 0)
|
||||
Dbg.Assert(SAMPLE_COUNT == 2);
|
||||
_idx = _idx ^ 1;
|
||||
// remember the sample time
|
||||
_cacheSizeSampleTimes[_idx] = DateTime.UtcNow;
|
||||
// remember the sample value
|
||||
_cacheSizeSamples[_idx] = sref.ApproximateSize;
|
||||
#if DBG
|
||||
Dbg.Trace("MemoryCacheStats", "SizedRef.ApproximateSize=" + _cacheSizeSamples[_idx]);
|
||||
#endif
|
||||
IMemoryCacheManager memoryCacheManager = s_memoryCacheManager;
|
||||
if (memoryCacheManager != null) {
|
||||
memoryCacheManager.UpdateCacheSize(_cacheSizeSamples[_idx], _memoryCache);
|
||||
}
|
||||
}
|
||||
|
||||
// if there's no memory limit, then there's nothing more to do
|
||||
if (_memoryLimit <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
long cacheSize = _cacheSizeSamples[_idx];
|
||||
|
||||
// use _memoryLimit as an upper bound so that pressure is a percentage (between 0 and 100, inclusive).
|
||||
if (cacheSize > _memoryLimit) {
|
||||
cacheSize = _memoryLimit;
|
||||
}
|
||||
|
||||
// PerfCounter: Cache Percentage Process Memory Limit Used
|
||||
// = memory used by this process / process memory limit at pressureHigh
|
||||
// Set private bytes used in kilobytes because the counter is a DWORD
|
||||
|
||||
//
|
||||
|
||||
|
||||
int result = (int)(cacheSize * 100 / _memoryLimit);
|
||||
return result;
|
||||
}
|
||||
|
||||
internal override int GetPercentToTrim(DateTime lastTrimTime, int lastTrimPercent) {
|
||||
int percent = 0;
|
||||
if (IsAboveHighPressure()) {
|
||||
long cacheSize = _cacheSizeSamples[_idx];
|
||||
if (cacheSize > _memoryLimit) {
|
||||
percent = Math.Min(100, (int)((cacheSize - _memoryLimit) * 100L / cacheSize));
|
||||
}
|
||||
|
||||
#if PERF
|
||||
SafeNativeMethods.OutputDebugString(String.Format("CacheMemoryMonitor.GetPercentToTrim: percent={0:N}, lastTrimPercent={1:N}\n",
|
||||
percent,
|
||||
lastTrimPercent));
|
||||
#endif
|
||||
|
||||
}
|
||||
return percent;
|
||||
}
|
||||
|
||||
internal void SetLimit(int cacheMemoryLimitMegabytes) {
|
||||
long cacheMemoryLimit = cacheMemoryLimitMegabytes;
|
||||
cacheMemoryLimit = cacheMemoryLimit << MEGABYTE_SHIFT;
|
||||
|
||||
//
|
||||
_memoryLimit = 0;
|
||||
|
||||
// VSWhidbey 546381: never override what the user specifies as the limit;
|
||||
// only call AutoPrivateBytesLimit when the user does not specify one.
|
||||
if (cacheMemoryLimit == 0 && _memoryLimit == 0) {
|
||||
// Zero means we impose a limit
|
||||
_memoryLimit = EffectiveProcessMemoryLimit;
|
||||
}
|
||||
else if (cacheMemoryLimit != 0 && _memoryLimit != 0) {
|
||||
// Take the min of "cache memory limit" and the host's "process memory limit".
|
||||
_memoryLimit = Math.Min(_memoryLimit, cacheMemoryLimit);
|
||||
}
|
||||
else if (cacheMemoryLimit != 0) {
|
||||
// _memoryLimit is 0, but "cache memory limit" is non-zero, so use it as the limit
|
||||
_memoryLimit = cacheMemoryLimit;
|
||||
}
|
||||
|
||||
Dbg.Trace("MemoryCacheStats", "CacheMemoryMonitor.SetLimit: _memoryLimit=" + (_memoryLimit >> MEGABYTE_SHIFT) + "Mb");
|
||||
|
||||
if (_memoryLimit > 0) {
|
||||
_pressureHigh = 100;
|
||||
_pressureLow = 80;
|
||||
}
|
||||
else {
|
||||
_pressureHigh = 99;
|
||||
_pressureLow = 97;
|
||||
}
|
||||
|
||||
Dbg.Trace("MemoryCacheStats", "CacheMemoryMonitor.SetLimit: _pressureHigh=" + _pressureHigh +
|
||||
", _pressureLow=" + _pressureLow);
|
||||
}
|
||||
|
||||
[SecuritySafeCritical]
|
||||
[PermissionSet(SecurityAction.Assert, Unrestricted = true)]
|
||||
[SuppressMessage("Microsoft.Security", "CA2106:SecureAsserts", Justification = "Grandfathered suppression from original caching code checkin")]
|
||||
private static void InitMemoryCacheManager() {
|
||||
if (s_memoryCacheManager == null) {
|
||||
IMemoryCacheManager memoryCacheManager = null;
|
||||
IServiceProvider host = ObjectCache.Host;
|
||||
if (host != null) {
|
||||
memoryCacheManager = host.GetService(typeof(IMemoryCacheManager)) as IMemoryCacheManager;
|
||||
}
|
||||
if (memoryCacheManager != null) {
|
||||
Interlocked.CompareExchange(ref s_memoryCacheManager, memoryCacheManager, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,225 @@
|
||||
// <copyright file="ChangeMonitor.cs" company="Microsoft">
|
||||
// Copyright (c) 2009 Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
using System;
|
||||
using System.Runtime.Caching.Resources;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Threading;
|
||||
|
||||
// Every member of this class is thread-safe.
|
||||
//
|
||||
// Derived classes begin monitoring during construction, so that a user can know if the
|
||||
// dependency changed any time after construction. For example, suppose we have a
|
||||
// FileChangeMonitor class that derives from ChangeMonitor. A user might create an instance
|
||||
// of FileChangeMonitor for an XML file, and then read the file to populate an object representation.
|
||||
// The user would then cache the object with the FileChangeMonitor. The user could optionally check the
|
||||
// HasChanged property of the FileChangeMonitor, to see if the XML file changed while the object
|
||||
// was being populated, and if it had changed, they could call Dispose and start over, without
|
||||
// inserting the item into the cache. However, in a multi-threaded environment, for cleaner, easier
|
||||
// to maintain code, it's usually appropriate to just insert without checking HasChanged, since the
|
||||
// cache implementer will handle this for you, and the next thread to attempt to get the object
|
||||
// will recreate and insert it.
|
||||
//
|
||||
// The following contract must be followed by derived classes, cache implementers, and users of the
|
||||
// derived class:
|
||||
//
|
||||
// 1. The constructor of a derived class must set UniqueId, begin monitoring for dependency
|
||||
// changes, and call InitializationComplete before returning. If a dependency changes
|
||||
// before initialization is complete, for example, if a dependent cache key is not found
|
||||
// in the cache, the constructor must invoke OnChanged. The constructor can only call
|
||||
// Dispose after InitializationComplete is called, because Dispose will throw
|
||||
// InvalidOperationException if initialization is not complete.
|
||||
// 2. Once constructed, the user must either insert the ChangeMonitor into an ObjectCache, or
|
||||
// if they're not going to use it, they must call Dispose.
|
||||
// 3. Once inserted into an ObjectCache, the ObjectCache implementation must ensure that the
|
||||
// ChangeMonitor is eventually disposed. Even if the insert is invalid, and results in an
|
||||
// exception being thrown, the ObjectCache implementation must call Dispose. If this we're not
|
||||
// a requirement, users of the ChangeMonitor would need exception handling around each insert
|
||||
// into the cache that carefully ensures the dependency is disposed. While this would work, we
|
||||
// think it is better to put this burden on the ObjectCache implementer, since users are far more
|
||||
// numerous than cache implementers.
|
||||
// 4. After the ChangeMonitor is inserted into a cache, the ObjectCache implementer must call
|
||||
// NotifyOnChanged, passing in an OnChangedCallback. NotifyOnChanged can only be called once,
|
||||
// and will throw InvalidOperationException on subsequent calls. If the dependency has already
|
||||
// changed, the OnChangedCallback will be called when NotifyOnChanged is called. Otherwise, the
|
||||
// OnChangedCallback will be called exactly once, when OnChanged is invoked or when Dispose
|
||||
// is invoked, which ever happens first.
|
||||
// 5. The OnChangedCallback provided by the cache implementer should remove the cache entry, and specify
|
||||
// a reason of CacheEntryRemovedReason.DependencyChanged. Care should be taken to remove the specific
|
||||
// entry having this dependency, and not it's replacement, which will have the same key.
|
||||
// 6. In general, it is okay for OnChanged to be called at any time. If OnChanged is called before
|
||||
// NotifyOnChanged is called, the "state" from the original call to OnChanged will be saved, and the
|
||||
// callback to NotifyOnChange will be called immediately when NotifyOnChanged is invoked.
|
||||
// 7. A derived class must implement Dispose(bool disposing) to release all managed and unmanaged
|
||||
// resources when "disposing" is true. Dispose(true) is only called once, when the instance is
|
||||
// disposed. The derived class must not call Dispose(true) directly--it should only be called by
|
||||
// the ChangeMonitor class, when disposed. Although a derived class could implement a finalizer and
|
||||
// invoke Dispose(false), this is generally not necessary. Dependency monitoring is typically performed
|
||||
// by a service that maintains a reference to the ChangeMonitor, preventing it from being garbage collected,
|
||||
// and making finalizers useless. To help prevent leaks, when a dependency changes, OnChanged disposes
|
||||
// the ChangeMonitor, unless initialization has not yet completed.
|
||||
// 8. Dispose() must be called, and is designed to be called, in one of the following three ways:
|
||||
// - The user must call Dispose() if they decide not to insert the ChangeMonitor into a cache. Otherwise,
|
||||
// the ChangeMonitor will continue monitoring for changes and be unavailable for garbage collection.
|
||||
// - The cache implementor is responsible for calling Dispose() once an attempt is made to insert it.
|
||||
// Even if the insert throws, the cache implementor must dispose the dependency.
|
||||
// Even if the entry is removed, the cache implementor must dispose the dependency.
|
||||
// - The OnChanged method will automatically call Dispose if initialization is complete. Otherwise, when
|
||||
// the derived class' constructor calls InitializationComplete, the instance will be automatically disposed.
|
||||
//
|
||||
// Before inserted into the cache, the user must ensure the dependency is disposed. Once inserted into the
|
||||
// cache, the cache implementer must ensure that Dispose is called, even if the insert fails. After being inserted
|
||||
// into a cache, the user should not dispose the dependency. When Dispose is called, it is treated as if the dependency
|
||||
// changed, and OnChanged is automatically invoked.
|
||||
// 9. HasChanged will be true after OnChanged is called by the derived class, regardless of whether an OnChangedCallback has been set
|
||||
// by a call to NotifyOnChanged.
|
||||
|
||||
namespace System.Runtime.Caching {
|
||||
public abstract class ChangeMonitor : IDisposable {
|
||||
private const int INITIALIZED = 0x01; // initialization complete
|
||||
private const int CHANGED = 0x02; // dependency changed
|
||||
private const int INVOKED = 0x04; // OnChangedCallback has been invoked
|
||||
private const int DISPOSED = 0x08; // Dispose(true) called, or about to be called
|
||||
private readonly static object NOT_SET = new object();
|
||||
|
||||
private SafeBitVector32 _flags;
|
||||
private OnChangedCallback _onChangedCallback;
|
||||
private Object _onChangedState = NOT_SET;
|
||||
|
||||
// The helper routines (OnChangedHelper and DisposeHelper) are used to prevent
|
||||
// an infinite loop, where Dispose calls OnChanged and OnChanged calls Dispose.
|
||||
[SuppressMessage("Microsoft.Performance", "CA1816:DisposeMethodsShouldCallSuppressFinalize", Justification = "Grandfathered suppression from original caching code checkin")]
|
||||
private void DisposeHelper() {
|
||||
// if not initialized, return without doing anything.
|
||||
if (_flags[INITIALIZED]) {
|
||||
if (_flags.ChangeValue(DISPOSED, true)) {
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The helper routines (OnChangedHelper and DisposeHelper) are used to prevent
|
||||
// an infinite loop, where Dispose calls OnChanged and OnChanged calls Dispose.
|
||||
private void OnChangedHelper(Object state) {
|
||||
_flags[CHANGED] = true;
|
||||
|
||||
// the callback is only invoked once, after NotifyOnChanged is called, so
|
||||
// remember "state" on the first call and use it when invoking the callback
|
||||
Interlocked.CompareExchange(ref _onChangedState, state, NOT_SET);
|
||||
|
||||
OnChangedCallback onChangedCallback = _onChangedCallback;
|
||||
if (onChangedCallback != null) {
|
||||
// only invoke the callback once
|
||||
if (_flags.ChangeValue(INVOKED, true)) {
|
||||
onChangedCallback(_onChangedState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// protected members
|
||||
//
|
||||
|
||||
// Derived classes must implement this. When "disposing" is true,
|
||||
// all managed and unmanaged resources are disposed and any references to this
|
||||
// object are released so that the ChangeMonitor can be garbage collected.
|
||||
// It is guaranteed that ChangeMonitor.Dispose() will only invoke
|
||||
// Dispose(bool disposing) once.
|
||||
protected abstract void Dispose(bool disposing);
|
||||
|
||||
// Derived classes must call InitializationComplete
|
||||
protected void InitializationComplete() {
|
||||
_flags[INITIALIZED] = true;
|
||||
|
||||
// If the dependency has already changed, or someone tried to dispose us, then call Dispose now.
|
||||
Dbg.Assert(_flags[INITIALIZED], "It is critical that INITIALIZED is set before CHANGED is checked below");
|
||||
if (_flags[CHANGED]) {
|
||||
Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
// Derived classes call OnChanged when the dependency changes. Optionally,
|
||||
// they may pass state which will be passed to the OnChangedCallback. The
|
||||
// OnChangedCallback is only invoked once, and only after NotifyOnChanged is
|
||||
// called by the cache implementer. OnChanged is also invoked when the instance
|
||||
// is disposed, but only has an affect if the callback has not already been invoked.
|
||||
protected void OnChanged(Object state) {
|
||||
OnChangedHelper(state);
|
||||
|
||||
// OnChanged will also invoke Dispose, but only after initialization is complete
|
||||
Dbg.Assert(_flags[CHANGED], "It is critical that CHANGED is set before INITIALIZED is checked below.");
|
||||
if (_flags[INITIALIZED]) {
|
||||
DisposeHelper();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// public members
|
||||
//
|
||||
|
||||
// set to true when the dependency changes, specifically, when OnChanged is called.
|
||||
public bool HasChanged { get { return _flags[CHANGED]; } }
|
||||
|
||||
// set to true when this instance is disposed, specifically, after
|
||||
// Dispose(bool disposing) is called by Dispose().
|
||||
public bool IsDisposed { get { return _flags[DISPOSED]; } }
|
||||
|
||||
// a unique ID representing this ChangeMonitor, typically consisting of
|
||||
// the dependency names and last-modified times.
|
||||
public abstract string UniqueId { get; }
|
||||
|
||||
|
||||
// Dispose must be called to release the ChangeMonitor. In order to
|
||||
// prevent derived classes from overriding Dispose, it is not an explicit
|
||||
// interface implementation.
|
||||
//
|
||||
// Before cache insertion, if the user decides not to do a cache insert, they
|
||||
// must call this to dispose the dependency; otherwise, the ChangeMonitor will
|
||||
// be referenced and unable to be garbage collected until the dependency changes.
|
||||
//
|
||||
// After cache insertion, the cache implementer must call this when the cache entry
|
||||
// is removed, for whatever reason. Even if an exception is thrown during insert.
|
||||
//
|
||||
// After cache insertion, the user should not call Dispose. However, since there's
|
||||
// no way to prevent this, doing so will invoke the OnChanged event handler, if it
|
||||
// hasn't already been invoked, and the cache entry will be notified as if the
|
||||
// dependency has changed.
|
||||
//
|
||||
// Dispose() will only invoke the Dispose(bool disposing) method of derived classes
|
||||
// once, the first time it is called. Subsequent calls to Dispose() perform no
|
||||
// operation. After Dispose is called, the IsDisposed property will be true.
|
||||
[SuppressMessage("Microsoft.Performance", "CA1816:DisposeMethodsShouldCallSuppressFinalize", Justification = "Grandfathered suppression from original caching code checkin")]
|
||||
public void Dispose() {
|
||||
OnChangedHelper(null);
|
||||
|
||||
// If not initialized, throw, so the derived class understands that it must call InitializeComplete before Dispose.
|
||||
Dbg.Assert(_flags[CHANGED], "It is critical that CHANGED is set before INITIALIZED is checked below.");
|
||||
if (!_flags[INITIALIZED]) {
|
||||
throw new InvalidOperationException(R.Init_not_complete);
|
||||
}
|
||||
|
||||
DisposeHelper();
|
||||
}
|
||||
|
||||
// Cache implementers must call this to be notified of any dependency changes.
|
||||
// NotifyOnChanged can only be invoked once, and will throw InvalidOperationException
|
||||
// on subsequent calls. The OnChangedCallback is guaranteed to be called exactly once.
|
||||
// It will be called when the dependency changes, or if it has already changed, it will
|
||||
// be called immediately (on the same thread??).
|
||||
public void NotifyOnChanged(OnChangedCallback onChangedCallback) {
|
||||
if (onChangedCallback == null) {
|
||||
throw new ArgumentNullException("onChangedCallback");
|
||||
}
|
||||
|
||||
if (Interlocked.CompareExchange(ref _onChangedCallback, onChangedCallback, null) != null) {
|
||||
throw new InvalidOperationException(R.Method_already_invoked);
|
||||
}
|
||||
|
||||
// if it already changed, raise the event now.
|
||||
if (_flags[CHANGED]) {
|
||||
OnChanged(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
// <copyright file="CacheSectionGroup.cs" company="Microsoft">
|
||||
// Copyright (c) 2009 Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
using System;
|
||||
using System.Configuration;
|
||||
|
||||
namespace System.Runtime.Caching.Configuration {
|
||||
public sealed class CachingSectionGroup : ConfigurationSectionGroup {
|
||||
public CachingSectionGroup() {
|
||||
}
|
||||
|
||||
// public properties
|
||||
[ConfigurationProperty("memoryCache")]
|
||||
public MemoryCacheSection MemoryCaches {
|
||||
get {
|
||||
return (MemoryCacheSection)Sections["memoryCache"];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
// <copyright file="ConfigUtil.cs" company="Microsoft">
|
||||
// Copyright (c) 2009 Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
using System;
|
||||
using System.Runtime.Caching.Resources;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
|
||||
namespace System.Runtime.Caching.Configuration {
|
||||
internal static class ConfigUtil {
|
||||
internal const string CacheMemoryLimitMegabytes = "cacheMemoryLimitMegabytes";
|
||||
internal const string PhysicalMemoryLimitPercentage = "physicalMemoryLimitPercentage";
|
||||
internal const string PollingInterval = "pollingInterval";
|
||||
internal const int DefaultPollingTimeMilliseconds = 120000;
|
||||
|
||||
internal static int GetIntValue(NameValueCollection config, string valueName, int defaultValue, bool zeroAllowed, int maxValueAllowed) {
|
||||
string sValue = config[valueName];
|
||||
|
||||
if (sValue == null) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
int iValue;
|
||||
if (!Int32.TryParse(sValue, out iValue)
|
||||
|| iValue < 0
|
||||
|| (!zeroAllowed && iValue == 0)) {
|
||||
if (zeroAllowed) {
|
||||
throw new ArgumentException(RH.Format(R.Value_must_be_non_negative_integer, valueName, sValue), "config");
|
||||
}
|
||||
|
||||
throw new ArgumentException(RH.Format(R.Value_must_be_positive_integer, valueName, sValue), "config");
|
||||
}
|
||||
|
||||
if (maxValueAllowed > 0 && iValue > maxValueAllowed) {
|
||||
throw new ArgumentException(RH.Format(R.Value_too_big,
|
||||
valueName,
|
||||
sValue,
|
||||
maxValueAllowed.ToString(CultureInfo.InvariantCulture)), "config");
|
||||
}
|
||||
|
||||
return iValue;
|
||||
}
|
||||
|
||||
internal static int GetIntValueFromTimeSpan(NameValueCollection config, string valueName, int defaultValue) {
|
||||
string sValue = config[valueName];
|
||||
|
||||
if (sValue == null) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
if (sValue == "Infinite") {
|
||||
return Int32.MaxValue;
|
||||
}
|
||||
|
||||
TimeSpan tValue;
|
||||
if (!TimeSpan.TryParse(sValue, out tValue) || tValue <= TimeSpan.Zero) {
|
||||
throw new ArgumentException(RH.Format(R.TimeSpan_invalid_format, valueName, sValue), "config");
|
||||
}
|
||||
|
||||
double milliseconds = tValue.TotalMilliseconds;
|
||||
int iValue = (milliseconds < (double)Int32.MaxValue) ? (int) milliseconds : Int32.MaxValue;
|
||||
return iValue;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="MemoryCacheSettingsSettingsCollection.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.Runtime.Caching.Configuration {
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Configuration;
|
||||
using System.Collections.Specialized;
|
||||
using System.Collections;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Security.Permissions;
|
||||
|
||||
public sealed class MemoryCacheElement : ConfigurationElement {
|
||||
private static ConfigurationPropertyCollection _properties;
|
||||
private static readonly ConfigurationProperty _propName;
|
||||
private static readonly ConfigurationProperty _propPhysicalMemoryLimitPercentage;
|
||||
private static readonly ConfigurationProperty _propCacheMemoryLimitMegabytes;
|
||||
private static readonly ConfigurationProperty _propPollingInterval;
|
||||
|
||||
static MemoryCacheElement() {
|
||||
// Property initialization
|
||||
_properties = new ConfigurationPropertyCollection();
|
||||
|
||||
_propName =
|
||||
new ConfigurationProperty("name",
|
||||
typeof(string),
|
||||
null,
|
||||
new WhiteSpaceTrimStringConverter(),
|
||||
new StringValidator(1),
|
||||
ConfigurationPropertyOptions.IsRequired |
|
||||
ConfigurationPropertyOptions.IsKey);
|
||||
|
||||
_propPhysicalMemoryLimitPercentage =
|
||||
new ConfigurationProperty("physicalMemoryLimitPercentage",
|
||||
typeof(int),
|
||||
(int)0,
|
||||
null,
|
||||
new IntegerValidator(0, 100),
|
||||
ConfigurationPropertyOptions.None);
|
||||
|
||||
_propCacheMemoryLimitMegabytes =
|
||||
new ConfigurationProperty("cacheMemoryLimitMegabytes",
|
||||
typeof(int),
|
||||
(int)0,
|
||||
null,
|
||||
new IntegerValidator(0, Int32.MaxValue),
|
||||
ConfigurationPropertyOptions.None);
|
||||
|
||||
_propPollingInterval =
|
||||
new ConfigurationProperty("pollingInterval",
|
||||
typeof(TimeSpan),
|
||||
TimeSpan.FromMilliseconds(ConfigUtil.DefaultPollingTimeMilliseconds),
|
||||
new InfiniteTimeSpanConverter(),
|
||||
new PositiveTimeSpanValidator(),
|
||||
ConfigurationPropertyOptions.None);
|
||||
|
||||
_properties.Add(_propName);
|
||||
_properties.Add(_propPhysicalMemoryLimitPercentage);
|
||||
_properties.Add(_propCacheMemoryLimitMegabytes);
|
||||
_properties.Add(_propPollingInterval);
|
||||
}
|
||||
|
||||
internal MemoryCacheElement() {
|
||||
}
|
||||
|
||||
public MemoryCacheElement(string name) {
|
||||
Name = name;
|
||||
}
|
||||
|
||||
protected override ConfigurationPropertyCollection Properties {
|
||||
get {
|
||||
return _properties;
|
||||
}
|
||||
}
|
||||
|
||||
[ConfigurationProperty("name", DefaultValue = "", IsRequired = true, IsKey = true)]
|
||||
[TypeConverter(typeof(WhiteSpaceTrimStringConverter))]
|
||||
[StringValidator(MinLength = 1)]
|
||||
public string Name {
|
||||
get {
|
||||
return (string)base["name"];
|
||||
}
|
||||
set {
|
||||
base["name"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[ConfigurationProperty("physicalMemoryLimitPercentage", DefaultValue = (int)0)]
|
||||
[IntegerValidator(MinValue = 0, MaxValue = 100)]
|
||||
public int PhysicalMemoryLimitPercentage {
|
||||
get {
|
||||
return (int)base["physicalMemoryLimitPercentage"];
|
||||
}
|
||||
set {
|
||||
base["physicalMemoryLimitPercentage"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[ConfigurationProperty("cacheMemoryLimitMegabytes", DefaultValue = (int)0)]
|
||||
[IntegerValidator(MinValue = 0)]
|
||||
public int CacheMemoryLimitMegabytes {
|
||||
get {
|
||||
return (int)base["cacheMemoryLimitMegabytes"];
|
||||
}
|
||||
set {
|
||||
base["cacheMemoryLimitMegabytes"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[ConfigurationProperty("pollingInterval", DefaultValue = "00:02:00")]
|
||||
[TypeConverter(typeof(InfiniteTimeSpanConverter))]
|
||||
public TimeSpan PollingInterval {
|
||||
get {
|
||||
return (TimeSpan)base["pollingInterval"];
|
||||
}
|
||||
set {
|
||||
base["pollingInterval"] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
// <copyright file="MemoryCacheSection.cs" company="Microsoft">
|
||||
// Copyright (c) 2009 Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
|
||||
using System;
|
||||
using System.Collections.Specialized;
|
||||
using System.Configuration;
|
||||
using System.Runtime.Caching.Resources;
|
||||
|
||||
namespace System.Runtime.Caching.Configuration {
|
||||
|
||||
/*
|
||||
<system.runtime.caching>
|
||||
<memoryCaches>
|
||||
<namedCaches>
|
||||
<add name="Default" physicalMemoryPercentage="0" pollingInterval="00:02:00"/>
|
||||
<add name="Foo" physicalMemoryPercentage="0" pollingInterval="00:02:00"/>
|
||||
<add name="Bar" physicalMemoryPercentage="0" pollingInterval="00:02:00"/>
|
||||
</namedCaches>
|
||||
</memoryCaches>
|
||||
</system.caching>
|
||||
|
||||
*/
|
||||
|
||||
public sealed class MemoryCacheSection : ConfigurationSection {
|
||||
private static ConfigurationPropertyCollection _properties;
|
||||
private static readonly ConfigurationProperty _propNamedCaches;
|
||||
|
||||
static MemoryCacheSection() {
|
||||
_propNamedCaches = new ConfigurationProperty("namedCaches",
|
||||
typeof(MemoryCacheSettingsCollection),
|
||||
null, // defaultValue
|
||||
ConfigurationPropertyOptions.None);
|
||||
|
||||
_properties = new ConfigurationPropertyCollection();
|
||||
_properties.Add(_propNamedCaches);
|
||||
}
|
||||
|
||||
public MemoryCacheSection() {
|
||||
}
|
||||
|
||||
protected override ConfigurationPropertyCollection Properties {
|
||||
get {
|
||||
return _properties;
|
||||
}
|
||||
}
|
||||
|
||||
[ConfigurationProperty("namedCaches")]
|
||||
public MemoryCacheSettingsCollection NamedCaches {
|
||||
get {
|
||||
return (MemoryCacheSettingsCollection)base[_propNamedCaches];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="MemoryCacheSettingsSettingsCollection.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.Runtime.Caching.Configuration {
|
||||
using System;
|
||||
using System.Configuration;
|
||||
using System.Collections.Specialized;
|
||||
using System.Collections;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Security.Permissions;
|
||||
|
||||
[ConfigurationCollection(typeof(MemoryCacheElement),
|
||||
CollectionType = ConfigurationElementCollectionType.AddRemoveClearMap)]
|
||||
public sealed class MemoryCacheSettingsCollection : ConfigurationElementCollection {
|
||||
private static ConfigurationPropertyCollection _properties;
|
||||
|
||||
static MemoryCacheSettingsCollection() {
|
||||
// Property initialization
|
||||
_properties = new ConfigurationPropertyCollection();
|
||||
}
|
||||
|
||||
protected override ConfigurationPropertyCollection Properties {
|
||||
get {
|
||||
return _properties;
|
||||
}
|
||||
}
|
||||
|
||||
public MemoryCacheSettingsCollection() {
|
||||
}
|
||||
|
||||
public MemoryCacheElement this[int index] {
|
||||
get { return (MemoryCacheElement)base.BaseGet(index); }
|
||||
set {
|
||||
if (base.BaseGet(index) != null) {
|
||||
base.BaseRemoveAt(index);
|
||||
}
|
||||
base.BaseAdd(index, value);
|
||||
}
|
||||
}
|
||||
|
||||
public new MemoryCacheElement this[string key] {
|
||||
get {
|
||||
return (MemoryCacheElement)BaseGet(key);
|
||||
}
|
||||
}
|
||||
|
||||
public override ConfigurationElementCollectionType CollectionType {
|
||||
get {
|
||||
return ConfigurationElementCollectionType.AddRemoveClearMapAlternate;
|
||||
}
|
||||
}
|
||||
|
||||
public int IndexOf(MemoryCacheElement cache) {
|
||||
return BaseIndexOf(cache);
|
||||
}
|
||||
|
||||
public void Add(MemoryCacheElement cache) {
|
||||
BaseAdd(cache);
|
||||
}
|
||||
|
||||
public void Remove(MemoryCacheElement cache) {
|
||||
BaseRemove(cache.Name);
|
||||
}
|
||||
|
||||
public void RemoveAt(int index) {
|
||||
BaseRemoveAt(index);
|
||||
}
|
||||
|
||||
public void Clear() {
|
||||
BaseClear();
|
||||
}
|
||||
|
||||
protected override ConfigurationElement CreateNewElement() {
|
||||
return new MemoryCacheElement();
|
||||
}
|
||||
|
||||
protected override ConfigurationElement CreateNewElement(string elementName) {
|
||||
return new MemoryCacheElement(elementName);
|
||||
}
|
||||
|
||||
protected override object GetElementKey(ConfigurationElement element) {
|
||||
return ((MemoryCacheElement)element).Name;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user