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" >
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
+
+
+
+
+
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
+
+
diff --git a/TextLocator/SettingWindow.xaml.cs b/TextLocator/SettingWindow.xaml.cs
index eb5ca680bf942b68bcceb78fc4351bca6ffc867d..e5b6857c307e071fd6f1413275f9b44b601576d0 100644
--- a/TextLocator/SettingWindow.xaml.cs
+++ b/TextLocator/SettingWindow.xaml.cs
@@ -65,6 +65,9 @@ namespace TextLocator
// 文件读取超时时间
this.FileReadTimeout.Text = AppConst.FILE_READ_TIMEOUT + "";
+
+ // 缓存池容量
+ this.CachePoolCapacity.Text = AppConst.CACHE_POOL_CAPACITY + "";
}
#region 保存并关闭
@@ -85,6 +88,9 @@ namespace TextLocator
// 文件读取超时时间
string fileReadTimeoutText = this.FileReadTimeout.Text;
+ // 缓存池容量
+ string cachePoolCapacityText = this.CachePoolCapacity.Text;
+
// 转换,验证
int minThreads = 0;
try
@@ -152,6 +158,21 @@ namespace TextLocator
return;
}
+ int cachePoolCapacity = 0;
+ try
+ {
+ cachePoolCapacity = int.Parse(cachePoolCapacityText);
+ } catch
+ {
+ Message.ShowWarning("MessageContainer", "缓存池容量设置错误");
+ return;
+ }
+ if (cachePoolCapacity < 300000 || cachePoolCapacity > 3000000)
+ {
+ Message.ShowWarning("MessageContainer", "建议设置在30-300w范围内");
+ return;
+ }
+
// 刷新、保存
AppConst.THREAD_POOL_MIN_SIZE = minThreads;
AppConst.THREAD_POOL_MAX_SIZE = maxThreads;
@@ -166,6 +187,10 @@ namespace TextLocator
AppUtil.WriteValue("AppConfig", "FileReadTimeout", AppConst.FILE_READ_TIMEOUT + "");
log.Debug("修改文件读取超时时间:" + AppConst.FILE_READ_TIMEOUT);
+ AppConst.CACHE_POOL_CAPACITY = cachePoolCapacity;
+ AppUtil.WriteValue("AppConfig", "CachePoolCapacity", AppConst.CACHE_POOL_CAPACITY + "");
+ log.Debug("修改缓存池容量:" + AppConst.CACHE_POOL_CAPACITY);
+
this.Close();
}
#endregion
diff --git a/TextLocator/TextLocator.csproj b/TextLocator/TextLocator.csproj
index a913e9bdef3c3eb45926b9194a058017df0989dd..687fbb9cb9323832a7795bbc0c8be541f824d99e 100644
--- a/TextLocator/TextLocator.csproj
+++ b/TextLocator/TextLocator.csproj
@@ -177,6 +177,8 @@
MSBuild:Compile
Designer
+
+
diff --git a/TextLocator/Util/CacheUtil.cs b/TextLocator/Util/CacheUtil.cs
index 82b2c6d2165835deece2deb3585d351ad760b39b..0f53b3ecc232b526cc4f46fe9613c61ce9bf6384 100644
--- a/TextLocator/Util/CacheUtil.cs
+++ b/TextLocator/Util/CacheUtil.cs
@@ -1,4 +1,6 @@
using System.Collections.Generic;
+using TextLocator.Cache;
+using TextLocator.Core;
namespace TextLocator.Util
{
@@ -7,15 +9,22 @@ namespace TextLocator.Util
///
public class CacheUtil
{
- //缓存容器
- private static Dictionary cacheDic = new Dictionary();
+ ///
+ /// LFU缓存
+ ///
+ private static LFUCache _cache;
+
+ static CacheUtil()
+ {
+ _cache = new LFUCache(AppConst.CACHE_POOL_CAPACITY);
+ }
///
/// 添加缓存
///
public static void Add(string key, object value)
{
- cacheDic[key] = value;
+ _cache.Put(key, value);
}
///
@@ -23,11 +32,7 @@ namespace TextLocator.Util
///
public static T Get(string key)
{
- try
- {
- return (T)cacheDic[key];
- } catch { }
- return default(T);
+ return _cache.Get(key);
}
///
@@ -37,7 +42,7 @@ namespace TextLocator.Util
///
public static bool Exsits(string key)
{
- return cacheDic.ContainsKey(key);
+ return _cache.Exists(key);
}
}
}