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

📄 codecompletiondatausagecache.cs

📁 SharpDevelop2.0.0 c#开发免费工具
💻 CS
字号:
// <file>
//     <copyright see="prj:///doc/copyright.txt"/>
//     <license see="prj:///doc/license.txt"/>
//     <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
//     <version>$Revision: 915 $</version>
// </file>

using System;
using System.Collections.Generic;
using System.IO;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Project;

namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
{
	/// <summary>
	/// Tracks the names of the top-used CodeCompletionData items and gives them higher
	/// priority in the completion dropdown.
	/// </summary>
	public static class CodeCompletionDataUsageCache
	{
		struct UsageStruct {
			public int Uses;
			public int ShowCount;
			public UsageStruct(int Uses, int ShowCount) {
				this.Uses = Uses;
				this.ShowCount = ShowCount;
			}
		}
		
		static Dictionary<string, UsageStruct> dict;
		
		// File format for stored CodeCompletionDataUsageCache
		// long   magic   = 0x6567617355444343 (identifies file type = 'CCDUsage')
		// short  version = 1                  (file version)
		// int    itemCount
		// {
		//   string itemName
		//   int    itemUses
		//   int    itemShowCount
		// }
		
		const long magic = 0x6567617355444343;
		const short version = 1;
		
		/// <summary>Minimum number how often an item must be used to be saved to
		/// the file. Items with less uses than this count also get a priority penalty.
		/// (Because the first use would otherwise always be 100% priority)</summary>
		const int MinUsesForSave = 2;
		
		public static string CacheFilename {
			get {
				return Path.Combine(PropertyService.ConfigDirectory, "CodeCompletionUsageCache.dat");
			}
		}
		
		static void LoadCache()
		{
			dict = new Dictionary<string, UsageStruct>();
			ProjectService.SolutionClosed += delegate(object sender, EventArgs e) { SaveCache(); };
			if (!File.Exists(CacheFilename))
				return;
			using (FileStream fs = new FileStream(CacheFilename, FileMode.Open, FileAccess.Read)) {
				using (BinaryReader reader = new BinaryReader(fs)) {
					if (reader.ReadInt64() != magic) {
						LoggingService.Warn("CodeCompletionDataUsageCache: wrong file magic");
						return;
					}
					if (reader.ReadInt16() != version) {
						LoggingService.Warn("CodeCompletionDataUsageCache: unknown file version");
						return;
					}
					int itemCount = reader.ReadInt32();
					for (int i = 0; i < itemCount; i++) {
						string key = reader.ReadString();
						int uses = reader.ReadInt32();
						int showCount = reader.ReadInt32();
						if (showCount > 1000) {
							// reduce count because the usage in the next time
							// should have more influence on the past
							showCount /= 3;
							uses /= 3;
						}
						dict.Add(key, new UsageStruct(uses, showCount));
					}
				}
			}
			LoggingService.Info("Loaded CodeCompletionDataUsageCache (" + dict.Count + " items)");
		}
		
		public static void SaveCache()
		{
			if (dict == null) {
				return;
			}
			int count;
			using (FileStream fs = new FileStream(CacheFilename, FileMode.Create, FileAccess.Write)) {
				using (BinaryWriter writer = new BinaryWriter(fs)) {
					count = SaveCache(writer);
				}
			}
			LoggingService.Info("Saved CodeCompletionDataUsageCache (" + count + " of " + dict.Count + " items)");
		}
		
		static int SaveCache(BinaryWriter writer)
		{
			writer.Write(magic);
			writer.Write(version);
			int maxSaveItems = CodeCompletionOptions.DataUsageCacheItemCount;
			if (dict.Count < maxSaveItems) {
				writer.Write(dict.Count);
				foreach (KeyValuePair<string, UsageStruct> entry in dict) {
					writer.Write(entry.Key);
					writer.Write(entry.Value.Uses);
					writer.Write(entry.Value.ShowCount);
				}
				return dict.Count;
			} else {
				List<KeyValuePair<string, UsageStruct>> saveItems = new List<KeyValuePair<string, UsageStruct>>();
				foreach (KeyValuePair<string, UsageStruct> entry in dict) {
					if (entry.Value.Uses > MinUsesForSave) {
						saveItems.Add(entry);
					}
				}
				if (saveItems.Count > maxSaveItems) {
					saveItems.Sort(new SaveItemsComparer());
				}
				int count = Math.Min(maxSaveItems, saveItems.Count);
				writer.Write(count);
				for (int i = 0; i < count; i++) {
					KeyValuePair<string, UsageStruct> entry = saveItems[i];
					writer.Write(entry.Key);
					writer.Write(entry.Value.Uses);
					writer.Write(entry.Value.ShowCount);
				}
				return count;
			}
		}
		
		class SaveItemsComparer : IComparer<KeyValuePair<string, UsageStruct>>
		{
			public int Compare(KeyValuePair<string, UsageStruct> x, KeyValuePair<string, UsageStruct> y)
			{
				double a = ((double)x.Value.Uses / x.Value.ShowCount);
				return a.CompareTo((double)y.Value.Uses / y.Value.ShowCount);
			}
		}
		
		public static void ResetCache()
		{
			dict = new Dictionary<string, UsageStruct>();
			try {
				if (File.Exists(CacheFilename)) {
					File.Delete(CacheFilename);
				}
			} catch (Exception ex) {
				LoggingService.Warn("CodeCompletionDataUsageCache.ResetCache(): " + ex.Message);
			}
		}
		
		public static double GetPriority(string dotnetName, bool incrementShowCount)
		{
			if (!CodeCompletionOptions.DataUsageCacheEnabled)
				return 0;
			if (dict == null) {
				LoadCache();
			}
			UsageStruct usage;
			if (!dict.TryGetValue(dotnetName, out usage))
				return 0;
			double priority = (double)usage.Uses / usage.ShowCount;
			if (usage.Uses < MinUsesForSave)
				priority *= 0.2;
			if (incrementShowCount) {
				usage.ShowCount += 1;
				dict[dotnetName] = usage;
			}
			return priority;
		}
		
		public static void IncrementUsage(string dotnetName)
		{
			if (!CodeCompletionOptions.DataUsageCacheEnabled)
				return;
			if (dict == null) {
				LoadCache();
			}
			UsageStruct usage;
			if (!dict.TryGetValue(dotnetName, out usage)) {
				usage = new UsageStruct(0, 2);
			}
			usage.Uses += 1;
			dict[dotnetName] = usage;
		}
	}
}

⌨️ 快捷键说明

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