diff --git a/TextLocator/Cache/LFUCache.cs b/TextLocator/Cache/LFUCache.cs new file mode 100644 index 0000000000000000000000000000000000000000..b6032142e881a51913607fab3f6e0ab6acf8f0e7 --- /dev/null +++ b/TextLocator/Cache/LFUCache.cs @@ -0,0 +1,157 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace TextLocator.Cache +{ + + /// + /// LFU(Least Frequently Used)缓存机制 + /// 从数据集中,挑选最不经常使用的数据淘汰。 + /// + public class LFUCache + { + /// + /// 数据键值对 + /// + private Dictionary dataDic; + /// + /// 缓存频率数据节点 + /// + private Dictionary> frequenNodeListDic; + /// + /// 缓存容量大小 + /// + private int _capacity; + /// + /// 最小频率 + /// + private int _minFreq; + + /// + /// 构造函数 + /// + /// 缓存池容量 + public LFUCache(int capacity) + { + _capacity = capacity; + _minFreq = 0; + + dataDic = new Dictionary(capacity); + frequenNodeListDic = new Dictionary>(); + + frequenNodeListDic.Add(0, new LinkedList()); + } + + /// + /// 获取缓存 + /// + /// 接收数据类型 + /// 缓存Key + /// 缓存Value + public T Get(string key) + { + // 验证缓存是否存在 + if (!Exists(key)) + return default(T); + + // 获取缓存值 + var value = dataDic[key].Value; + // 重新写入,频率计数器+1 + Put(key, value); + try + { + // 返回Value + return (T)value; + } + catch + { + return default(T); + } + } + + /// + /// 设置缓存 + /// + /// 缓存Key + /// 缓存Value + public void Put(string key, object value) + { + // 如果容量为0,则返回 + if (_capacity == 0) + return; + + // 构造新的缓存对象 + var newCacheData = new LFUCacheEntity { Key = key, Value = value, Frequen = 0 }; + + // 缓存已存在 + if (dataDic.ContainsKey(key)) + { + // 缓存数据对象 + var cacheEntity = dataDic[key]; + + // 旧的计数器 + var oldFrequen = cacheEntity.Frequen; + // 旧的计数器节点列表 + var oldFrequenNodeList = frequenNodeListDic[oldFrequen]; + // 从缓存频率数据节点 + oldFrequenNodeList.Remove(cacheEntity); + + // 频率计数器+1 + var newFrequen = oldFrequen + 1; + // 缓存频率数据节点不存在 + if (!frequenNodeListDic.ContainsKey(newFrequen)) + { + // 新频率添加节点列表 + frequenNodeListDic.Add(newFrequen, new LinkedList()); + } + + // 设置新缓存频率计数器 + newCacheData.Frequen = newFrequen; + // 缓存频率数据节点添加新缓存 + frequenNodeListDic[newFrequen].AddLast(newCacheData); + // 数据缓存对象设置新缓存 + dataDic[key] = newCacheData; + + // 缓存频率数据节点存在缓存 && 节点数据为0 + if (frequenNodeListDic.ContainsKey(_minFreq) && frequenNodeListDic[_minFreq].Count == 0) { + // 记录访问频率 + _minFreq = newFrequen; + } + return; + } + + // 缓存池 超出容量 + if (_capacity <= dataDic.Count) + { + // 根据记录的访问频率获取需要删除的节点列表 + var deleteNodeList = frequenNodeListDic[_minFreq]; + // 获取需要删除的节点,节点列表第一个元素 + var deleteFirstNode = deleteNodeList.First; + // 删除节点列表第一个元素 + deleteNodeList.RemoveFirst(); + // 数据缓存吃删除第一个元素对应的Key + dataDic.Remove(deleteFirstNode.Value.Key); + } + + // 缓存频率数据节点最后添加新缓存 + frequenNodeListDic[0].AddLast(newCacheData); + // 数据缓存添加新缓存 + dataDic.Add(key, newCacheData); + // 频率计数器归零 + _minFreq = 0; + } + + /// + /// 是否存在缓存 + /// + /// + /// + public bool Exists(string key) + { + return dataDic.ContainsKey(key); + } + } +} diff --git a/TextLocator/Cache/LFUCacheEntity.cs b/TextLocator/Cache/LFUCacheEntity.cs new file mode 100644 index 0000000000000000000000000000000000000000..6d6b83bf11417de8355e5a1f6cbf101e4ad6867e --- /dev/null +++ b/TextLocator/Cache/LFUCacheEntity.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace TextLocator.Cache +{ + /// + /// LFU缓存对象 + /// + public class LFUCacheEntity + { + /// + /// 缓存Key + /// + public string Key { get; set; } + /// + /// 缓存Value + /// + public object Value { get; set; } + /// + /// 缓存使用频率计数器 + /// + public int Frequen { get; set; } + } +} diff --git a/TextLocator/Core/AppConst.cs b/TextLocator/Core/AppConst.cs index 2851fb6376c7e7d6333f7d47acde71ff783c77ab..f96aaf9044646c1f9efda085881e401e5bc21186 100644 --- a/TextLocator/Core/AppConst.cs +++ b/TextLocator/Core/AppConst.cs @@ -36,6 +36,10 @@ namespace TextLocator.Core /// 压缩包解析大小 /// public static int ZIP_FILE_SIZE_LIMIT = int.Parse(AppUtil.ReadValue("AppConfig", "ZipFileSizeLimit", "20000000")); + /// + /// 缓存池容量 + /// + public static int CACHE_POOL_CAPACITY = int.Parse(AppUtil.ReadValue("AppConfig", "CachePoolCapacity", "1000000")); /// diff --git a/TextLocator/MainWindow.xaml.cs b/TextLocator/MainWindow.xaml.cs index 0749b09b5cb2f8c13bf35620df4f998ea6dccbc0..9bf6ab472008614285dbb1159ad01ee7c711f61a 100644 --- a/TextLocator/MainWindow.xaml.cs +++ b/TextLocator/MainWindow.xaml.cs @@ -758,7 +758,14 @@ namespace TextLocator /// 清理查询结果 /// private void CleanSearchResult() - { + { + // 先清空搜索框 + SearchText.Text = ""; + // 光标移除文本框 + SearchText.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next)); + // 光标聚焦 + SearchText.Focus(); + // 搜索结果列表清空 SearchResultList.Items.Clear(); @@ -801,13 +808,6 @@ namespace TextLocator // 隐藏上一个和下一个切换面板 this.SwitchPreview.Visibility = Visibility.Collapsed; - - SearchText.Text = ""; - // 光标移除文本框 - SearchText.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next)); - // 光标聚焦 - SearchText.Focus(); - // 工作状态更新为就绪 WorkStatus.Text = "就绪"; } diff --git a/TextLocator/Properties/AssemblyInfo.cs b/TextLocator/Properties/AssemblyInfo.cs index 2385d32ce66350e9b1860e06ddc86f7707b6a429..666cd99530fb84c218beae01cab722fa47d4a069 100644 --- a/TextLocator/Properties/AssemblyInfo.cs +++ b/TextLocator/Properties/AssemblyInfo.cs @@ -49,8 +49,8 @@ using System.Windows; //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值 //通过使用 "*",如下所示: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.2.10")] -[assembly: AssemblyFileVersion("1.2.10.0")] +[assembly: AssemblyVersion("1.2.11")] +[assembly: AssemblyFileVersion("1.2.11.0")] // log4net [assembly: log4net.Config.XmlConfigurator(Watch = true)] \ No newline at end of file diff --git a/TextLocator/SettingWindow.xaml b/TextLocator/SettingWindow.xaml index b2a4b640649e72435893325b6f79d5bc6c425fa7..53a033cc22972ff105733e18350101500e620e11 100644 --- a/TextLocator/SettingWindow.xaml +++ b/TextLocator/SettingWindow.xaml @@ -10,50 +10,64 @@ Title="设置" Height="380" Width="520" WindowStartupLocation="CenterScreen" WindowStyle="ToolWindow" ResizeMode="CanMinimize" Icon="/Resource/App.ico" Loaded="Window_Loaded" Closed="Window_Closed" > - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - + + + + + + + - - + + - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + - - + +