PageRenderTime 24ms CodeModel.GetById 12ms app.highlight 4ms RepoModel.GetById 2ms app.codeStats 0ms

/NRefactory/ICSharpCode.NRefactory.Tests/TypeSystem/TestInterningProvider.cs

http://github.com/icsharpcode/ILSpy
C# | 207 lines | 14 code | 2 blank | 191 comment | 0 complexity | ddea32b6bb06651ffcb9c5e67c46e9ca MD5 | raw file
  1// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
  2// 
  3// Permission is hereby granted, free of charge, to any person obtaining a copy of this
  4// software and associated documentation files (the "Software"), to deal in the Software
  5// without restriction, including without limitation the rights to use, copy, modify, merge,
  6// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
  7// to whom the Software is furnished to do so, subject to the following conditions:
  8// 
  9// The above copyright notice and this permission notice shall be included in all copies or
 10// substantial portions of the Software.
 11// 
 12// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
 13// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 14// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
 15// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 16// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 17// DEALINGS IN THE SOFTWARE.
 18
 19using System;
 20using System.Collections;
 21using System.Collections.Generic;
 22using System.Collections.ObjectModel;
 23using System.Linq;
 24using System.Runtime.CompilerServices;
 25using System.Runtime.InteropServices;
 26using System.Runtime.Serialization;
 27using ICSharpCode.NRefactory.TypeSystem.Implementation;
 28using ICSharpCode.NRefactory.Utils;
 29using NUnit.Framework;
 30
 31namespace ICSharpCode.NRefactory.TypeSystem
 32{
 33	/* Not a real unit test
 34	[TestFixture]
 35	public class TestInterningProvider
 36	{
 37		sealed class ReferenceComparer : IEqualityComparer<object>
 38		{
 39			public new bool Equals(object a, object b)
 40			{
 41				return ReferenceEquals(a, b);
 42			}
 43			
 44			public int GetHashCode(object obj)
 45			{
 46				return RuntimeHelpers.GetHashCode(obj);
 47			}
 48		}
 49		
 50		sealed class InterningComparer : IEqualityComparer<ISupportsInterning>
 51		{
 52			public bool Equals(ISupportsInterning x, ISupportsInterning y)
 53			{
 54				return x.EqualsForInterning(y);
 55			}
 56			
 57			public int GetHashCode(ISupportsInterning obj)
 58			{
 59				return obj.GetHashCodeForInterning();
 60			}
 61		}
 62		
 63		sealed class ListComparer : IEqualityComparer<IEnumerable<object>>
 64		{
 65			public bool Equals(IEnumerable<object> a, IEnumerable<object> b)
 66			{
 67				if (a.GetType() != b.GetType())
 68					return false;
 69				return Enumerable.SequenceEqual(a, b, new ReferenceComparer());
 70			}
 71			
 72			public int GetHashCode(IEnumerable<object> obj)
 73			{
 74				int hashCode = obj.GetType().GetHashCode();
 75				unchecked {
 76					foreach (object o in obj) {
 77						hashCode *= 27;
 78						hashCode += RuntimeHelpers.GetHashCode(o);
 79					}
 80				}
 81				return hashCode;
 82			}
 83		}
 84		
 85		sealed class InterningProvider : IInterningProvider
 86		{
 87			internal HashSet<object> uniqueObjectsPreIntern = new HashSet<object>(new ReferenceComparer());
 88			internal HashSet<object> uniqueObjectsPostIntern = new HashSet<object>(new ReferenceComparer());
 89			internal Dictionary<object, object> byValueDict = new Dictionary<object, object>();
 90			internal Dictionary<ISupportsInterning, ISupportsInterning> supportsInternDict = new Dictionary<ISupportsInterning, ISupportsInterning>(new InterningComparer());
 91			internal Dictionary<IEnumerable<object>, IEnumerable<object>> listDict = new Dictionary<IEnumerable<object>, IEnumerable<object>>(new ListComparer());
 92			
 93			public T Intern<T>(T obj) where T : class
 94			{
 95				if (obj == null)
 96					return null;
 97				uniqueObjectsPreIntern.Add(obj);
 98				ISupportsInterning s = obj as ISupportsInterning;
 99				if (s != null) {
100					ISupportsInterning output;
101					if (supportsInternDict.TryGetValue(s, out output)) {
102						obj = (T)output;
103					} else {
104						s.PrepareForInterning(this);
105						if (supportsInternDict.TryGetValue(s, out output))
106							obj = (T)output;
107						else
108							supportsInternDict.Add(s, s);
109					}
110				} else if (obj is IType || Type.GetTypeCode(obj.GetType()) >= TypeCode.Boolean) {
111					object output;
112					if (byValueDict.TryGetValue(obj, out output))
113						obj = (T)output;
114					else
115						byValueDict.Add(obj, obj);
116				}
117				uniqueObjectsPostIntern.Add(obj);
118				return obj;
119			}
120			
121			public IList<T> InternList<T>(IList<T> list) where T : class
122			{
123				if (list == null)
124					return null;
125				uniqueObjectsPreIntern.Add(list);
126				for (int i = 0; i < list.Count; i++) {
127					T oldItem = list[i];
128					T newItem = Intern(oldItem);
129					if (oldItem != newItem) {
130						if (list.IsReadOnly)
131							list = new T[list.Count];
132						list[i] = newItem;
133					}
134				}
135				if (!list.IsReadOnly)
136					list = new ReadOnlyCollection<T>(list);
137				IEnumerable<object> output;
138				if (listDict.TryGetValue(list, out output))
139					list = (IList<T>)output;
140				else
141					listDict.Add(list, list);
142				uniqueObjectsPostIntern.Add(list);
143				return list;
144			}
145			
146			public void InternProject(IProjectContent pc)
147			{
148				foreach (var c in TreeTraversal.PreOrder(pc.GetClasses(), c => c.NestedTypes)) {
149					Intern(c.Namespace);
150					Intern(c.Name);
151					foreach (IMember m in c.Members) {
152						Intern(m);
153					}
154				}
155			}
156		}
157		
158		IProjectContent[] LoadProjects(CecilLoader loader)
159		{
160			const string dir = @"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\";
161			return new IProjectContent[] {
162				loader.LoadAssemblyFile(dir + "mscorlib.dll"),
163				loader.LoadAssemblyFile(dir + "System.dll"),
164				loader.LoadAssemblyFile(dir + "System.Core.dll"),
165				loader.LoadAssemblyFile(dir + "System.Xml.dll"),
166				loader.LoadAssemblyFile(dir + "System.Xml.Linq.dll"),
167				loader.LoadAssemblyFile(dir + "System.Data.dll"),
168				loader.LoadAssemblyFile(dir + "System.Drawing.dll"),
169				loader.LoadAssemblyFile(dir + "System.Windows.Forms.dll"),
170				loader.LoadAssemblyFile(dir + "WindowsBase.dll"),
171				loader.LoadAssemblyFile(dir + "PresentationCore.dll"),
172				loader.LoadAssemblyFile(dir + "PresentationFramework.dll")
173			};
174		}
175		
176		[Test]
177		public void PrintStatistics()
178		{
179			long startMemory = GC.GetTotalMemory(true);
180			IProjectContent[] pc = LoadProjects(new CecilLoader());
181			long memoryWithFullPC = GC.GetTotalMemory(true) - startMemory;
182			InterningProvider p = new InterningProvider();
183			CecilLoader loader = new CecilLoader();
184			loader.InterningProvider = p;
185			pc = LoadProjects(loader);
186			PrintStatistics(p);
187			loader = null;
188			p = null;
189			long memoryWithInternedPC = GC.GetTotalMemory(true) - startMemory;
190			GC.KeepAlive(pc);
191			Console.WriteLine(memoryWithInternedPC / 1024 + " KB / " + memoryWithFullPC / 1024 + " KB");
192		}
193		
194		void PrintStatistics(InterningProvider p)
195		{
196			var stats =
197				from obj in p.uniqueObjectsPreIntern
198				group 1 by obj.GetType() into g
199				join g2 in (from obj in p.uniqueObjectsPostIntern group 1 by obj.GetType()) on g.Key equals g2.Key
200				orderby g.Key.FullName
201				select new { Type = g.Key, PreCount = g.Count(), PostCount = g2.Count() };
202			foreach (var element in stats) {
203				Console.WriteLine(element.Type + ": " + element.PostCount + "/" + element.PreCount);
204			}
205		}
206	}//*/
207}