⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 filecacheprovider.cs

📁 HeyCacher 高性能缓存方案(带源码) 1. 文件的所有权益归上传用户所有 2. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途 3. CSDN下载频道仅提供交流平台
💻 CS
📖 第 1 页 / 共 2 页
字号:
//===============================================================================
// CSDN HeyCache 
//===============================================================================
// 修改记录:[按最后修改时间倒排序]
// modify: 2007.06.14 by tangwei 
// create: 2007.06.11 by tangwei
//
// 代码来源:tangwei
//===============================================================================
using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.IO;
using System.Collections;
using System.Threading;
using HeyCacher.Components;
using HeyCacher.Components.Scavenger;
using HeyCacher.Components.Expirations;
using System.Collections.Specialized;

namespace HeyCacher.Providers
{
    /// <summary>
    /// 基于文件的缓存实现
    /// </summary>
    public class FileCacheProvider : CacheProvider
    {
        #region 属性
        //文件存储目录
        public string RootPath
        {
            get { return m_RootPath; }
        }
        private string m_RootPath;

        //几级hash目录
        public int PathDepth
        {
            get { return m_PathDepth; }
        }
        private int m_PathDepth;

        //文件前缀
        public string FileNameMark
        {
            get { return m_FileNameMark; }
        }
        private string m_FileNameMark;

        #endregion

        #region 初始化
        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="name"></param>
        /// <param name="config"></param>
        public override void Initialize(string name, NameValueCollection config)
        {
            //
            int ScavengInSeconds = 10; //资源回收间隔时间,单位为秒

            #region 初始化配置
            base.Initialize(name, config);
            if (config != null)
            {
                if (config["RootPath"] != null)
                {
                    this.m_RootPath = config["RootPath"];
                    config.Remove("RootPath");
                    if(!String.IsNullOrEmpty(this.m_RootPath))
                    {
                        char pathHead = this.m_RootPath[0];
                        if (pathHead == '~')
                        {
                            this.m_RootPath = System.Web.HttpContext.Current.Server.MapPath(this.m_RootPath);
                        }
                    }
                }
                if (config["PathDepth"] != null)
                {
                    this.m_PathDepth = int.Parse(config["PathDepth"]);
                    config.Remove("PathDepth");
                }
                if (config["FileNameMark"] != null)
                {
                    this.m_FileNameMark = config["FileNameMark"];
                    config.Remove("FileNameMark");
                }
                if (config["ScavengInSeconds"] != null)
                {
                    ScavengInSeconds = int.Parse(config["ScavengInSeconds"]);
                    config.Remove("ScavengInSeconds");
                }
            }
            #endregion

            //建立各种回收任务与控制器对象,并启动
            ExpirationTask expirationTask = new ExpirationTask(this);
            BackgroundScheduler scheduler = new BackgroundScheduler(expirationTask);
            scheduler.Start();

            //启动回收定时器
            ScavengerTimer timer = new ScavengerTimer();
            //timer.StartPolling(new TimerCallback(scheduler.ExpirationTimeoutExpired), ScavengInSeconds); //系统线程池定时器
            timer.StartPolling(new System.Timers.ElapsedEventHandler(scheduler.ExpirationTimeoutExpired), ScavengInSeconds); //普通定时器
        }
        #endregion

        #region Count
        public override int Count
        {
            get { return -1; }
        }
        #endregion

        #region Contains
        public override bool Contains(string Key, CacheTack cacheTack)
        {
            //
            string filename = null;

            //取得缓存文件的存储路径
            if (cacheTack == null || String.IsNullOrEmpty(cacheTack.SavePath))
            {
                filename = BuildFileFullPath(GetMd5Key(Key));
            }
            else
            {
                filename = GetFullPath(cacheTack.SavePath);
            }

            return File.Exists(filename);
        }
        #endregion

        #region Get
        public override CacheItem GetCacheItem(string Key, CacheTack cacheTack)
        {
            string filename = null;
            CacheItem ci = null;
            
            //取得缓存文件的存储路径
            if (cacheTack == null || String.IsNullOrEmpty(cacheTack.SavePath))
            {
                filename = BuildFileFullPath(GetMd5Key(Key));
            }
            else
            {
                filename = GetFullPath(cacheTack.SavePath);
            }

            #region 更新本地依赖
            ExpirationItem expirationItemBeforeLock = null;

            //独占锁
            bool LockFlag;
            do
            {
                lock (ExpirationItemTable.SyncRoot)
                {
                    if (!ExpirationItemTable.ContainsKey(Key))
                    {
                        ci = innerGet(filename);
                        if (ci != null)
                        {
                            expirationItemBeforeLock = new ExpirationItem(Key, ci.Priority, ci.RefreshAction, ci.Expirations);
                            ExpirationItemTable.Add(Key, expirationItemBeforeLock);
                        }
                        else
                        {
                            break;
                        }
                    }
                    else
                    {
                        expirationItemBeforeLock = (ExpirationItem)ExpirationItemTable[Key];
                    }
                    LockFlag = Monitor.TryEnter(expirationItemBeforeLock);
                }
                if (!LockFlag)
                {
                    Thread.Sleep(0);
                }
            } while (!LockFlag);

            //操作
            if (expirationItemBeforeLock != null)
            {
                //过期
                if (expirationItemBeforeLock.HasExpired())
                {
                    expirationItemBeforeLock.TouchedByUserAction(true);

                    ExpirationItemTable.Remove(Key);

                    realRemove(Key, cacheTack);
                    return null;
                }
            }

            //释放锁
            if (expirationItemBeforeLock != null)
            {
                Monitor.Exit(expirationItemBeforeLock);
            }
            #endregion

            //取得缓存
            if (ci == null)
            {
                ci = innerGet(filename);
            }
            if (ci == null)
            {
                return null;
            }

            //返回缓存中的值
            return ci;
        }
        private CacheItem innerGet(string filename)
        {
            CacheItem ci = null;
            if (File.Exists(filename))
            {
                byte[] FileBytes = ReadFile(filename);
                if (FileBytes != null)
                {
                    ci = Cnlamar.Serialization.Deserialize(FileBytes, XmlSerialize, DataCompress) as CacheItem;
                }
            }
            return ci;
        }
        #endregion

        #region innerInsert
        /// <summary>
        /// 添加一个缓存项
        /// </summary>
        /// <param name="Replace"></param>
        /// <param name="ci"></param>
        /// <param name="Insertd"></param>
        /// <returns></returns>
        protected override object innerInsert(bool Replace, CacheItem ci, CacheTack cacheTack, out bool Insertd)
        {
            Insertd = false; //是否被插入
            string filename = null;

            //检查缓存项是否有了,有了的话,根据Replace进行删除或者返回
            if (Contains(ci.Key))
            {
                if (Replace)
                {
                    Remove(ci.Key);
                }
                else
                {
                    return GetCacheItem(ci.Key, null).realValue;
                }
            }

            //建立过期策略
            ICacheItemExpiration[] LocalExpirations;
            InsertCacheItemExpiration(ci, out LocalExpirations);

            //取得缓存文件的存储路径
            if (cacheTack == null || String.IsNullOrEmpty(cacheTack.SavePath))
            {
                filename = BuildFileFullPath(GetMd5Key(ci.Key));
            }
            else
            {
                filename = GetFullPath(cacheTack.SavePath);
            }

            //建立缓存项
            byte[] byteCacheData = Cnlamar.Serialization.Serialize(ci, XmlSerialize, DataCompress);

            //写文件
            Insertd = WriteFile(filename, byteCacheData);

            //判断返回
            if (Insertd)
            {
                return ci.realValue;
            }
            else
            {
                return null;
            }
        }
        private void InsertCacheItemExpiration(CacheItem ci, out ICacheItemExpiration[] LocalExpirations)
        {
            LocalExpirations = null; //本地过期策略

            //如果过期规则为空,则不建立本地本地过期策略
            if (ci.Expirations == null)
            {
                return;
            }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -