Skip to content

Commit

Permalink
Cherry-picking #9578 to 2.0.3
Browse files Browse the repository at this point in the history
  • Loading branch information
reddyashish committed May 21, 2019
1 parent 3d46bbf commit fab0735
Show file tree
Hide file tree
Showing 4 changed files with 177 additions and 18 deletions.
58 changes: 44 additions & 14 deletions src/Engine/ProtoCore/Lang/CallSite.cs
Original file line number Diff line number Diff line change
Expand Up @@ -809,22 +809,44 @@ private FunctionEndPoint GetLooseCompliantFEP(
return compliantTarget;
}


/// <summary>
/// This helper function checks if the current replication option is
/// similar to the previous option but of a higher rank.
/// Checks if the first entry is same in both the options and the current options count is more.
/// </summary>
/// <returns>Returns true or false based on the condition described above.
/// </returns>
private Boolean IsSimilarOptionButOfHigherRank(List<ReplicationInstruction> oldOption, List<ReplicationInstruction> newOption)
{
if (oldOption.Count > 0 && newOption.Count > 0 && oldOption.Count < newOption.Count)
{
if (oldOption[0].Equals(newOption[0]))
return true;
}
return false;
}

private void ComputeFeps(
Context context,
List<StackValue> arguments,
FunctionGroup funcGroup,
List<ReplicationInstruction> instructions,
StackFrame stackFrame,
RuntimeCore runtimeCore,
out List<FunctionEndPoint> resolvesFeps,
out List<FunctionEndPoint> resolvedFeps,
out List<ReplicationInstruction> replicationInstructions)
{
replicationInstructions = null;
resolvedFeps = null;
var matchFound = false;

#region Case 1: Replication guide with exact match
{
FunctionEndPoint fep = GetCompleteMatchFunctionEndPoint(context, arguments, funcGroup, instructions, stackFrame, runtimeCore);
if (fep != null)
{
resolvesFeps = new List<FunctionEndPoint>() { fep };
resolvedFeps = new List<FunctionEndPoint>() { fep };
replicationInstructions = instructions;
return;
}
Expand All @@ -842,13 +864,17 @@ private void ComputeFeps(
HashSet<FunctionEndPoint> lookups;
if (funcGroup.CanGetExactMatchStatics(context, reducedParams, stackFrame, runtimeCore, out lookups))
{
//Otherwise we have a cluster of FEPs that can be used to dispatch the array
resolvesFeps = new List<FunctionEndPoint>(lookups);
replicationInstructions = replicationOption;
return;
if (replicationInstructions == null || IsSimilarOptionButOfHigherRank(replicationInstructions, replicationOption))
{
//Otherwise we have a cluster of FEPs that can be used to dispatch the array
resolvedFeps = new List<FunctionEndPoint>(lookups);
replicationInstructions = replicationOption;
matchFound = true;
}
}
}

if (matchFound)
return;
}
#endregion

Expand All @@ -857,7 +883,7 @@ private void ComputeFeps(
FunctionEndPoint compliantTarget = GetCompliantFEP(context, arguments, funcGroup, instructions, stackFrame, runtimeCore);
if (compliantTarget != null)
{
resolvesFeps = new List<FunctionEndPoint>() { compliantTarget };
resolvedFeps = new List<FunctionEndPoint>() { compliantTarget };
replicationInstructions = instructions;
return;
}
Expand All @@ -873,11 +899,13 @@ private void ComputeFeps(
FunctionEndPoint compliantTarget = GetCompliantFEP(context, arguments, funcGroup, replicationOption, stackFrame, runtimeCore);
if (compliantTarget != null)
{
resolvesFeps = new List<FunctionEndPoint>() { compliantTarget };
resolvedFeps = new List<FunctionEndPoint>() { compliantTarget };
replicationInstructions = replicationOption;
return;
matchFound = true;
}
}
if (matchFound)
return;
}
}

Expand All @@ -893,7 +921,7 @@ private void ComputeFeps(
FunctionEndPoint compliantTarget = GetCompliantFEP(context, arguments, funcGroup, replicationOption, stackFrame, runtimeCore, true);
if (compliantTarget != null)
{
resolvesFeps = new List<FunctionEndPoint>() { compliantTarget };
resolvedFeps = new List<FunctionEndPoint>() { compliantTarget };
replicationInstructions = replicationOption;
return;
}
Expand All @@ -908,15 +936,17 @@ private void ComputeFeps(
FunctionEndPoint compliantTarget = GetLooseCompliantFEP(context, arguments, funcGroup, replicationOption, stackFrame, runtimeCore);
if (compliantTarget != null)
{
resolvesFeps = new List<FunctionEndPoint>() { compliantTarget };
resolvedFeps = new List<FunctionEndPoint>() { compliantTarget };
replicationInstructions = replicationOption;
return;
matchFound = true;
}
}
if (matchFound)
return;
}
#endregion

resolvesFeps = new List<FunctionEndPoint>();
resolvedFeps = new List<FunctionEndPoint>();
replicationInstructions = instructions;
}

Expand Down
26 changes: 24 additions & 2 deletions src/Engine/ProtoCore/Lang/Replication/ReplicationInstruction.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Text;
using System;
using System.Collections.Generic;
using System.Linq;

namespace ProtoCore.Lang.Replication
{
Expand Down Expand Up @@ -44,5 +45,26 @@ public override string ToString()
}

}

public Boolean Equals(ReplicationInstruction oldOption) {

if (this.Zipped == oldOption.Zipped && this.ZipAlgorithm == oldOption.ZipAlgorithm)
{
if (this.ZipIndecies == null && oldOption.ZipIndecies == null)
return true;

if (this.ZipIndecies != null && oldOption.ZipIndecies != null)
{
// Fastest way to compare all elements of 2 lists.
// Excluding one list from another list and checking if the leftover lists is empty or not.
// https://stackoverflow.com/questions/12795882/quickest-way-to-compare-two-list
var currentExcludesOldList = this.ZipIndecies.Except(oldOption.ZipIndecies).ToList();
var oldExcludescurrentList = oldOption.ZipIndecies.Except(this.ZipIndecies).ToList();

return !currentExcludesOldList.Any() && !oldExcludescurrentList.Any();
}
}
return false;
}
}
}
46 changes: 45 additions & 1 deletion test/Engine/ProtoTest/Associative/BuiltinMethodsTest.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System;
using NUnit.Framework;
using ProtoCore.DSASM.Mirror;
using ProtoTest.TD;
using ProtoTestFx.TD;
namespace ProtoTest.Associative
{
Expand Down Expand Up @@ -1069,6 +1068,51 @@ public void TestTryGetValuesFromDictionary08()
thisTest.Verify("r", null);
}

[Test]
public void TestTryGetValuesFromDictionary09()
{
string code = @"
a = { ""in"" : 42, ""out"" : 24 };
b = { ""in"" : 24, ""out"" : 42 };
c = [[a],[[b]]];
r1 = Dictionary.ValueAtKey(c, ""in"");
r2 = Dictionary.ValueAtKey(c, ""out"");
";
var mirror = thisTest.RunScriptSource(code);
thisTest.Verify("r1", new object[] { new object[] { 42 } , new object[] { new object[] { 24 } } });
thisTest.Verify("r2", new object[] { new object[] { 24 } , new object[] { new object[] { 42 } } });
}

[Test]
public void TestTryGetValuesFromDictionary10()
{
string code = @"
a = { ""in"" : 42, ""out"" : 24 };
b = { ""in"" : 24, ""out"" : 42 };
c = [[[a]],b];
r1 = Dictionary.ValueAtKey(c, ""in"");
r2 = Dictionary.ValueAtKey(c, ""out"");
";
var mirror = thisTest.RunScriptSource(code);
thisTest.Verify("r1", new object[] { new object[] { new object[] { 42 } }, 24 });
thisTest.Verify("r2", new object[] { new object[] { new object[] { 24 } }, 42 });
}

[Test, Category("Failure")]
public void TestTryGetValuesFromDictionary11()
{
string code = @"
a = [ ""in"" , 42, ""out"" , 24 ];
b = { ""in"" : 24, ""out"" : 42 };
c = [a,[b]];
r1 = Dictionary.ValueAtKey(c, ""in"");
r2 = Dictionary.ValueAtKey(c, ""out"");
";
var mirror = thisTest.RunScriptSource(code);
thisTest.Verify("r1", new object[] { new object[] { null, null, null, null }, new object[] { 24 } });
thisTest.Verify("r2", new object[] { new object[] { null, null, null, null }, new object[] { 42 } });
}

[Test]
public void TestGetKeysFromNonArray()
{
Expand Down
65 changes: 64 additions & 1 deletion test/Engine/ProtoTest/TD/Associative/Replication.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4926,7 +4926,70 @@ public void TestReplicationInInlineConditional()
thisTest.RunScriptSource(code);
thisTest.Verify("r", new object[] { 2, 5, 7 });
}
}

// This tests the case 2 block in the computeFeps method(CallSite.cs line:943)
[Test]
public void TestReplicationWithEmptyListInNestedLists()
{
string code = @"import(""FFITarget.dll"");
pt = DummyPoint2D.ByCoordinates(0,0);
l = [[],[pt]];
px1 = DummyPoint2D.X(l);
pt = DummyPoint2D.ByCoordinates(0,0);
l2 = [[pt],[]];
px2 = DummyPoint2D.X(l2);
";
var mirror = thisTest.RunScriptSource(code);
thisTest.Verify("px1", new object[] { new object[] { }, new object[] { 0 } });
thisTest.Verify("px2", new object[] { new object[] { 0 }, new object[] { } });
}

// This tests the case 4 block in the computeFeps method(CallSite.cs line:943)
[Test]
public void TestReplicationWithNullElementInNestedLists()
{
string code = @"import(""FFITarget.dll"");
pt = DummyPoint2D.ByCoordinates(0,0);
l = [null,[pt]];
px1 = DummyPoint2D.X(l);
pt = DummyPoint2D.ByCoordinates(0,0);
l2 = [[pt],null];
px2 = DummyPoint2D.X(l2);
";

var mirror = thisTest.RunScriptSource(code);
thisTest.Verify("px1", new object[] { null, new object[] { 0 } });
thisTest.Verify("px2", new object[] { new object[] { 0 }, null });
}

// This tests the case:6 block in the computeFeps method(CallSite.cs line:943)
// input example for case 6: l4 and l5 lists.
[Test]
public void TestReplicationWithArraysOfDifferentRanks()
{
string code = @"import(""FFITarget.dll"");
t1 = [1, [2]];
t2 = t1 + 5;
pt = DummyPoint2D.ByCoordinates(0,0);
l1 = [[[pt]],[pt]];
px1 = DummyPoint2D.X(l1);
l2 = [[pt],[[pt]]];
px2 = DummyPoint2D.X(l2);
l3 = [[null],[[pt]]];
px3 = DummyPoint2D.X(l3);
l4 = [3.3,[pt],[[pt]]];
px4 = DummyPoint2D.X(l4);
l5 = [""test"",[[pt]],[pt]];
px5 = DummyPoint2D.X(l5);
";
var mirror = thisTest.RunScriptSource(code);
thisTest.Verify("t2", new object[] { 6, new object[] { 7 } });
thisTest.Verify("px1", new object[] { new object[] { new object[] { 0 } }, new object[] { 0 } });
thisTest.Verify("px2", new object[] { new object[] { 0 }, new object[] { new object[] { 0 } } });
thisTest.Verify("px3", new object[] { new object[] { null }, new object[] { new object[] { 0 } } });
thisTest.Verify("px4", new object[] { null, new object[] { 0 }, new object[] { new object[] { 0 } } });
thisTest.Verify("px5", new object[] { null, new object[] { new object[] { 0 } }, new object[] { 0 } });
}
}
}

0 comments on commit fab0735

Please sign in to comment.