Skip to content

Commit

Permalink
Add an input iterator which support reading from multiple data source
Browse files Browse the repository at this point in the history
  • Loading branch information
SunMaungOo committed Jan 8, 2020
1 parent a3ffce6 commit 61c569b
Show file tree
Hide file tree
Showing 7 changed files with 325 additions and 1 deletion.
21 changes: 21 additions & 0 deletions LibNavigate/Converter/IZipper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LibNavigate.Converter
{
/// <summary>
/// Function which combine inputs to create new data type
/// </summary>
/// <typeparam name="Input1"></typeparam>
/// <typeparam name="Input2"></typeparam>
/// <typeparam name="Output"></typeparam>
public interface IZipper<Input1,Input2,Output>
{

Output Zip(Data.Nullable<Input1> input1,
Data.Nullable<Input2> input2);
}
}
75 changes: 75 additions & 0 deletions LibNavigate/Data/Nullable.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LibNavigate.Data
{
public sealed class Nullable<T>
{
private readonly T value;

public readonly bool HasValue;

public T Value
{
get
{
if(!HasValue)
{
throw new InvalidOperationException("Does not have value");
}

return value;
}
}
public Nullable(T value)
{
this.value = value;

HasValue = true;
}

private Nullable()
{
this.value = default(T);

HasValue = false;
}

public static Nullable<T> From(T value)
{
return new Nullable<T>(value);
}

public static Nullable<T> Empty()
{
return new Nullable<T>();
}

public T GetValueOrDefault(T defaultValue)
{
return HasValue ? value : defaultValue;
}

public override bool Equals(object other)
{
if (!HasValue) return other == null;
if (other == null) return false;
return value.Equals(other);
}

public override int GetHashCode()
{
return HasValue ? value.GetHashCode() : 0;
}

public override string ToString()
{
return HasValue ? value.ToString() : "";
}


}
}
105 changes: 105 additions & 0 deletions LibNavigate/Iterator/Extend/MultipleInputIterator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
using LibNavigate.Converter;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LibNavigate.Iterator.Extend
{
/// <summary>
/// Input iterator which support reading from multiple data source
/// </summary>
/// <typeparam name="Input1"></typeparam>
/// <typeparam name="Input2"></typeparam>
/// <typeparam name="Output"></typeparam>
public sealed class MultipleInputIterator<Input1, Input2, Output> : IInputIterator<Output>
{
private IInputIterator<Input1> inputIterator1;

private IInputIterator<Input2> inputIterator2;

private IZipper<Input1, Input2, Output> zipper;

/// <summary>
///
/// </summary>
/// <param name="inputIterator1"></param>
/// <param name="inputIterator2"></param>
/// <param name="zipper">Function which create new data type</param>
public MultipleInputIterator(IInputIterator<Input1> inputIterator1,
IInputIterator<Input2> inputIterator2,
IZipper<Input1, Input2, Output> zipper)
{

this.inputIterator1 = inputIterator1;

this.inputIterator2 = inputIterator2;

this.zipper = zipper;
}

public void Begin()
{
inputIterator1.Begin();

inputIterator2.Begin();

}

public void Dispose()
{
inputIterator1.Dispose();

inputIterator2.Dispose();
}

public void End()
{
inputIterator1.End();

inputIterator2.End();
}

public bool IsEnd()
{
return inputIterator1.IsEnd() &&
inputIterator2.IsEnd();
}

public void MoveNext()
{
if(!inputIterator1.IsEnd())
{
inputIterator1.MoveNext();
}

if(!inputIterator2.IsEnd())
{
inputIterator2.MoveNext();
}
}

/// <summary>
/// </summary>
/// <returns>Output which is create from inputs</returns>
public Output Read()
{
Data.Nullable<Input1> input1 = Data.Nullable<Input1>.Empty();

if(!inputIterator1.IsEnd())
{
input1 = Data.Nullable<Input1>.From(inputIterator1.Read());
}

Data.Nullable<Input2> input2 = Data.Nullable<Input2>.Empty();

if (!inputIterator2.IsEnd())
{
input2 = Data.Nullable<Input2>.From(inputIterator2.Read());
}

return zipper.Zip(input1,input2);
}
}
}
3 changes: 3 additions & 0 deletions LibNavigate/LibNavigate.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
<Compile Include="Algorithm\Algorithm.cs" />
<Compile Include="Algorithm\Comparer.cs" />
<Compile Include="Converter\IConverter.cs" />
<Compile Include="Converter\IZipper.cs" />
<Compile Include="Data\Nullable.cs" />
<Compile Include="Function\Function.cs" />
<Compile Include="Iterator\Extend\BackInsertIterator.cs" />
<Compile Include="Iterator\Extend\BackwardInputIterator.cs" />
Expand All @@ -54,6 +56,7 @@
<Compile Include="Iterator\Extend\InputIterator.cs" />
<Compile Include="Iterator\Extend\InputIteratorAdapter.cs" />
<Compile Include="Iterator\Extend\LimitInputIterator.cs" />
<Compile Include="Iterator\Extend\MultipleInputIterator.cs" />
<Compile Include="Iterator\Extend\OutputIteratorAdapter.cs" />
<Compile Include="Iterator\Extend\RandomAccessIterator.cs" />
<Compile Include="Iterator\Extend\RangeInputIterator.cs" />
Expand Down
92 changes: 91 additions & 1 deletion LibNavigateTests/IteratorTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using LibNavigate.Iterator;
using LibNavigate.Algorithm;
using LibNavigate.Iterator;
using LibNavigate.Iterator.Extend;
using LibNavigate.Iterator.Helper;
using Microsoft.VisualStudio.TestTools.UnitTesting;
Expand All @@ -9,6 +10,8 @@ namespace LibNavigateTests
[TestClass()]
public class IteratorTests
{
public object Algorthm { get; private set; }

[TestMethod()]
public void RangeIteratorTest()
{
Expand Down Expand Up @@ -270,5 +273,92 @@ public void LimitInputIterator2()
}
}
}

[TestMethod()]
public void MultipleInputIteratorTest()
{
int[] data1 = { 1, 2 };

int[] data2 = { 3, 4 };

IList<int> lst = new List<int>();

using (IInputIterator<int> inputIterator1 = new InputIterator<int>(data1))
{
using (IInputIterator<int> inputIterator2 = new InputIterator<int>(data2))
{
using (IInputIterator<int> multiInputs = new MultipleInputIterator<int, int, int>(inputIterator1,
inputIterator2, new SumZipper()))
{
using (IOutputIterator<int> output = new BackInsertIterator<int>(lst))
{
Algorithm.Copy(multiInputs, output);
}
}
}
}

Assert.IsTrue(lst.Count==2 &&
lst[0]==4 &&
lst[1]==6);
}

[TestMethod()]
public void MultipleInputIteratorTest2()
{
int[] data1 = { 1, 2 };

int[] data2 = { 3 };

IList<int> lst = new List<int>();

using (IInputIterator<int> inputIterator1 = new InputIterator<int>(data1))
{
using (IInputIterator<int> inputIterator2 = new InputIterator<int>(data2))
{
using (IInputIterator<int> multiInputs = new MultipleInputIterator<int, int, int>(inputIterator1,
inputIterator2, new SumZipper()))
{
using (IOutputIterator<int> output = new BackInsertIterator<int>(lst))
{
Algorithm.Copy(multiInputs, output);
}
}
}
}

Assert.IsTrue(lst.Count == 2 &&
lst[0] == 4 &&
lst[1] == 2);
}

[TestMethod()]
public void MultipleInputIteratorTest3()
{
int[] data1 = { 1 };

int[] data2 = { 3, 4 };

IList<int> lst = new List<int>();

using (IInputIterator<int> inputIterator1 = new InputIterator<int>(data1))
{
using (IInputIterator<int> inputIterator2 = new InputIterator<int>(data2))
{
using (IInputIterator<int> multiInputs = new MultipleInputIterator<int, int, int>(inputIterator1,
inputIterator2, new SumZipper()))
{
using (IOutputIterator<int> output = new BackInsertIterator<int>(lst))
{
Algorithm.Copy(multiInputs, output);
}
}
}
}

Assert.IsTrue(lst.Count == 2 &&
lst[0] == 4 &&
lst[1] == 4);
}
}
}
1 change: 1 addition & 0 deletions LibNavigateTests/LibNavigateTests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
<Compile Include="SortAlgorithmTests.cs" />
<Compile Include="SortedRangeAlgorithmTests.cs" />
<Compile Include="StringToIntConverter.cs" />
<Compile Include="SumZipper.cs" />
<Compile Include="UtilityAlgorithmTests.cs" />
</ItemGroup>
<ItemGroup>
Expand Down
29 changes: 29 additions & 0 deletions LibNavigateTests/SumZipper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using LibNavigate.Converter;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using LibNavigate.Data;

namespace LibNavigateTests
{
public class SumZipper : IZipper<int, int, int>
{
public int Zip(LibNavigate.Data.Nullable<int> input1,
LibNavigate.Data.Nullable<int> input2)
{
if(!input1.HasValue)
{
return input2.Value;
}

if(!input2.HasValue)
{
return input1.Value;
}

return input1.Value + input2.Value;
}
}
}

0 comments on commit 61c569b

Please sign in to comment.