Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions Ix.NET/Source/System.Interactive.Async/Join.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ public override void Dispose()
TOuter item;
private int mode;

const int State_Begin = 1;
const int State_If = 1;
const int State_DoLoop = 2;
const int State_For = 3;
const int State_While = 4;
Expand All @@ -108,18 +108,19 @@ protected override async Task<bool> MoveNextCore(CancellationToken cancellationT
{
case AsyncIteratorState.Allocated:
outerEnumerator = outer.GetEnumerator();
mode = State_Begin;
mode = State_If;
state = AsyncIteratorState.Iterating;
goto case AsyncIteratorState.Iterating;

case AsyncIteratorState.Iterating:
switch (mode)
{
case State_Begin:
case State_If:
if (await outerEnumerator.MoveNext(cancellationToken)
.ConfigureAwait(false))
{
lookup = await Internal.Lookup<TKey, TInner>.CreateForJoinAsync(inner, innerKeySelector, comparer, cancellationToken).ConfigureAwait(false);

if (lookup.Count != 0)
{
mode = State_DoLoop;
Expand All @@ -140,7 +141,9 @@ protected override async Task<bool> MoveNextCore(CancellationToken cancellationT
goto case State_For;
}

break;
// advance to while
mode = State_While;
goto case State_While;

case State_For:
current = resultSelector(item, elements[index]);
Expand Down
121 changes: 121 additions & 0 deletions Ix.NET/Source/Tests/AsyncTests.Multiple.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using Xunit;
Expand Down Expand Up @@ -891,6 +892,73 @@ public async Task Join10()
}


[Fact]
public void Join11()
{
var customers = new List<Customer>
{
new Customer {CustomerId = "ALFKI"},
new Customer {CustomerId = "ANANT"},
new Customer {CustomerId = "FISSA"}
};
var orders = new List<Order>
{
new Order { OrderId = 1, CustomerId = "ALFKI"},
new Order { OrderId = 2, CustomerId = "ALFKI"},
new Order { OrderId = 3, CustomerId = "ALFKI"},
new Order { OrderId = 4, CustomerId = "FISSA"},
new Order { OrderId = 5, CustomerId = "FISSA"},
new Order { OrderId = 6, CustomerId = "FISSA"},
};

var asyncResult = customers.ToAsyncEnumerable()
.Join(orders.ToAsyncEnumerable(), c => c.CustomerId, o => o.CustomerId,
(c, o) => new CustomerOrder { CustomerId = c.CustomerId, OrderId = o.OrderId });

var e = asyncResult.GetEnumerator();
HasNext(e, new CustomerOrder { CustomerId = "ALFKI", OrderId = 1 });
HasNext(e, new CustomerOrder { CustomerId = "ALFKI", OrderId = 2 });
HasNext(e, new CustomerOrder { CustomerId = "ALFKI", OrderId = 3 });
HasNext(e, new CustomerOrder { CustomerId = "FISSA", OrderId = 4 });
HasNext(e, new CustomerOrder { CustomerId = "FISSA", OrderId = 5 });
HasNext(e, new CustomerOrder { CustomerId = "FISSA", OrderId = 6 });
NoNext(e);
}

[Fact]
public void Join12()
{
var customers = new List<Customer>
{
new Customer {CustomerId = "ANANT"},
new Customer {CustomerId = "ALFKI"},
new Customer {CustomerId = "FISSA"}
};
var orders = new List<Order>
{
new Order { OrderId = 1, CustomerId = "ALFKI"},
new Order { OrderId = 2, CustomerId = "ALFKI"},
new Order { OrderId = 3, CustomerId = "ALFKI"},
new Order { OrderId = 4, CustomerId = "FISSA"},
new Order { OrderId = 5, CustomerId = "FISSA"},
new Order { OrderId = 6, CustomerId = "FISSA"},
};

var asyncResult = customers.ToAsyncEnumerable()
.Join(orders.ToAsyncEnumerable(), c => c.CustomerId, o => o.CustomerId,
(c, o) => new CustomerOrder { CustomerId = c.CustomerId, OrderId = o.OrderId });

var e = asyncResult.GetEnumerator();
HasNext(e, new CustomerOrder { CustomerId = "ALFKI", OrderId = 1 });
HasNext(e, new CustomerOrder { CustomerId = "ALFKI", OrderId = 2 });
HasNext(e, new CustomerOrder { CustomerId = "ALFKI", OrderId = 3 });
HasNext(e, new CustomerOrder { CustomerId = "FISSA", OrderId = 4 });
HasNext(e, new CustomerOrder { CustomerId = "FISSA", OrderId = 5 });
HasNext(e, new CustomerOrder { CustomerId = "FISSA", OrderId = 6 });
NoNext(e);
}


[Fact]
public void SelectManyMultiple_Null()
{
Expand All @@ -915,5 +983,58 @@ public void SelectManyMultiple1()
HasNext(e, 4);
NoNext(e);
}


public class Customer
{
public string CustomerId { get; set; }
}

public class Order
{
public int OrderId { get; set; }
public string CustomerId { get; set; }
}

[DebuggerDisplay("CustomerId = {CustomerId}, OrderId = {OrderId}")]
public class CustomerOrder : IEquatable<CustomerOrder>
{
public bool Equals(CustomerOrder other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return OrderId == other.OrderId && string.Equals(CustomerId, other.CustomerId);
}

public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return Equals((CustomerOrder)obj);
}

public override int GetHashCode()
{
unchecked
{
return (OrderId * 397) ^ (CustomerId != null ? CustomerId.GetHashCode() : 0);
}
}

public static bool operator ==(CustomerOrder left, CustomerOrder right)
{
return Equals(left, right);
}

public static bool operator !=(CustomerOrder left, CustomerOrder right)
{
return !Equals(left, right);
}

public int OrderId { get; set; }
public string CustomerId { get; set; }
}

}
}