Commit 1d508c6d authored by An Ionescu's avatar An Ionescu

Redoing interface hierarchy, reducing code duplication, adding more tests.

parent 16901687
......@@ -19,9 +19,7 @@ namespace Anvoker.Collections.Maps
/// </typeparam>
/// <typeparam name="TVal">The type of the values.
/// </typeparam>
public partial class BiMap<TKey, TVal> : IBiMap<TKey, TVal>,
IReadOnlyBiMap<TKey, TVal>,
IFixedKeysBiMap<TKey, TVal>
public partial class BiMap<TKey, TVal> : IBiMap<TKey, TVal>
{
#region Private Fields
......@@ -324,7 +322,7 @@ namespace Anvoker.Collections.Maps
/// are not cleared before being removed from the
/// <see cref="MultiBiMap{TKey, TVal}"/>.
/// </summary>
public void Clear()
public void ShallowClear()
{
dictFwd.Clear();
dictRev.Clear();
......@@ -370,14 +368,14 @@ namespace Anvoker.Collections.Maps
/// which will reflect in any variable referencing them though read-only
/// wrappers.
/// </summary>
public void DeepClear()
public void Clear()
{
foreach (HashSet<TKey> hashSetKeys in dictRev.Values)
{
hashSetKeys.Clear();
}
Clear();
ShallowClear();
}
/// <summary>
......@@ -423,10 +421,17 @@ namespace Anvoker.Collections.Maps
/// <returns>A <see cref="Dictionary{TVal, IReadOnlyCollection{TKey}}
/// .Enumerator"/> structure for the
/// <see cref="BiMap{TKey, TVal}"/>.</returns>
public IEnumerator<KeyValuePair<TVal, IReadOnlyCollection<TKey>>>
public IEnumerator<KeyValuePair<TVal, TKey>>
GetReverseEnumerator()
=> ((IDictionary<TVal, IReadOnlyCollection<TKey>>)dictRev)
.GetEnumerator();
{
foreach (var kvp in dictRev)
{
foreach (var value in kvp.Value)
{
yield return new KeyValuePair<TVal, TKey>(kvp.Key, value);
}
}
}
/// <summary>
/// Removes the element with the specified key from the
......@@ -563,9 +568,7 @@ namespace Anvoker.Collections.Maps
/// <content>
/// Explicit interface implementations.
/// </content>
public partial class BiMap<TKey, TVal> : IBiMap<TKey, TVal>,
IReadOnlyBiMap<TKey, TVal>,
IFixedKeysBiMap<TKey, TVal>
public partial class BiMap<TKey, TVal> : IBiMap<TKey, TVal>
{
#region Public Properties
......
......@@ -8,79 +8,8 @@ namespace Anvoker.Collections.Maps
/// </summary>
/// <typeparam name="TKey">The type of the keys.</typeparam>
/// <typeparam name="TVal">The type of the values.</typeparam>
public interface IBiMap<TKey, TVal> : IDictionary<TKey, TVal>
{
/// <summary>
/// Gets the <see cref="IEqualityComparer{T}"/> that is used to
/// determine equality of keys for the
/// <see cref="IBiMap{TKey, TVal}"/>.
/// </summary>
IEqualityComparer<TKey> ComparerKey { get; }
/// <summary>
/// Gets the <see cref="IEqualityComparer{T}"/> that is used to
/// determine equality of values for the
/// <see cref="IBiMap{TKey, TVal}"/>.
/// </summary>
IEqualityComparer<TVal> ComparerValue { get; }
/// <summary>
/// Gets the number of unique values in the
/// <see cref="IBiMap{TKey, TVal}"/>.
/// </summary>
int UniqueValueCount { get; }
/// <summary>
/// Gets or sets the value associated with the specified key.
/// </summary>
/// <param name="key">The key of the value to get or set.</param>
/// <returns>The value associated with the specified key.</returns>
new TVal this[TKey key] { get; set; }
/// <summary>
/// Gets all keys that are associated with the specified value.
/// </summary>
/// <param name="val">The value to locate the keys by.</param>
/// <returns>A read-only collection with all of the associated keys.
/// </returns>
IReadOnlyCollection<TKey> this[TVal val] { get; }
/// <summary>
/// Determines whether the <see cref="IBiMap{TKey, TVal}"/> contains a
/// specific value.
/// </summary>
/// <param name="value">The value to locate in the
/// <see cref="IBiMap{TKey, TVal}"/>. The value can be null for reference
/// types.</param>
/// <returns>true if the <see cref="IBiMap{TKey, TVal}"/> contains an
/// element with the specified value; otherwise, false.</returns>
bool ContainsValue(TVal value);
/// <summary>
/// Gets all keys that are associated with the specified value.
/// </summary>
/// <param name="value">The value to locate the keys by.</param>
/// <returns>A read-only collection with all of the associated keys.
/// </returns>
IReadOnlyCollection<TKey> GetKeysWithValue(TVal value);
/// <summary>
/// Returns an enumerator that iterates through the values-key elements
/// of the <see cref="IBiMap{TKey, TVal}"/>. Since the same value can be
/// associated with multiple keys, the keys are grouped in their own
/// collection in each element.
/// </summary>
/// <returns>A <see cref="Dictionary{TVal, IReadOnlyCollection{TKey}}
/// .Enumerator"/> structure for the
/// <see cref="IBiMap{TKey, TVal}"/>.</returns>
IEnumerator<KeyValuePair<TVal, IReadOnlyCollection<TKey>>>
GetReverseEnumerator();
/// <summary>
/// Replaces the value currently associated with the specified key.
/// </summary>
/// <param name="key">The key of the value to replace.</param>
/// <param name="value">The new value.</param>
bool Replace(TKey key, TVal value);
}
public interface IBiMap<TKey, TVal> :
IDictionary<TKey, TVal>,
IFixedKeysBiMap<TKey, TVal>
{ }
}
\ No newline at end of file
......@@ -9,28 +9,8 @@ namespace Anvoker.Collections.Maps
/// <typeparam name="TKey">The type of the keys.</typeparam>
/// <typeparam name="TVal">The type of the values.</typeparam>
public interface IFixedKeysBiMap<TKey, TVal> :
IReadOnlyDictionary<TKey, TVal>
IReadOnlyBiMap<TKey, TVal>
{
/// <summary>
/// Gets the <see cref="IEqualityComparer{T}"/> that is used to
/// determine equality of keys for the
/// <see cref="IFixedKeysBiMap{TKey, TVal}"/>.
/// </summary>
IEqualityComparer<TKey> ComparerKey { get; }
/// <summary>
/// Gets the <see cref="IEqualityComparer{T}"/> that is used to
/// determine equality of values for the
/// <see cref="IFixedKeysBiMap{TKey, TVal}"/>.
/// </summary>
IEqualityComparer<TVal> ComparerValue { get; }
/// <summary>
/// Gets the number of unique values in the
/// <see cref="IFixedKeysBiMap{TKey, TVal}"/>.
/// </summary>
int UniqueValueCount { get; }
/// <summary>
/// Gets all keys that are associated with the specified value.
/// </summary>
......@@ -39,38 +19,6 @@ namespace Anvoker.Collections.Maps
/// </returns>
IReadOnlyCollection<TKey> this[TVal val] { get; }
/// <summary>
/// Determines whether the <see cref="IFixedKeysBiMap{TKey, TVal}"/>
/// contains a specific value.
/// </summary>
/// <param name="value">The value to locate in the
/// <see cref="IFixedKeysBiMap{TKey, TVal}"/>. The value can be null for
/// reference types.</param>
/// <returns>true if the <see cref="IFixedKeysBiMap{TKey, TVal}"/>
/// contains an element with the specified value; otherwise,
/// false.</returns>
bool ContainsValue(TVal value);
/// <summary>
/// Gets all keys that are associated with the specified value.
/// </summary>
/// <param name="value">The value to locate the keys by.</param>
/// <returns>A read-only collection with all of the associated keys.
/// </returns>
IReadOnlyCollection<TKey> GetKeysWithValue(TVal value);
/// <summary>
/// Returns an enumerator that iterates through the values-key elements
/// of the <see cref="IFixedKeysBiMap{TKey, TVal}"/>. Since the same value
/// can be associated with multiple keys, the keys are grouped in their
/// own collection in each element.
/// </summary>
/// <returns>A <see cref="Dictionary{TVal, IReadOnlyCollection{TKey}}
/// .Enumerator"/> structure for the
/// <see cref="IFixedKeysBiMap{TKey, TVal}"/>.</returns>
IEnumerator<KeyValuePair<TVal, IReadOnlyCollection<TKey>>>
GetReverseEnumerator();
/// <summary>
/// Replaces the value currently associated with the specified key.
/// </summary>
......
......@@ -10,67 +10,8 @@ namespace Anvoker.Collections.Maps
/// <typeparam name="TKey">The type of the keys.</typeparam>
/// <typeparam name="TVal">The type of the values.</typeparam>
public interface IFixedKeysMultiBiMap<TKey, TVal> :
IReadOnlyBiMap<TKey, TVal>,
IFixedKeysMultiMap<TKey, TVal>
{
/// <summary>
/// Gets keys whose associated value collection has at least one value
/// in common with the specified collection.
/// </summary>
/// <param name="values">The collection of values to search by.</param>
/// <returns>An enumeration of all of the associated keys.
/// </returns>
IEnumerable<TKey> GetKeysWithAny(IEnumerable<TVal> values);
/// <summary>
/// Gets keys whose associated value collection satisfies set equality
/// with the specified collection.
/// </summary>
/// <param name="values">The collection of values to search by.</param>
/// <returns>An enumeration of all of the associated keys.
/// </returns>
IEnumerable<TKey> GetKeysWithEqualSet(IEnumerable<TVal> values);
/// <summary>
/// Gets keys whose associated value collection is a subset of the
/// specified collection.
/// </summary>
/// <param name="values">The collection of values to search by.</param>
/// <returns>An enumeration of all of the associated keys.
/// </returns>
IEnumerable<TKey> GetKeysWithSubset(IEnumerable<TVal> values);
/// <summary>
/// Gets keys whose associated value collection is a superset of the
/// specified collection.
/// </summary>
/// <param name="values">The collection of values to search by.</param>
/// <returns>An enumeration of all of the associated keys.
/// </returns>
IEnumerable<TKey> GetKeysWithSuperset(IEnumerable<TVal> values);
/// <summary>
/// Removes the element with the specified key from the
/// <see cref="IFixedKeysMultiBiMap{TKey, TVal}"/>.
/// </summary>
/// <param name="key">The key of the element to remove.</param>
/// <returns>true if the element is successfully found and removed;
/// otherwise, false.</returns>
bool RemoveKey(TKey key);
/// <summary>
/// Gets the key associated with the specified value collection, using
/// reference equality on the collection.
/// </summary>
/// <param name="values">The value collection of the key to get.</param>
/// <param name="key">When this method returns, contains the key
/// associated with the value collection, if the collection is found;
/// otherwise, the default value for the type of the key parameter.
/// This parameter is passed uninitialized.</param>
/// <returns>true if <see cref="IFixedKeysMultiBiMap{TKey, TVal}"/>
/// contains a key with the specified collection; otherwise false.
/// </returns>
bool TryGetKeyByCollectionRef(
IReadOnlyCollection<TVal> values, out TKey key);
}
IFixedKeysMultiMap<TKey, TVal>,
IFixedKeysBiMap<TKey, IReadOnlyCollection<TVal>>,
IReadOnlyMultiBiMap<TKey, TVal>
{ }
}
\ No newline at end of file
......@@ -9,23 +9,8 @@ namespace Anvoker.Collections.Maps
/// <typeparam name="TKey">The type of the keys.</typeparam>
/// <typeparam name="TVal">The type of the values.</typeparam>
public interface IFixedKeysMultiMap<TKey, TVal> :
IReadOnlyDictionary<TKey, ICollection<TVal>>,
IReadOnlyDictionary<TKey, TVal>
IReadOnlyMultiMap<TKey, TVal>
{
/// <summary>
/// Gets the <see cref="IEqualityComparer{T}"/> that is used to
/// determine equality of keys for the
/// <see cref="IBiMap{TKey, TVal}"/>.
/// </summary>
IEqualityComparer<TKey> ComparerKey { get; }
/// <summary>
/// Gets the <see cref="IEqualityComparer{T}"/> that is used to
/// determine equality of values for the
/// <see cref="IBiMap{TKey, TVal}"/>.
/// </summary>
IEqualityComparer<TVal> ComparerValue { get; }
/// <summary>
/// Adds the value to the specified key in the
/// <see cref="IFixedKeysMultiMap{TKey, TVal}"/>.
......@@ -48,31 +33,7 @@ namespace Anvoker.Collections.Maps
/// added; otherwise, false.</returns>
bool AddValues(TKey key, IEnumerable<TVal> values);
/// <summary>
/// Determines whether the <see cref="IFixedKeysMultiMap{TKey, TVal}"/>
/// contains a specific value.
/// </summary>
/// <param name="value">The value to locate in the
/// <see cref="IFixedKeysMultiMap{TKey, TVal}"/>. The value can be null
/// for reference types.</param>
/// <returns>true if the <see cref="IFixedKeysMultiMap{TKey, TVal}"/>
/// contains an element with the specified value; otherwise, false.
/// </returns>
bool ContainsValue(TVal value);
/// <summary>
/// Determines whether the <see cref="IFixedKeysMultiMap{TKey, TVal}"/>
/// contains a specific value at the specified key.
/// </summary>
/// <param name="key">The key to locate in the
/// <see cref="IFixedKeysMultiMap{TKey, TVal}"/>.</param>
/// <param name="value">The value to locate in the
/// <see cref="IFixedKeysMultiMap{TKey, TVal}"/>. The value can be null for
/// reference types.</param>
/// <returns>true if the <see cref="IFixedKeysMultiMap{TKey, TVal}"/>
/// contains an element with the specified key and value; otherwise,
/// false.</returns>
bool ContainsKeyWithValue(TKey key, TVal value);
void Replace(TKey key, IEnumerable<TVal> values);
/// <summary>
/// Removes the value associated with the specified key from the
......@@ -102,6 +63,8 @@ namespace Anvoker.Collections.Maps
/// <see cref="IFixedKeysMultiMap{TKey, TVal}"/>.
/// </summary>
/// <param name="key">The key of the element.</param>
void RemoveValuesAll(TKey key);
/// <returns>true if the element is successfully found and its values
/// removed; otherwise, false.</returns>
bool RemoveValuesAll(TKey key);
}
}
\ No newline at end of file
......@@ -9,58 +9,7 @@ namespace Anvoker.Collections.Maps
/// <typeparam name="TKey">The type of the keys.</typeparam>
/// <typeparam name="TVal">The type of the values.</typeparam>
public interface IMultiBiMap<TKey, TVal> :
IReadOnlyBiMap<TKey, TVal>,
IReadOnlyDictionary<TKey, IReadOnlyCollection<TVal>>,
IFixedKeysMultiBiMap<TKey, TVal>,
IMultiMap<TKey, TVal>
{
/// <summary>
/// Gets keys whose associated value collection has at least one value
/// in common with the specified collection.
/// </summary>
/// <param name="values">The collection of values to search by.</param>
/// <returns>An enumeration of all of the associated keys.
/// </returns>
IEnumerable<TKey> GetKeysWithAny(IEnumerable<TVal> values);
/// <summary>
/// Gets keys whose associated value collection satisfies set equality
/// with the specified collection.
/// </summary>
/// <param name="values">The collection of values to search by.</param>
/// <returns>An enumeration of all of the associated keys.
/// </returns>
IEnumerable<TKey> GetKeysWithEqualSet(IEnumerable<TVal> values);
/// <summary>
/// Gets keys whose associated value collection is a subset of the
/// specified collection.
/// </summary>
/// <param name="values">The collection of values to search by.</param>
/// <returns>An enumeration of all of the associated keys.
/// </returns>
IEnumerable<TKey> GetKeysWithSubset(IEnumerable<TVal> values);
/// <summary>
/// Gets keys whose associated value collection is a superset of the
/// specified collection.
/// </summary>
/// <param name="values">The collection of values to search by.</param>
/// <returns>An enumeration of all of the associated keys.
/// </returns>
IEnumerable<TKey> GetKeysWithSuperset(IEnumerable<TVal> values);
/// <summary>
/// Gets the key associated with the specified value collection, using
/// reference equality on the collection.
/// </summary>
/// <param name="values">The value collection of the key to get.</param>
/// <param name="key">When this method returns, contains the key
/// associated with the value collection, if the collection is found;
/// otherwise, the default value for the type of the key parameter.
/// This parameter is passed uninitialized.</param>
/// <returns>true if <see cref="IMultiBiMap{TKey, TVal}"/> contains a key
/// with the specified collection; otherwise false.</returns>
bool TryGetKeyByCollectionRef(
IReadOnlyCollection<TVal> values, out TKey key);
}
{ }
}
\ No newline at end of file
......@@ -8,21 +8,34 @@ namespace Anvoker.Collections.Maps
/// <typeparam name="TKey">The type of the keys.</typeparam>
/// <typeparam name="TVal">The type of the values.</typeparam>
public interface IMultiMap<TKey, TVal> :
IDictionary<TKey, ICollection<TVal>>
IDictionary<TKey, ICollection<TVal>>,
IFixedKeysMultiMap<TKey, TVal>
{
/// <summary>
/// Gets the <see cref="IEqualityComparer{T}"/> that is used to
/// determine equality of keys for the
/// <see cref="IBiMap{TKey, TVal}"/>.
/// Gets the number of elements contained in the
/// <see cref="IMultiMap{TKey, TVal}"/>
/// </summary>
IEqualityComparer<TKey> ComparerKey { get; }
new int Count { get; }
new IReadOnlyCollection<TKey> Keys { get; }
new IReadOnlyCollection<IReadOnlyCollection<TVal>> Values { get; }
new IEnumerable<TVal> this[TKey key] { get; set; }
new IEnumerator<KeyValuePair<TKey, ICollection<TVal>>> GetEnumerator();
new bool TryGetValue(TKey key, out ICollection<TVal> values);
/// <summary>
/// Gets the <see cref="IEqualityComparer{T}"/> that is used to
/// determine equality of values for the
/// <see cref="IBiMap{TKey, TVal}"/>.
/// Determines whether the <see cref="IMultiMap{TKey, TVal}"/> contains
/// a specific key.
/// </summary>
IEqualityComparer<TVal> ComparerValue { get; }
/// <param name="key">The key to locate in the
/// <see cref="IMultiMap{TKey, TVal}"/>.</param>
/// <returns>true if the <see cref="IMultiMap{TKey, TVal}"/> contains
/// an element with the specified key; otherwise, false.</returns>
new bool ContainsKey(TKey key);
/// <summary>
/// Adds the specified key to the
......@@ -50,54 +63,6 @@ namespace Anvoker.Collections.Maps
/// be null for reference types.</param>
void AddKey(TKey key, IEnumerable<TVal> values);
/// <summary>
/// Adds the value to an existing specified key in the
/// <see cref="IMultiMap{TKey, TVal}"/>.
/// </summary>
/// <param name="key">The key of the element.</param>
/// <param name="value">The value to add to the element. The value can
/// be null for reference types.</param>
/// <returns>true if the key was found and the value didn't exist
/// already; otherwise, false.</returns>
bool AddValue(TKey key, TVal value);
/// <summary>
/// Adds the values to an existing specified key in the
/// <see cref="IMultiMap{TKey, TVal}"/>.
/// </summary>
/// <param name="key">The key of the element.</param>
/// <param name="values">The values to add to the element. The value can
/// be null for reference types.</param>
/// <returns>true if the key was found and at least one value didn't
/// exist already; otherwise, false.</returns>
bool AddValues(TKey key, IEnumerable<TVal> values);
/// <summary>
/// Determines whether the <see cref="IMultiMap{TKey, TVal}"/>
/// contains a specific value.
/// </summary>
/// <param name="value">The value to locate in the
/// <see cref="IMultiMap{TKey, TVal}"/>. The value can be null
/// for reference types.</param>
/// <returns>true if the <see cref="IMultiMap{TKey, TVal}"/>
/// contains an element with the specified value; otherwise, false.
/// </returns>
bool ContainsValue(TVal value);
/// <summary>
/// Determines whether the <see cref="IMultiMap{TKey, TVal}"/> contains
/// a specific value at the specified key.
/// </summary>
/// <param name="key">The key to locate in the
/// <see cref="IMultiMap{TKey, TVal}"/>.</param>
/// <param name="value">The value to locate in the
/// <see cref="IMultiMap{TKey, TVal}"/>. The value can be null for
/// reference types.</param>
/// <returns>true if the <see cref="IMultiMap{TKey, TVal}"/> contains
/// an element with the specified key and value; otherwise, false.
/// </returns>
bool ContainsKeyWithValue(TKey key, TVal value);
/// <summary>
/// Determines whether the <see cref="IMultiMap{TKey, TVal}"/> contains
/// all of the specified values at the specified key.
......@@ -111,44 +76,5 @@ namespace Anvoker.Collections.Maps
/// an element with the specified key and values; otherwise, false.
/// </returns>
bool ContainsKeyWithValues(TKey key, IEnumerable<TVal> values);
/// <summary>
/// Removes the element with the specified key from the
/// <see cref="IMultiMap{TKey, TVal}"/>.
/// </summary>
/// <param name="key">The key of the element to remove.</param>
/// <returns>true if the element is successfully found and removed;
/// otherwise, false.</returns>
bool RemoveKey(TKey key);
/// <summary>
/// Removes the value associated with the specified key from the
/// <see cref="IMultiMap{TKey, TVal}"/>.
/// </summary>
/// <param name="key">The key of the element.</param>
/// <param name="value">The value to remove from the element. Values
/// can be null for reference types.</param>
/// <returns>true if the element is successfully found and the value
/// removed; otherwise, false.</returns>
bool RemoveValue(TKey key, TVal value);
/// <summary>
/// Removes all values associated with the specified key from the
/// <see cref="IMultiMap{TKey, TVal}"/> that are found in common
/// with the specified enumeration of values.
/// </summary>
/// <param name="key">The key of the element.</param>
/// <param name="values">The values to remove from the element. Values
/// can be null for reference types.</param>
/// <returns>true if the element is successfully found and at least one
/// value removed; otherwise, false.</returns>
bool RemoveValues(TKey key, IEnumerable<TVal> values);
/// <summary>
/// Removes all values associated with the specified key from the
/// <see cref="IMultiMap{TKey, TVal}"/>.
/// </summary>
/// <param name="key">The key of the element.</param>
void RemoveValuesAll(TKey key);
}
}
\ No newline at end of file
......@@ -50,17 +50,5 @@ namespace Anvoker.Collections.Maps
/// <returns>A read-only collection with all of the associated keys.
/// </returns>
IReadOnlyCollection<TKey> GetKeysWithValue(TVal value);
/// <summary>
/// Returns an enumerator that iterates through the values-key elements
/// of the <see cref="IReadOnlyBiMap{TKey, TVal}"/>. Since the same value
/// can be associated with multiple keys, keys are grouped in their own
/// collection in each element.
/// </summary>
/// <returns>A <see cref="Dictionary{TVal, IReadOnlyCollection{TKey}}
/// .Enumerator"/> structure for the
/// <see cref="IReadOnlyBiMap{TKey, TVal}"/>.</returns>
IEnumerator<KeyValuePair<TVal, IReadOnlyCollection<TKey>>>
GetReverseEnumerator();
}
}
\ No newline at end of file
......@@ -9,8 +9,8 @@ namespace Anvoker.Collections.Maps
/// <typeparam name="TKey">The type of the keys.</typeparam>
/// <typeparam name="TVal">The type of the values.</typeparam>
public interface IReadOnlyMultiBiMap<TKey, TVal> :
IReadOnlyBiMap<TKey, TVal>,
IReadOnlyDictionary<TKey, IReadOnlyCollection<TVal>>
IReadOnlyMultiMap<TKey, TVal>,