Skip to content
Permalink
Browse files

Refactor SortedCollection to use a LinkedList + minor changes

  • Loading branch information...
a046 committed Feb 22, 2019
1 parent ce9d178 commit 73e5b2f05b68d640542ce2848ecf8863ae641432
@@ -149,7 +149,6 @@ public static ICollectQuery<IEnumerable<TSource>> Collect<TSource>(this IQuery<T
return new QueryExpression<IEnumerable<TSource>>(source.Builder);
}


/// <summary>
/// Configures sorted matching facts to subsequently be sorted ascending by key.
/// </summary>
@@ -37,7 +37,7 @@ internal abstract class SortedAggregatorBase<TSource, TKey> : IAggregator
private readonly SortedFactCollection<TSource, TKey> _sortedFactCollection;
private bool _created = false;

public SortedAggregatorBase(IComparer<TKey> comparer)
protected SortedAggregatorBase(IComparer<TKey> comparer)
{
_sortedFactCollection = new SortedFactCollection<TSource, TKey>(comparer);
}
@@ -6,39 +6,38 @@ namespace NRules.Aggregators
{
internal class SortedFactCollection<TElement, TKey> : IEnumerable<TElement>
{
private readonly SortedDictionary<TKey, List<IFact>> _items;
private readonly Dictionary<IFact, TKey> _keyMap;
private readonly SortedDictionary<TKey, LinkedList<IFact>> _items;
private readonly Dictionary<IFact, SortedFactData> _dataMap;

public SortedFactCollection(IComparer<TKey> comparer)
{
_keyMap = new Dictionary<IFact, TKey>();
_items = new SortedDictionary<TKey, List<IFact>>(comparer);
_dataMap = new Dictionary<IFact, SortedFactData>();
_items = new SortedDictionary<TKey, LinkedList<IFact>>(comparer);
}

public void AddFact(TKey key, IFact fact)
{
_keyMap[fact] = key;

if (!_items.TryGetValue(key, out var list))
{
list = new List<IFact>();
list = new LinkedList<IFact>();
_items.Add(key, list);
}

list.Add(fact);
var linkedListNode = list.AddLast(fact);
_dataMap[fact] = new SortedFactData(key, linkedListNode);
}

public void RemoveFact(IFact fact)
{
var key = _keyMap[fact];
_keyMap.Remove(fact);
var data = _dataMap[fact];
_dataMap.Remove(fact);

var list = _items[key];
list.Remove(fact);
var list = _items[data.Key];
list.Remove(data.LinkedListNode);

if (list.Count == 0)
{
_items.Remove(key);
_items.Remove(data.Key);
}
}

@@ -68,5 +67,17 @@ IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}

private class SortedFactData
{
internal SortedFactData(TKey key, LinkedListNode<IFact> linkedListNode)
{
Key = key;
LinkedListNode = linkedListNode;
}

public TKey Key { get; }
public LinkedListNode<IFact> LinkedListNode { get; }
}
}
}
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using NRules.Aggregators;
using NRules.RuleModel;
@@ -414,21 +415,21 @@ public void Remove_NonExistent_Throws()
() => target.Remove(null, EmptyTuple(), AsFact(new TestFact(1, "A"), new TestFact(1, "B"))));
}

private MultiKeySortedAggregator<TestFact> CreateTarget_SortWithInt1AndInt2(SortDirection sortDirection1, SortDirection sortDirection2)
private static MultiKeySortedAggregator<TestFact> CreateTarget_SortWithInt1AndInt2(SortDirection sortDirection1, SortDirection sortDirection2)
{
var expression1 = new FactExpression<TestFact, int>(x => x.Int1);
var expression2 = new FactExpression<TestFact, int>(x => x.Int2);
return new MultiKeySortedAggregator<TestFact>(new[] { new SortCriteria(expression1, sortDirection1), new SortCriteria(expression2, sortDirection2) });
}

private MultiKeySortedAggregator<TestFact> CreateTarget_SortWithInt1AndString(SortDirection sortDirectionInt, SortDirection sortDirectionString)
private static MultiKeySortedAggregator<TestFact> CreateTarget_SortWithInt1AndString(SortDirection sortDirectionInt, SortDirection sortDirectionString)
{
var expressionInt = new FactExpression<TestFact, int>(x => x.Int1);
var expressionString = new FactExpression<TestFact, string>(x => x.String);
return new MultiKeySortedAggregator<TestFact>(new[] { new SortCriteria(expressionInt, sortDirectionInt), new SortCriteria(expressionString, sortDirectionString) });
}

private void AssertAggregationResult(AggregationResult[] results, AggregationAction action, params TestFact[] orderedFacts)
private static void AssertAggregationResult(AggregationResult[] results, AggregationAction action, params TestFact[] orderedFacts)
{
Assert.Equal(1, results.Length);

@@ -448,12 +449,12 @@ private void AssertAggregationResult(AggregationResult[] results, AggregationAct
}
}

private class TestFact
private class TestFact : IEquatable<TestFact>
{
public TestFact(int value1, int value2)
{
Int1 = value1;
Int2 = value1;
Int2 = value2;
}

public TestFact(int value1, string stringValue)
@@ -330,29 +330,29 @@ public void Remove_NonExistent_Throws()
() => target.Remove(null, EmptyTuple(), AsFact(new TestFact(1), new TestFact(2))));
}

private SortedAggregator<TestFact, int> CreateTarget(SortDirection sortDirection = SortDirection.Ascending)
private static SortedAggregator<TestFact, int> CreateTarget(SortDirection sortDirection = SortDirection.Ascending)
{
var expression = new FactExpression<TestFact, int>(x => x.Id);
return new SortedAggregator<TestFact, int>(expression, sortDirection);
}

private SortedAggregator<TestFact, string> CreateTarget_SortByValue(SortDirection sortDirection = SortDirection.Ascending)
private static SortedAggregator<TestFact, string> CreateTarget_SortByValue(SortDirection sortDirection = SortDirection.Ascending)
{
var expression = new FactExpression<TestFact, string>(x => x.Value);
return new SortedAggregator<TestFact, string>(expression, sortDirection);
}

private void AssertAggregationResult(AggregationResult[] results, AggregationAction action, params int[] orderedKeys)
private static void AssertAggregationResult(AggregationResult[] results, AggregationAction action, params int[] orderedKeys)
{
AssertAggregationResult(results, action, f => f.Id, orderedKeys);
}

private void AssertAggregationResult(AggregationResult[] results, AggregationAction action, params string[] orderedKeys)
private static void AssertAggregationResult(AggregationResult[] results, AggregationAction action, params string[] orderedKeys)
{
AssertAggregationResult(results, action, f => f.Value, orderedKeys);
}

private void AssertAggregationResult<TKey>(AggregationResult[] results, AggregationAction action, Func<TestFact, TKey> keySelector, params TKey[] orderedKeys)
private static void AssertAggregationResult<TKey>(AggregationResult[] results, AggregationAction action, Func<TestFact, TKey> keySelector, params TKey[] orderedKeys)
{
Assert.Equal(1, results.Length);

0 comments on commit 73e5b2f

Please sign in to comment.
You can’t perform that action at this time.