File: ObjectCacheHost.cs

package info (click to toggle)
mono 6.14.1%2Bds2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,282,732 kB
  • sloc: cs: 11,182,461; xml: 2,850,281; ansic: 699,123; cpp: 122,919; perl: 58,604; javascript: 30,841; asm: 21,845; makefile: 19,602; sh: 10,973; python: 4,772; pascal: 925; sql: 859; sed: 16; php: 1
file content (139 lines) | stat: -rw-r--r-- 5,394 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
// <copyright file="ObjectCacheHost.cs" company="Microsoft">
//   Copyright (c) 2009 Microsoft Corporation.  All rights reserved.
// </copyright>

using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.Caching;
using System.Runtime.Caching.Hosting;
using System.Web.Util;

namespace System.Web.Hosting {
    [SuppressMessage("Microsoft.Usage", "CA2302:FlagServiceProviders", Justification = "Internal class")]
    internal sealed class ObjectCacheHost : IServiceProvider, IApplicationIdentifier, IFileChangeNotificationSystem, IMemoryCacheManager
    {

        private Object _lock = new Object();
        private Dictionary<MemoryCache, MemoryCacheInfo> _cacheInfos;

        internal sealed class FileChangeEventTarget {
            private OnChangedCallback _onChangedCallback;
            private FileChangeEventHandler _handler;

            private void OnChanged(Object sender, FileChangeEvent e) {
                _onChangedCallback(null);
            }
            
            internal FileChangeEventHandler Handler { get { return _handler; } }

            internal FileChangeEventTarget(OnChangedCallback onChangedCallback) {
                _onChangedCallback = onChangedCallback;
                _handler = new FileChangeEventHandler(this.OnChanged);
            }
        }
        
        internal sealed class MemoryCacheInfo {
            internal MemoryCache Cache;
            internal long Size;
        }

        Object IServiceProvider.GetService(Type service) {
            if (service == typeof(IFileChangeNotificationSystem)) {
                return this as IFileChangeNotificationSystem;
            }
            else if (service == typeof(IMemoryCacheManager)) {
                return this as IMemoryCacheManager;
            }
            else if (service == typeof(IApplicationIdentifier)) {
                return this as IApplicationIdentifier;
            }
            else {
                return null;
            }
        }

        String IApplicationIdentifier.GetApplicationId() {
            return HttpRuntime.AppDomainAppId;
        }

        void IFileChangeNotificationSystem.StartMonitoring(string filePath, OnChangedCallback onChangedCallback, out Object state, out DateTimeOffset lastWrite, out long fileSize) {
            if (filePath == null) {
                throw new ArgumentNullException("filePath");
            }
            if (onChangedCallback == null) {
                throw new ArgumentNullException("onChangedCallback");
            }
            FileChangeEventTarget target = new FileChangeEventTarget(onChangedCallback);
            FileAttributesData fad;
            HttpRuntime.FileChangesMonitor.StartMonitoringPath(filePath, target.Handler, out fad);
            if (fad == null) {
                fad = FileAttributesData.NonExistantAttributesData;
            }
            state = target;
#if DBG            
            Debug.Assert(fad.UtcLastWriteTime.Kind == DateTimeKind.Utc, "fad.UtcLastWriteTime.Kind == DateTimeKind.Utc");
#endif
            lastWrite = fad.UtcLastWriteTime;
            fileSize = fad.FileSize;
        }

        void IFileChangeNotificationSystem.StopMonitoring(string filePath, Object state) {
            if (filePath == null) {
                throw new ArgumentNullException("filePath");
            }
            if (state == null) {
                throw new ArgumentNullException("state");
            }
            HttpRuntime.FileChangesMonitor.StopMonitoringPath(filePath, state);
        }

        void IMemoryCacheManager.ReleaseCache(MemoryCache memoryCache) {
            if (memoryCache == null) {
                throw new ArgumentNullException("memoryCache");
            }
            lock (_lock) {
                if (_cacheInfos != null) {
                    MemoryCacheInfo info = null;
                    if (_cacheInfos.TryGetValue(memoryCache, out info)) {
                        _cacheInfos.Remove(memoryCache);
                    }
                }
            }
        }

        void IMemoryCacheManager.UpdateCacheSize(long size, MemoryCache memoryCache) {
            if (memoryCache == null) {
                throw new ArgumentNullException("memoryCache");
            }
            lock (_lock) {
                if (_cacheInfos == null) {
                    _cacheInfos = new Dictionary<MemoryCache, MemoryCacheInfo>();
                }
                MemoryCacheInfo info = null;
                if (!_cacheInfos.TryGetValue(memoryCache, out info)) {
                    info = new MemoryCacheInfo();
                    info.Cache = memoryCache;
                    _cacheInfos[memoryCache] = info;
                }
                info.Size = size;
            }
        }

        internal long TrimCache(int percent) {
            long trimmedOrExpired = 0;
            MemoryCache[] caches = null;
            lock (_lock) {
                if (_cacheInfos != null && _cacheInfos.Count > 0) {
                    caches = new MemoryCache[_cacheInfos.Keys.Count];
                    _cacheInfos.Keys.CopyTo(caches, 0);
                }
            }
            if (caches != null) {
                foreach (MemoryCache cache in caches) {
                    trimmedOrExpired += cache.Trim(percent);
                }
            }
            return trimmedOrExpired;
        }
    }
}