Skip to content

Commit

Permalink
Replace ICollection with concrete type in OneToManyRelation.
Browse files Browse the repository at this point in the history
  • Loading branch information
Washi1337 committed Sep 17, 2022
1 parent b32727e commit 07b09c3
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ private OneToManyRelation<uint, uint> InitializeTypeDefinitionTree()
return typeDefTree;
}

internal ICollection<uint> GetNestedTypeRids(uint enclosingTypeRid)
internal OneToManyRelation<uint, uint>.ValueSet GetNestedTypeRids(uint enclosingTypeRid)
{
EnsureTypeDefinitionTreeInitialized();
return _typeDefTree.GetValues(enclosingTypeRid);
Expand Down Expand Up @@ -123,7 +123,7 @@ private void InitializeMethodSemantics()
Interlocked.CompareExchange(ref _semanticMethods, semanticMethods, null);
}

internal ICollection<uint> GetMethodSemantics(MetadataToken owner)
internal OneToManyRelation<MetadataToken, uint>.ValueSet GetMethodSemantics(MetadataToken owner)
{
EnsureMethodSemanticsInitialized();
return _semantics.GetValues(owner);
Expand Down Expand Up @@ -213,7 +213,7 @@ private OneToManyRelation<MetadataToken, uint> InitializeCustomAttributes()
/// <inheritdoc />
protected override IList<CustomAttribute> GetCustomAttributes() => GetCustomAttributeCollection(this);

internal ICollection<uint> GetCustomAttributes(MetadataToken ownerToken)
internal OneToManyRelation<MetadataToken, uint>.ValueSet GetCustomAttributes(MetadataToken ownerToken)
{
EnsureCustomAttributesInitialized();
return _customAttributes.GetValues(ownerToken);
Expand Down Expand Up @@ -315,7 +315,7 @@ internal MetadataToken GetGenericParameterOwner(uint parameterRid)
return _genericParameters.GetKey(parameterRid);
}

internal ICollection<uint> GetGenericParameters(MetadataToken ownerToken)
internal OneToManyRelation<MetadataToken, uint>.ValueSet GetGenericParameters(MetadataToken ownerToken)
{
EnsureGenericParametersInitialized();
return _genericParameters.GetValues(ownerToken);
Expand Down Expand Up @@ -350,7 +350,7 @@ internal MetadataToken GetGenericParameterConstraintOwner(uint constraintRid)
return _genericParameterConstraints.GetKey(constraintRid);
}

internal ICollection<uint> GetGenericParameterConstraints(MetadataToken ownerToken)
internal OneToManyRelation<MetadataToken, uint>.ValueSet GetGenericParameterConstraints(MetadataToken ownerToken)
{
EnsureGenericParameterConstrainsInitialized();
return _genericParameterConstraints.GetValues(ownerToken);
Expand Down Expand Up @@ -385,7 +385,7 @@ internal MetadataToken GetInterfaceImplementationOwner(uint implementationRid)
return _interfaces.GetKey(implementationRid);
}

internal ICollection<uint> GetInterfaceImplementationRids(MetadataToken ownerToken)
internal OneToManyRelation<MetadataToken, uint>.ValueSet GetInterfaceImplementationRids(MetadataToken ownerToken)
{
EnsureInterfacesInitialized();
return _interfaces.GetValues(ownerToken);
Expand Down Expand Up @@ -414,7 +414,7 @@ private OneToManyRelation<MetadataToken, uint> InitializeMethodImplementations()
return methodImplementations;
}

internal ICollection<uint> GetMethodImplementationRids(MetadataToken ownerToken)
internal OneToManyRelation<MetadataToken, uint>.ValueSet GetMethodImplementationRids(MetadataToken ownerToken)
{
EnsureMethodImplementationsInitialized();
return _methodImplementations.GetValues(ownerToken);
Expand Down
85 changes: 79 additions & 6 deletions src/AsmResolver/Collections/OneToManyRelation.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using System;
using System.Collections;
using System.Collections.Generic;

namespace AsmResolver.Collections
Expand All @@ -11,15 +13,15 @@ public sealed class OneToManyRelation<TKey, TValue>
where TKey : notnull
where TValue : notnull
{
private readonly Dictionary<TKey, ICollection<TValue>> _memberLists;
private readonly Dictionary<TKey, ValueSet> _memberLists;
private readonly Dictionary<TValue, TKey> _memberOwners;

/// <summary>
/// Creates a new, empty one-to-many relation mapping.
/// </summary>
public OneToManyRelation()
{
_memberLists = new Dictionary<TKey, ICollection<TValue>>();
_memberLists = new Dictionary<TKey, ValueSet>();
_memberOwners = new Dictionary<TValue, TKey>();
}

Expand All @@ -29,7 +31,7 @@ public OneToManyRelation()
/// <param name="capacity">The initial number of elements the relation can store.</param>
public OneToManyRelation(int capacity)
{
_memberLists = new Dictionary<TKey, ICollection<TValue>>(capacity);
_memberLists = new Dictionary<TKey, ValueSet>(capacity);
_memberOwners = new Dictionary<TValue, TKey>(capacity);
}

Expand All @@ -44,7 +46,7 @@ public bool Add(TKey key, TValue value)
{
if (!_memberOwners.ContainsKey(value))
{
GetValues(key).Add(value);
GetValues(key).Items.Add(value);
_memberOwners.Add(value, key);
return true;
}
Expand All @@ -57,11 +59,11 @@ public bool Add(TKey key, TValue value)
/// </summary>
/// <param name="key">The key.</param>
/// <returns>The values.</returns>
public ICollection<TValue> GetValues(TKey key)
public ValueSet GetValues(TKey key)
{
if (!_memberLists.TryGetValue(key, out var items))
{
items = new List<TValue>();
items = new ValueSet();
_memberLists.Add(key, items);
}

Expand All @@ -79,5 +81,76 @@ public ICollection<TValue> GetValues(TKey key)
? key
: default;
}

/// <summary>
/// Represents a collection of values assigned to a single key in a one-to-many relation.
/// </summary>
public class ValueSet : ICollection<TValue>
{
internal List<TValue> Items
{
get;
} = new();

/// <inheritdoc />
public int Count => Items.Count;

/// <inheritdoc />
public bool IsReadOnly => true;

/// <inheritdoc />
public void Add(TValue item) => throw new NotSupportedException();

/// <inheritdoc />
public void Clear() => throw new NotSupportedException();

/// <inheritdoc />
public bool Contains(TValue item) => Items.Contains(item);

/// <inheritdoc />
public void CopyTo(TValue[] array, int arrayIndex) => Items.CopyTo(array, arrayIndex);

/// <inheritdoc />
public bool Remove(TValue item) => throw new NotSupportedException();

/// <summary>
/// Gets an enumerator that enumerates all values in the collection.
/// </summary>
public Enumerator GetEnumerator() => new(Items.GetEnumerator());

/// <inheritdoc />
IEnumerator<TValue> IEnumerable<TValue>.GetEnumerator() => GetEnumerator();

/// <inheritdoc />
IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable) Items).GetEnumerator();

/// <summary>
/// Represents an enumerator that enumerates all items in a value collection.
/// </summary>
public struct Enumerator : IEnumerator<TValue>
{
private List<TValue>.Enumerator _enumerator;

internal Enumerator(List<TValue>.Enumerator enumerator)
{
_enumerator = enumerator;
}

/// <inheritdoc />
public TValue Current => _enumerator.Current!;

/// <inheritdoc />
object IEnumerator.Current => ((IEnumerator) _enumerator).Current!;

/// <inheritdoc />
public bool MoveNext() => _enumerator.MoveNext();

/// <inheritdoc />
public void Reset() => throw new NotSupportedException();

/// <inheritdoc />
public void Dispose() => _enumerator.Dispose();
}
}
}
}

0 comments on commit 07b09c3

Please sign in to comment.