C#開源磁碟/記憶體快取引擎
using System; using System.Collections.Generic; using System.Linq; using System.Text; using STSdb4.Database; using fastJSON; using System.IO; namespace Com.SuperCache.Engine { public class RawCache : BaseCache { private const string ExpirationFileExtension = "exp"; private const string DataFileExtension = "dat"; private const string statFile = "SuperCache.sta"; private string dataPath; private static Dictionary<string, object> memoryData = new Dictionary<string, object>(); private static Dictionary<string, DateTime?> memoryExpiration = new Dictionary<string, DateTime?>(); private static object syncRoot = new object(); private bool isMemory = false; private RecycleAlgorithms recycleAlgorithm; private int maxCount; private int threshold; private static Dictionary<string, KeyValue> usageStat = new Dictionary<string, KeyValue>(); private Dictionary<string, KeyValuePair<DateTime, string>> expiredFiles = new Dictionary<string, KeyValuePair<DateTime, string>>(); private RecycleModes recycleMode; public RawCache(string DataPath, RecycleAlgorithms RecycleAlgorithm, int MaxCount, int Threshold, RecycleModes RecycleMode) { dataPath = DataPath; if (!dataPath.EndsWith(Path.DirectorySeparatorChar.ToString())) dataPath += Path.DirectorySeparatorChar; isMemory = string.IsNullOrEmpty(DataPath); recycleAlgorithm = RecycleAlgorithm; maxCount = MaxCount; threshold = Threshold; recycleMode = RecycleMode; } public override void Add<K>(string Category, K Key, object Data) { Add(Category, Key, Data, null); } private string GetExpirationTable(string Category) { return KeyExpiration + "_" + Category; } public override void Add<K, V>(string Category, IEnumerable<KeyValuePair<K, V>> Items, DateTime? ExpirationDate) { long count = 0; lock (syncRoot) { Items.ForEach(i => { var key = i.Key; var data = i.Value; var cacheKey = GetKey(Category, key.ToString()); if (isMemory) { memoryData[cacheKey] = data; memoryExpiration[cacheKey] = ExpirationDate; //recycle algo switch (recycleAlgorithm) { case RecycleAlgorithms.MRU: usageStat[cacheKey] = new KeyValue(string.Empty, 0); if (recycleMode == RecycleModes.Active) Recycle<K>(Category, memoryData.Count); break; default: break; } } else { //will only serialize object other than string var result = typeof(V) == typeof(string) ? data as string : JSON.Instance.ToJSON(data); var fileKey = key.ToString(); var dataFile = GetFile(Category, fileKey, true); bool exists = File.Exists(dataFile); File.WriteAllText(dataFile, result); //specify expiration //default 30 mins to expire from now var expirationDate = ExpirationDate == null || ExpirationDate <= DateTime.Now ? DateTime.Now.AddMinutes(30) : (DateTime)ExpirationDate; var expirationFile = GetFile(Category, fileKey, false); File.WriteAllText(expirationFile, expirationDate.ToString()); //recycle algo if (recycleAlgorithm != RecycleAlgorithms.None) { var statFilePath = dataPath + statFile; if (File.Exists(statFilePath)) { var buffer = File.ReadAllText(statFilePath); count = Convert.ToInt32(buffer); } if (!exists) { count++; File.WriteAllText(statFilePath, count.ToString()); } switch (recycleAlgorithm) { case RecycleAlgorithms.MRU: usageStat[cacheKey] = new KeyValue(expirationFile, 0); expiredFiles[cacheKey] = new KeyValuePair<DateTime, string>(expirationDate, expirationFile); if (recycleMode == RecycleModes.Active) Recycle<K>(Category, count); break; default: break; } } } }); if (recycleAlgorithm != RecycleAlgorithms.None && recycleMode == RecycleModes.Passive) { if (isMemory) count = memoryData.Count; Recycle<K>(Category, count); } } } public override void Add<K>(string Category, K Key, object Data, DateTime? ExpirationDate) { Add<K, object>(Category, new List<KeyValuePair<K, object>> { new KeyValuePair<K, object>(Key, Data) }, ExpirationDate); } private string GetFile(string Category, string FileName, bool IsData) { var path = dataPath + Category.NormalizeFileName() + @"\"; if (!Directory.Exists(path)) Directory.CreateDirectory(path); return path + FileName.NormalizeFileName() + "." + (IsData ? "dat" : ExpirationFileExtension); } private string GetKey(string Category, string Key) { return Category + "_" + Key; } public override List<KeyValuePair<K, V>> Get<K, V>(string Category, IEnumerable<K> Keys) { var result = new List<KeyValuePair<K, V>>(); lock (syncRoot) { Keys.ForEach(key => { string buffer; V value; var cacheKey = GetKey(Category, key.ToString()); if (isMemory) { object memBuffer; if (memoryData.TryGetValue(cacheKey, out memBuffer)) { //track recycle switch (recycleAlgorithm) { case RecycleAlgorithms.MRU: usageStat[cacheKey].Value++; break; default: break; } value = (V)memBuffer; DateTime? expirationDate; if (memoryExpiration.TryGetValue(cacheKey, out expirationDate)) { //expired if (expirationDate != null && (DateTime)expirationDate < DateTime.Now) { value = default(V); memoryData.Remove(cacheKey); memoryExpiration.Remove(cacheKey); } } } else value = default(V); } else { var dataFilePath = GetFile(Category, key.ToString(), true); if (File.Exists(dataFilePath)) { buffer = File.ReadAllText(dataFilePath); //track recycle switch (recycleAlgorithm) { case RecycleAlgorithms.MRU: usageStat[cacheKey].Value++; break; default: break; } //will only deserialize object other than string value = typeof(V) == typeof(string) ? (V)(object)buffer : JSON.Instance.ToObject<V>(buffer); DateTime expirationDate; var expirationFilePath = GetFile(Category, key.ToString(), false); if (File.Exists(expirationFilePath)) { buffer = File.ReadAllText(expirationFilePath); expirationDate = Convert.ToDateTime(buffer); //expired if (expirationDate < DateTime.Now) { value = default(V); File.Delete(dataFilePath); File.Delete(expirationFilePath); } } } else value = default(V); } result.Add(new KeyValuePair<K, V>(key, value)); }); } return result; } public override V Get<K, V>(string Category, K Key) { var buffer = Get<K, V>(Category, new K[] { Key }); var result = buffer.FirstOrDefault(); return result.Value; } public override void Recycle<K>(string Category, long Count) { if (Count < maxCount) return; switch (recycleAlgorithm) { case RecycleAlgorithms.MRU: lock (syncRoot) { var recycledFileCount = 0; if (isMemory) { //find out expired items var memExpired = memoryExpiration.Where(e => e.Value != null && (DateTime)e.Value < DateTime.Now); memExpired.ForEach(u => { memoryData.Remove(u.Key); memoryExpiration.Remove(u.Key); usageStat.Remove(u.Key); }); } else { if (expiredFiles.Count == 0) { Directory.GetFiles(dataPath, "*." + ExpirationFileExtension).ForEach(f => { var buffer = File.ReadAllText(f); var expirationDate = Convert.ToDateTime(buffer); expiredFiles[Path.GetFileNameWithoutExtension(f)] = new KeyValuePair<DateTime, string>(expirationDate, f); }); } //find out expired items var fileExpired = expiredFiles.Where(e => e.Value.Key < DateTime.Now); fileExpired.ForEach(u => { var dataFile = Path.ChangeExtension(u.Value.Value, DataFileExtension); File.Delete(dataFile); File.Delete(u.Value.Value); usageStat.Remove(u.Key); recycledFileCount++; }); } //find out least used items var leastUsed = usageStat.OrderByDescending(s => s.Value.Value).Skip(maxCount - threshold); leastUsed.ForEach(u => { if (isMemory) { memoryData.Remove(u.Key); memoryExpiration.Remove(u.Key); } else { var dataFile = Path.ChangeExtension(u.Value.Key, DataFileExtension); if (File.Exists(dataFile)) { recycledFileCount++; File.Delete(dataFile); } if (File.Exists(u.Value.Key)) File.Delete(u.Value.Key); } usageStat.Remove(u.Key); }); if (!isMemory) { var statFilePath = dataPath + statFile; var count = 0; if (File.Exists(statFilePath)) { var buffer = File.ReadAllText(statFilePath); count = Convert.ToInt32(buffer); } count = count - recycledFileCount; if (count < 0) count = 0; File.WriteAllText(statFilePath, count.ToString()); } } break; default: break; } } } }
相關推薦
C#開源磁碟/記憶體快取引擎
using System; using System.Collections.Generic; using System.Linq; using System.Text; using STSdb4.Database; using fastJSON; using System.IO; na
Android RxJava 實戰系列:從磁碟 / 記憶體快取中 獲取快取資料
前言 Rxjava,由於其基於事件流的鏈式呼叫、邏輯簡潔 & 使用簡單的特點,深受各大 Android開發者的歡迎。 RxJava如此受歡迎的原因,在於其提供了豐富 &
Fresco磁碟記憶體快取 工具類
1. 新增依賴,在AndroidManifest.xml清單檔案中配置: compile 'com.facebook.fresco:fresco:1.5.0' <application android:name=".util.BaseApplication"
基於STSdb和fastJson的磁碟/記憶體快取
更新 1. 增加了對批量處理的支援,寫操作速度提升5倍,讀操作提升100倍 2. 增加了對併發的支援 需求 業務系統用的是資料庫,資料量大,部分只讀或相對穩定業務查詢複雜,每次頁面載入都要花耗不少時間(不討論非同步),覺得可以做一下快取記憶體,譬如用nosql那種key/value快速存取結果 目的
Xenko C#開源遊戲引擎入門
on() actor scale con 為什麽 pro and 三維 str 最近使有和 Three.js 開發三維頁面,覺得很有趣。以前在做WP應用的時候使用過MonoGame做過一點東西,後來Windows 10上來,MonoGame好像不怎麽支持了,也沒
Android RxJava操作符的學習---組合合併操作符---從磁碟或記憶體快取中獲取快取資料
1. 需求場景 2. 功能說明 對於從磁碟 / 記憶體快取中 獲取快取資料 的功能邏輯如下: 3. 具體實現 詳細請看程式碼註釋 // 該2變數用於模擬記憶體快取 & 磁碟快取中的資料 String me
高併發、低延遲之C#玩轉CPU快取記憶體(附示例)
寫在前面 好久沒有寫部落格了,一直在不斷地探索響應式DDD,又get到了很多新知識,解惑了很多老問題,最近讀了Martin Fowler大師一篇非常精彩的部落格The LMAX Architecture,裡面有一個術語Mechanical Sympathy,姑且翻譯成軟硬體協同程式設計(Hardware an
.NET高效能程式設計之C#玩轉CPU快取記憶體(附示例)
寫在前面 好久沒有寫部落格了,一直在不斷地探索響應式DDD,又get到了很多新知識,解惑了很多老問題,最近讀了Martin Fowler大師一篇非常精彩的部落格The LMAX Architecture,裡面有一個術語Mechanical Sympathy,姑且翻譯成軟硬體協同程式設計(Hardware a
H2:開源記憶體資料庫引擎
本資源由 伯樂線上 - 劉立華 整理 H2是一個開源的記憶體資料庫。Java編寫、快速、小巧(1.5MB jar包)還提供了Web控制檯管理資料庫內容。 主要功能 非常快速的資料庫引擎。 開源。 Java編寫。 支援標準SQL、
磁碟快取和記憶體快取的區別
記憶體快取 快取記憶體(英語:cache,英語發音:/kæʃ/ kash [1][2][3],簡稱快取),其原始意義是指訪問速度比一般隨機存取儲存器(RAM)快的一種RAM,通常它不像系統主存那樣使用DRAM技術,而使用昂貴但較快速的SRAM技術。 原理
Glide 快取策略 記憶體快取和磁碟快取
本文主要介紹瞭如何配置和管理Glide中的快取,其中大部分內容都可以直接在官方Wiki中找到,這裡只是進行了整理和彙總。言歸正傳,Glide支援圖片的二級快取(並不是三級快取,因為從網路載入並不屬於快取),即記憶體快取和磁碟快取。 磁碟快取 一般的圖片快取指的就是磁碟快取
Glide原始碼閱讀(四)記憶體快取、磁碟快取、跳過快取
一、記憶體快取實現com.bumptech.glide.util.LruCache<T, Y>中,通過LinkedHashMap做記憶體快取Engine中,MemoryCache.put(EngineKey, EngineResource);新增到LinkedHa
Glide 快取工具例子,快取大小獲取,磁碟快取清除(2 種方法),記憶體快取清除
Glide 快取 Simple快取路徑的指定快取大小的獲取磁碟快取清除(兩種方法)記憶體快取清除可 clone 之後檢視使用 SimpleGlide cache Simple.The cache path specifiedThe cache sizeThe disk cache (two ways)Memo
CPU記憶體,磁碟,快取關係?(加深理解)
1. 暫存器是中央處理器內的組成部份。暫存器是有限存貯容量的高速存貯部件,它們可用來暫存指令、資料和位址。在中央處理器的控制部件中,包含的暫存器有指令暫存器(IR)和程式計數器(PC)。在中央處理器的算術及邏輯部件中,包含的暫存器有累加器(ACC)。 2. 記
Android快取機制Lrucache記憶體快取和DiskLruCache磁碟快取
1.1 記憶體快取——LruCache原始碼分析 1.1.1 LRU LRU,全稱Least Rencetly Used,即最近最少使用,是一種非常常用的置換演算法,也即淘汰最長時間未使用的物件。LRU在作業系統中的頁面置換演算法中廣泛使用,我們的記憶體或快取空間是有限的,當新加入一個物
iOS開發之記憶體快取 磁碟快取 沙盒
最近一直看到“快取”兩字,索性自己總結一下,希望大神看到多多指點。 說到快取,快取分為記憶體快取和磁碟快取兩種,記憶體是指當前程式的執行空間,磁碟是程式的儲存空間; 記憶體快取速度快容量小,磁碟快取容量大速度慢可持久化;記憶體是臨時儲存檔案用
Android記憶體快取和磁碟快取的實現
記憶體快取 Android自帶的LruCache實現了記憶體快取,LruCache內部主要使用LinkedHashMap的特性來實現,因為LinkedHashMap可支援FIFO和LRU訪問。 LinkedHashMap的特點 LinkedHashMap繼
站在巨人的肩膀上,C++開源庫大全
windows應用 pcr ram perl t對象 rest 容器 企業應用 聲音 程序員要站在巨人的肩膀上,C++擁有豐富的開源庫,這裏包括:標準庫、Web應用框架、人工智能、數據庫、圖片處理、機器學習、日誌、代碼分析等。 標準庫 C++ Standard
Linux下經常使用的C/C++開源Socket庫
bsd 面向對象 sql數據庫 高速 com telnet ade ftp 版本 1. Linux Socket Programming In C++ : http://tldp.org/LDP/LG/issue74/tougher.html2. A
c#開源工具(或者C# 開源框架)
stack windows 框架 ado doc 2.0 release dal .com 1.轉載聲明:本篇內容轉載自http://www.cnblogs.com/gaoyuchuanIT/articles/5612268.html。 2. C# 開源框架(整理)