Skip to content

Commit aad512f

Browse files
committed
HierarchyDefCollection: cache invalidation without events
1 parent 0538b38 commit aad512f

File tree

1 file changed

+26
-24
lines changed

1 file changed

+26
-24
lines changed

Orm/Xtensive.Orm/Orm/Building/Definitions/HierarchyDefCollection.cs

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ public HierarchyDefCollectionChangedEventArgs(HierarchyDef item)
2727
/// </summary>
2828
public class HierarchyDefCollection : CollectionBaseSlim<HierarchyDef>
2929
{
30+
private readonly Dictionary<Type, HierarchyDef> hierarchyDefByTypeCache = new();
31+
private bool invalidateCache;
32+
3033
public event EventHandler<HierarchyDefCollectionChangedEventArgs> Added;
3134
public event EventHandler<HierarchyDefCollectionChangedEventArgs> Removed;
3235

@@ -43,10 +46,7 @@ public override bool Contains(HierarchyDef item)
4346
/// <param name="key">The key of the value to get.</param>
4447
/// <returns>The value associated with the specified <paramref name="key"/> or <see langword="null"/>
4548
/// if item was not found.</returns>
46-
public HierarchyDef TryGetValue(TypeDef key)
47-
{
48-
return TryGetValue(key.UnderlyingType);
49-
}
49+
public HierarchyDef TryGetValue(TypeDef key) => TryGetValue(key.UnderlyingType);
5050

5151
/// <summary>
5252
/// Gets the value associated with the specified key.
@@ -56,9 +56,11 @@ public HierarchyDef TryGetValue(TypeDef key)
5656
/// if item was not found.</returns>
5757
public HierarchyDef TryGetValue(Type key)
5858
{
59-
foreach (HierarchyDef item in this)
60-
if (item.Root.UnderlyingType==key)
59+
foreach (var item in this) {
60+
if (item.Root.UnderlyingType == key) {
6161
return item;
62+
}
63+
}
6264
return null;
6365
}
6466

@@ -67,13 +69,14 @@ public HierarchyDef TryGetValue(Type key)
6769
/// </summary>
6870
/// <exception cref="ArgumentException"> when item was not found.</exception>
6971
public HierarchyDef this[Type key] =>
70-
TryGetValue(key) ?? throw new ArgumentException(String.Format(Strings.ExItemByKeyXWasNotFound, key), "key");
72+
TryGetValue(key) ?? throw new ArgumentException(string.Format(Strings.ExItemByKeyXWasNotFound, key), nameof(key));
7173

7274
/// <inheritdoc/>
7375
public override void Add(HierarchyDef item)
7476
{
7577
base.Add(item);
7678
Added?.Invoke(this, new HierarchyDefCollectionChangedEventArgs(item));
79+
invalidateCache = true;
7780
}
7881

7982
/// <inheritdoc/>
@@ -89,6 +92,7 @@ public override bool Remove(HierarchyDef item)
8992
{
9093
if (base.Remove(item)) {
9194
Removed?.Invoke(this, new HierarchyDefCollectionChangedEventArgs(item));
95+
invalidateCache = true;
9296
return true;
9397
}
9498
return false;
@@ -100,11 +104,10 @@ public override void Clear()
100104
foreach (var item in this) {
101105
Removed?.Invoke(this, new HierarchyDefCollectionChangedEventArgs(item));
102106
}
107+
invalidateCache = true;
103108
base.Clear();
104109
}
105110

106-
private readonly Dictionary<Type, HierarchyDef> hierarchyDefByTypeCache = new();
107-
108111
/// <summary>
109112
/// Finds the hierarchy.
110113
/// </summary>
@@ -115,24 +118,23 @@ public HierarchyDef Find(TypeDef item)
115118
ArgumentValidator.EnsureArgumentNotNull(item, "item");
116119
var itemUnderlyingType = item.UnderlyingType;
117120

118-
if (!hierarchyDefByTypeCache.TryGetValue(itemUnderlyingType, out var hierarchyDef)) {
119-
hierarchyDef = this.FirstOrDefault(hierarchy => hierarchy.Root.UnderlyingType.IsAssignableFrom(itemUnderlyingType));
120-
hierarchyDefByTypeCache.Add(itemUnderlyingType, hierarchyDef);
121+
HierarchyDef hierarchyDef;
122+
if (invalidateCache) {
123+
hierarchyDefByTypeCache.Clear();
124+
invalidateCache = false;
125+
126+
FindAndCache(itemUnderlyingType, out hierarchyDef);
127+
}
128+
else if (!hierarchyDefByTypeCache.TryGetValue(itemUnderlyingType, out hierarchyDef)) {
129+
FindAndCache(itemUnderlyingType, out hierarchyDef);
121130
}
122131
return hierarchyDef;
123-
}
124-
125-
private void ClearCache(object _, HierarchyDefCollectionChangedEventArgs __)
126-
{
127-
hierarchyDefByTypeCache.Clear();
128-
}
129132

130-
public HierarchyDefCollection()
131-
{
132-
Added += ClearCache;
133-
Removed += ClearCache;
133+
void FindAndCache(Type underlyingType, out HierarchyDef hierarchyDef1)
134+
{
135+
hierarchyDef1 = this.FirstOrDefault(hierarchy => hierarchy.Root.UnderlyingType.IsAssignableFrom(underlyingType));
136+
hierarchyDefByTypeCache.Add(itemUnderlyingType, hierarchyDef1);
137+
}
134138
}
135-
136-
private void HierarchyDefCollection_Removed(object sender, HierarchyDefCollectionChangedEventArgs e) => throw new NotImplementedException();
137139
}
138140
}

0 commit comments

Comments
 (0)