forked from nhibernate/nhibernate-core
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBackTrackCacheParameterList.cs
105 lines (95 loc) · 2.64 KB
/
BackTrackCacheParameterList.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using NHibernate.Util;
namespace NHibernate.SqlCommand
{
/// <summary>
/// A list of <see cref="Parameter"/> that maintains a cache of backtrace positions for performance purpose.
/// See https://nhibernate.jira.com/browse/NH-3489.
/// </summary>
internal class BackTrackCacheParameterList : Collection<Parameter>
{
private Dictionary<string, SortedSet<int>> _indexesByBackTrace;
private void AddIndex(Parameter parameter, int index)
{
var backTrack = parameter.BackTrack as string;
if (backTrack == null)
return;
SortedSet<int> indexes;
if (!_indexesByBackTrace.TryGetValue(backTrack, out indexes))
{
indexes = new SortedSet<int>();
_indexesByBackTrace.Add(backTrack, indexes);
}
indexes.Add(index);
}
private void RemoveIndexes(Parameter parameter)
{
var backTrack = parameter.BackTrack as string;
if (backTrack != null)
_indexesByBackTrace.Remove(backTrack);
}
private Dictionary<string, SortedSet<int>> BuildBackTrackCache()
{
var indexesByBackTrace = new Dictionary<string, SortedSet<int>>();
IList<Parameter> parameters = Items;
for (int i = 0; i < parameters.Count; i++)
{
var backTrace = parameters[i].BackTrack as string;
if (backTrace != null)
{
SortedSet<int> locations;
if (!indexesByBackTrace.TryGetValue(backTrace, out locations))
{
locations = new SortedSet<int>();
indexesByBackTrace.Add(backTrace, locations);
}
locations.Add(i);
}
}
return indexesByBackTrace;
}
protected override void InsertItem(int index, Parameter item)
{
base.InsertItem(index, item);
if (_indexesByBackTrace != null)
AddIndex(item, index);
}
protected override void RemoveItem(int index)
{
Parameter oldItem = Items[index];
base.RemoveItem(index);
if (_indexesByBackTrace != null)
RemoveIndexes(oldItem);
}
protected override void SetItem(int index, Parameter item)
{
Parameter oldItem = Items[index];
base.SetItem(index, item);
if (_indexesByBackTrace != null)
{
RemoveIndexes(oldItem);
AddIndex(item, index);
}
}
protected override void ClearItems()
{
base.ClearItems();
if (_indexesByBackTrace != null)
_indexesByBackTrace.Clear();
}
public IEnumerable<int> GetEffectiveParameterLocations(string backTrace)
{
if (backTrace != null)
{
if (_indexesByBackTrace == null)
_indexesByBackTrace = BuildBackTrackCache();
SortedSet<int> indexes;
if (_indexesByBackTrace.TryGetValue(backTrace, out indexes))
return indexes;
}
return Array.Empty<int>();
}
}
}