提交 88f2b8aa 编写于 作者: H Heejae Chang

fixed #5203 by caching boxed object only once and re-use them

上级 0fd8c380
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Concurrent;
namespace Microsoft.VisualStudio.LanguageServices.Implementation.TableDataSource
{
internal static class ValueTypeCache
{
/// <summary>
/// Re-use already boxed object for value type.
/// this cache never release cached object. must be used only with fixed set of valut types. or
/// something that grows very slowly like Guid for projects.
/// </summary>
public static object GetOrCreate<T>(T value) where T : struct
{
// let compiler creates a cache for each value type.
return Cache<T>.Instance.GetOrCreate(value);
}
private class Cache<T> where T : struct
{
public static readonly Cache<T> Instance = new Cache<T>();
private static readonly Func<T, object> _boxer = v => (object)v;
// this will be never released, must be used only for fixed size set
private readonly ConcurrentDictionary<T, object> _map =
new ConcurrentDictionary<T, object>(concurrencyLevel: 2, capacity: 5);
public object GetOrCreate(T value)
{
return _map.GetOrAdd(value, _boxer);
}
}
}
}
\ No newline at end of file
......@@ -257,10 +257,10 @@ public override bool TryGetValue(int index, string columnName, out object conten
switch (columnName)
{
case StandardTableKeyNames.ErrorRank:
content = GetErrorRank(data);
content = ValueTypeCache.GetOrCreate(GetErrorRank(data));
return true;
case StandardTableKeyNames.ErrorSeverity:
content = GetErrorCategory(data.Severity);
content = ValueTypeCache.GetOrCreate(GetErrorCategory(data.Severity));
return true;
case StandardTableKeyNames.ErrorCode:
content = data.Id;
......@@ -275,7 +275,7 @@ public override bool TryGetValue(int index, string columnName, out object conten
content = data.Category;
return true;
case StandardTableKeyNames.ErrorSource:
content = GetErrorSource(_source.BuildTool);
content = ValueTypeCache.GetOrCreate(GetErrorSource(_source.BuildTool));
return true;
case StandardTableKeyNames.BuildTool:
content = GetBuildTool(_source.BuildTool);
......@@ -299,7 +299,7 @@ public override bool TryGetValue(int index, string columnName, out object conten
content = item.ProjectNames;
return ((string[])content).Length > 0;
case StandardTableKeyNames.ProjectGuid:
content = item.ProjectGuid;
content = ValueTypeCache.GetOrCreate(item.ProjectGuid);
return (Guid)content != Guid.Empty;
case ProjectGuids:
content = item.ProjectGuids;
......
......@@ -235,7 +235,7 @@ public override bool TryGetValue(int index, string columnName, out object conten
switch (columnName)
{
case StandardTableKeyNames.Priority:
content = (VSTASKPRIORITY)data.Priority;
content = ValueTypeCache.GetOrCreate((VSTASKPRIORITY)data.Priority);
return true;
case StandardTableKeyNames.Text:
content = data.Message;
......@@ -250,7 +250,7 @@ public override bool TryGetValue(int index, string columnName, out object conten
content = GetLineColumn(data).Character;
return true;
case StandardTableKeyNames.TaskCategory:
content = VSTASKCATEGORY.CAT_COMMENTS;
content = ValueTypeCache.GetOrCreate(VSTASKCATEGORY.CAT_COMMENTS);
return true;
case StandardTableKeyNames.ProjectName:
content = item.ProjectName;
......@@ -259,7 +259,7 @@ public override bool TryGetValue(int index, string columnName, out object conten
content = item.ProjectNames;
return ((string[])content).Length > 0;
case StandardTableKeyNames.ProjectGuid:
content = item.ProjectGuid;
content = ValueTypeCache.GetOrCreate(item.ProjectGuid);
return (Guid)content != Guid.Empty;
case ProjectGuids:
content = item.ProjectGuids;
......
......@@ -180,10 +180,11 @@ public override bool TryGetValue(int index, string columnName, out object conten
switch (columnName)
{
case StandardTableKeyNames.ErrorRank:
content = WellKnownDiagnosticTags.Build;
// build error gets highest rank
content = ValueTypeCache.GetOrCreate(ErrorRank.Lexical);
return true;
case StandardTableKeyNames.ErrorSeverity:
content = GetErrorCategory(data.Severity);
content = ValueTypeCache.GetOrCreate(GetErrorCategory(data.Severity));
return true;
case StandardTableKeyNames.ErrorCode:
content = data.Id;
......@@ -198,7 +199,7 @@ public override bool TryGetValue(int index, string columnName, out object conten
content = data.Category;
return true;
case StandardTableKeyNames.ErrorSource:
content = ErrorSource.Build;
content = ValueTypeCache.GetOrCreate(ErrorSource.Build);
return true;
case StandardTableKeyNames.BuildTool:
content = _source.BuildTool;
......@@ -222,7 +223,7 @@ public override bool TryGetValue(int index, string columnName, out object conten
content = item.ProjectNames;
return ((string[])content).Length > 0;
case StandardTableKeyNames.ProjectGuid:
content = item.ProjectGuid;
content = ValueTypeCache.GetOrCreate(item.ProjectGuid);
return (Guid)content != Guid.Empty;
case ProjectGuids:
content = item.ProjectGuids;
......
......@@ -78,6 +78,7 @@
<Compile Include="Implementation\ProjectInfo\DefaultProjectInfoServiceFactory.cs" />
<Compile Include="Implementation\TableDataSource\MiscTodoListTableControlEventProcessorProvider.cs" />
<Compile Include="Implementation\TableDataSource\UriNavigator.cs" />
<Compile Include="Implementation\TableDataSource\ValueTypeCache.cs" />
<Compile Include="Implementation\TableDataSource\VisualStudioBaseDiagnosticListTable.LiveTableDataSource.cs" />
<Compile Include="Implementation\TableDataSource\VisualStudioDiagnosticListTable.BuildTableDataSource.cs" />
<Compile Include="Implementation\TableDataSource\VisualStudioDiagnosticListTable.cs" />
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册