예제 #1
0
파일: CacheConfig.cs 프로젝트: winal/Scree
        private static void LoadSingleTypeCacheConfig(IEnumerable <XElement> types)
        {
            SingleTypeCacheConfig config;

            foreach (XElement el in types)
            {
                try
                {
                    string name = el.Attribute("name").Value;
                    if (string.IsNullOrEmpty(name))
                    {
                        LogProxy.Warn(CACHETYPENAMEISNULL);
                        continue;
                    }

                    bool isFix = false;
                    if (el.Attribute("isfix") != null)
                    {
                        bool.TryParse(el.Attribute("isfix").Value.Trim(), out isFix);

                        if (isFix)
                        {
                            config = new SingleTypeCacheConfig(name, true, 0, 0);
                            MyCacheConfig[name] = config;

                            continue;
                        }
                    }

                    int second = 0;
                    if (el.Attribute("second") != null)
                    {
                        int.TryParse(el.Attribute("second").Value.Trim(), out second);

                        if (second < 0)
                        {
                            second = 0;
                        }
                    }

                    int size = 0;
                    if (el.Attribute("size") != null)
                    {
                        int.TryParse(el.Attribute("size").Value.Trim(), out size);

                        if (size < 0)
                        {
                            size = 0;
                        }
                    }

                    config = new SingleTypeCacheConfig(name, false, second, size);
                    MyCacheConfig[name] = config;
                }
                catch (Exception ex)
                {
                    LogProxy.Error(ex, false);
                }
            }
        }
예제 #2
0
        private static void CacheClear()
        {
            string[] typesKeys = GetTypesKeys();

            foreach (string typeName in typesKeys)
            {
                SingleTypeCacheConfig config = SingleTypeCacheConfig.Get(typeName);
                Dictionary <string, MyCacheObject> caches = GetCaches(typeName);

                #region 固定缓存
                if (config.IsFix)
                {
                    if (config.NextFixLoggingTime < DateTime.Now)
                    {
                        config.NextFixLoggingTime = DateTime.Now.AddMinutes(FixLoggingInterval);
                        LogProxy.InfoFormat(CACHEISFIX, typeName, caches.Count);
                    }

                    continue;
                }
                #endregion

                OverdueTimeCacheClear(caches, typeName, config);

                if (config.Size > 0)
                {
                    OverSizeCacheClear(caches, typeName, config);
                }
            }
        }
예제 #3
0
        public ICacheable Get(Type type, string id)
        {
            if (string.IsNullOrEmpty(id))
            {
                return(null);
            }

            string fullName = type.FullName;

            if (!IsNeedCached(fullName))
            {
                return(null);
            }

            SingleTypeCacheConfig config = SingleTypeCacheConfig.Get(fullName);

            Dictionary <string, MyCacheObject> caches = GetCaches(fullName);

            config.LockObj.EnterReadLock();

            try
            {
                id = id.ToLower();
                if (!caches.ContainsKey(id))
                {
                    return(null);
                }

                MyCacheObject myCacheObject = caches[id];

                if (!config.IsFix && myCacheObject.OverdueTime < DateTime.Now)
                {
                    return(null);
                }

                myCacheObject.LastGetTime = DateTime.Now;

                try
                {
                    config.Getted(myCacheObject.Obj);
                }
                catch (Exception ex)
                {
                    LogProxy.Error(ex, false);
                }

                return(myCacheObject.Obj);
            }
            catch (Exception ex)
            {
                LogProxy.Error(ex, false);
            }
            finally
            {
                config.LockObj.ExitReadLock();
            }

            return(null);
        }
예제 #4
0
        public void AddEvent <T>(OnCacheCleared cacheCleared, OnCacheSetted cacheSetted, OnCacheGetted cacheGetted) where T : ICacheable
        {
            if (!IsNeedCached <T>())
            {
                return;
            }

            SingleTypeCacheConfig config = SingleTypeCacheConfig.Get <T>();

            if (cacheCleared != null)
            {
                config.CacheCleared += cacheCleared;
            }
            if (cacheSetted != null)
            {
                config.CacheSetted += cacheSetted;
            }
            if (cacheGetted != null)
            {
                config.CacheGetted += cacheGetted;
            }
        }
예제 #5
0
 public bool IsNeedCached(string typeName)
 {
     return(SingleTypeCacheConfig.IsExist(typeName));
 }
예제 #6
0
 public bool IsNeedCached <T>() where T : ICacheable
 {
     return(SingleTypeCacheConfig.IsExist <T>());
 }
예제 #7
0
        private static void CacheClear(Dictionary <string, MyCacheObject> caches, string[] objKeys, ClearType clearType, SingleTypeCacheConfig config)
        {
            MyCacheObject objCache;

            if (!config.LockObj.TryEnterWriteLock(WriteLockTimeout))
            {
                return;
            }

            try
            {
                foreach (string objKey in objKeys)
                {
                    objCache = caches[objKey];
                    switch (clearType)
                    {
                    case ClearType.OverdueTime:
                    {
                        if (objCache.OverdueTime > DateTime.Now)
                        {
                            break;
                        }

                        caches.Remove(objCache.Obj.Id);

                        try
                        {
                            config.Cleared(objCache.Obj);
                        }
                        catch (Exception ex)
                        {
                            LogProxy.Error(ex, false);
                        }

                        break;
                    }

                    case ClearType.OverSize:
                    {
                        if (objCache.LastGetTime.AddSeconds(MinStayTime) > DateTime.Now)
                        {
                            break;
                        }

                        caches.Remove(objCache.Obj.Id);

                        try
                        {
                            config.Cleared(objCache.Obj);
                        }
                        catch (Exception ex)
                        {
                            LogProxy.Error(ex, false);
                        }
                        break;
                    }
                    }
                }
            }
            finally
            {
                config.LockObj.ExitWriteLock();
            }
        }
예제 #8
0
        private static void OverSizeCacheClear(Dictionary <string, MyCacheObject> caches, string typeName, SingleTypeCacheConfig config)
        {
            int cnt = caches.Count;

            LogProxy.InfoFormat(BEFOREOVERSIZECACHECLEARINFO, typeName, cnt);

            if (cnt < config.Size * 1.2)
            {
                return;
            }

            int clearSum = (int)(cnt - config.Size * 0.8);

            LogProxy.InfoFormat(SIZEOVER, typeName, cnt - config.Size, clearSum);

            string[] objKeys = GetOverSizeKeys(caches, clearSum, config);
            if (objKeys == null || objKeys.Length == 0)
            {
                return;
            }
            CacheClear(caches, objKeys, ClearType.OverSize, config);

            LogProxy.InfoFormat(AFTEROVERSIZECACHECLEARINFO, typeName, caches.Count);
        }
예제 #9
0
 private static string[] GetOverSizeKeys(Dictionary <string, MyCacheObject> caches, int clearSum, SingleTypeCacheConfig config)
 {
     config.LockObj.EnterReadLock();
     try
     {
         return((from o in caches
                 where o.Value.LastGetTime.AddSeconds(MinStayTime) < DateTime.Now
                 orderby o.Value.LastGetTime ascending
                 select o.Key).Take(clearSum).ToArray());
     }
     finally
     {
         config.LockObj.ExitReadLock();
     }
 }
예제 #10
0
        private static void OverdueTimeCacheClear(Dictionary <string, MyCacheObject> caches, string typeName, SingleTypeCacheConfig config)
        {
            LogProxy.InfoFormat(BEFOREOVERDUETIMECACHECLEARINFO, typeName, caches.Count);

            string[] objKeys = GetOverdueTimeKeys(caches, config);
            if (objKeys == null || objKeys.Length == 0)
            {
                return;
            }
            CacheClear(caches, objKeys, ClearType.OverdueTime, config);

            LogProxy.InfoFormat(AFTEROVERDUETIMECACHECLEAR, typeName, caches.Count);
        }
예제 #11
0
 private static string[] GetOverdueTimeKeys(Dictionary <string, MyCacheObject> caches, SingleTypeCacheConfig config)
 {
     config.LockObj.EnterReadLock();
     try
     {
         return((from o in caches
                 where o.Value.OverdueTime < DateTime.Now
                 select o.Key).ToArray());
     }
     finally
     {
         config.LockObj.ExitReadLock();
     }
 }
예제 #12
0
        public void Set(ICacheable obj)
        {
            if (obj == null)
            {
                return;
            }

            string fullName = obj.GetType().FullName;

            if (!IsNeedCached(fullName))
            {
                return;
            }

            SingleTypeCacheConfig config = SingleTypeCacheConfig.Get(fullName);
            Dictionary <string, MyCacheObject> caches = GetCaches(fullName);

            if (!config.LockObj.TryEnterWriteLock(WriteLockTimeout))
            {
                return;
            }

            try
            {
                string        id = obj.Id.ToLower();
                MyCacheObject myCacheObject;
                if (caches.ContainsKey(id))
                {
                    myCacheObject = caches[id];
                    if (myCacheObject.Obj.Version >= obj.Version)
                    {
                        return;
                    }

                    myCacheObject.Obj         = obj;
                    myCacheObject.OverdueTime = DateTime.Now.AddSeconds(config.Second);
                }
                else
                {
                    myCacheObject = new MyCacheObject(obj, DateTime.Now.AddSeconds(config.Second));
                    caches.Add(id, myCacheObject);
                }

                try
                {
                    config.Setted(obj);
                }
                catch (Exception ex)
                {
                    LogProxy.Error(ex, false);
                }
            }
            catch (Exception ex)
            {
                LogProxy.Error(ex, false);
            }
            finally
            {
                config.LockObj.ExitWriteLock();
            }
        }