private static List <ReplicationInstruction> Old_BuildPartialReplicationInstructions(List <int?> partialGuides) { Dictionary <int, List <int> > index = new Dictionary <int, List <int> >(); for (int i = 0; i < partialGuides.Count; i++) { if (partialGuides[i].HasValue) { int value = partialGuides[i].Value; if (!index.ContainsKey(value)) { index.Add(value, new List <int>()); } index[value].Add(i); } } //Now walk over the guides in order creating the replication int[] uniqueGuides = new int[index.Keys.Count]; index.Keys.CopyTo(uniqueGuides, 0); Array.Sort(uniqueGuides); List <ReplicationInstruction> ret = new List <ReplicationInstruction>(); foreach (int i in uniqueGuides) { //Create a new replication instruction ReplicationInstruction ri = new ReplicationInstruction(); if (index[i].Count == 1) { ri.CartesianIndex = index[i][0]; ri.Zipped = false; } else { ri.Zipped = true; ri.ZipIndecies = index[i]; } ret.Add(ri); } return(ret); }
/// <summary> /// Convert reduction to instruction. Using zip-first strategy. /// /// For example, /// 0 2 4 > Zip on 1,2 /// 0 1 3 > Zip on 1,2 /// 0 0 2 > Cartesian on 2 /// 0 0 1 > Cartesian on 2 /// </summary> /// <param name="reductions"></param> /// <param name="providedControl"></param> /// <returns></returns> public static List <ReplicationInstruction> ReductionToInstructions(List <int> reductions, List <ReplicationInstruction> providedControl) { List <ReplicationInstruction> ret = new List <ReplicationInstruction>(providedControl); while (true) { int zippableItemCount = reductions.Count(x => x > 0); if (zippableItemCount <= 1) { break; } List <int> locations = new List <int>(); for (int i = 0; i < reductions.Count; i++) { if (reductions[i] >= 1) { locations.Add(i); reductions[i] -= 1; } } ReplicationInstruction ri = new ReplicationInstruction() { CartesianIndex = -1, ZipIndecies = locations, Zipped = true }; ret.Add(ri); } for (int i = 0; i < reductions.Count; i++) { int reduction = reductions[i]; while (reduction > 0) { ReplicationInstruction ri = new ReplicationInstruction() { CartesianIndex = i, ZipIndecies = null, Zipped = false }; ret.Add(ri); reduction--; } } return(ret); }
private static List<ReplicationInstruction> BuildPartialReplicationInstructions(List<List<ProtoCore.ReplicationGuide>> partialRepGuides) { //DS code: foo(a<1><2><3>, b<2>, c) //partialGuides {1,2,3}, {2}, {} //Instructions //Check for out of order unboxing // Comment Jun: Convert from new replication guide data struct to the old format where guides are only a list of ints // TODO Luke: Remove this temporary marshalling and use the replicationguide data structure directly List<List<int>> partialGuides = new List<List<int>>(); List<List<ZipAlgorithm>> partialGuidesLace = new List<List<ZipAlgorithm>>(); foreach (List<ProtoCore.ReplicationGuide> guidesOnParam in partialRepGuides) { List<int> tempGuide = new List<int>(); List<ZipAlgorithm> tempGuideLaceStrategy = new List<ZipAlgorithm>(); foreach (ProtoCore.ReplicationGuide guide in guidesOnParam) { tempGuide.Add(guide.guideNumber); tempGuideLaceStrategy.Add(guide.isLongest ? ZipAlgorithm.Longest : ZipAlgorithm.Shortest); } partialGuides.Add(tempGuide); partialGuidesLace.Add(tempGuideLaceStrategy); } //@TODO: remove this limitation VerifyIncreasingGuideOrdering(partialGuides); //Guide -> args Dictionary<int, List<int>> index = new Dictionary<int, List<int>>(); Dictionary<int, ZipAlgorithm> indexLace = new Dictionary<int, ZipAlgorithm>(); int maxGuide = int.MinValue; foreach (List<int> guidesOnParam in partialGuides) { foreach (int guide in guidesOnParam) maxGuide = Math.Max(maxGuide, guide); } //There were no guides, exit with no instructions if (maxGuide == int.MinValue) return new List<ReplicationInstruction>(); //Iterate over all of the guides for (int guideCounter = 1; guideCounter <= maxGuide; guideCounter++) { index.Add(guideCounter, new List<int>()); indexLace.Add(guideCounter, ZipAlgorithm.Shortest); for (int i = 0; i < partialGuides.Count; i++) if (partialGuides[i].Contains(guideCounter)) { index[guideCounter].Add(i); int indexOfGuide = partialGuides[i].IndexOf(guideCounter); if (partialGuidesLace[i][indexOfGuide] == ZipAlgorithm.Longest) { //If we've previous seen a shortest node with this guide if (i > 0 && indexLace[guideCounter] == ZipAlgorithm.Shortest) { throw new ReplicationCaseNotCurrentlySupported(Resources.ZipAlgorithmError); } //Overwrite the default behaviour indexLace[guideCounter] = ZipAlgorithm.Longest; } else { //it's shortest, if we had something previous saying it should be longest //then we've created a violation foo(a<1>, b1<1L>) is not allowed if (indexLace[guideCounter] == ZipAlgorithm.Longest) { throw new ReplicationCaseNotCurrentlySupported(Resources.ZipAlgorithmError); } else { //Shortest lacing is actually the default, this call should be redundant indexLace[guideCounter] = ZipAlgorithm.Shortest; } } } // Validity.Assert(index[guideCounter].Count > 0, "Sorry, non-contiguous replication guides are not yet supported, please try again without leaving any gaps, err code {3E080694}"); } //Now walk over the guides in order creating the replication int[] uniqueGuides = new int[index.Keys.Count]; index.Keys.CopyTo(uniqueGuides, 0); Array.Sort(uniqueGuides); List<ReplicationInstruction> ret = new List<ReplicationInstruction>(); foreach (int i in uniqueGuides) { //Create a new replication instruction ReplicationInstruction ri = new ReplicationInstruction(); if (index[i].Count == 0) { continue; } else if (index[i].Count == 1) { ri.CartesianIndex = index[i][0]; ri.Zipped = false; } else { ri.Zipped = true; ri.ZipIndecies = index[i]; ri.ZipAlgorithm = indexLace[i]; } ret.Add(ri); } return ret; }
public static List<ReplicationInstruction> ReductionToInstructions(List<int> reductionList, List<ReplicationInstruction> providedControl) { List<ReplicationInstruction> ret = new List<ReplicationInstruction>(); ret.AddRange(providedControl); //if (providedControl.Count > 0) // throw new NotImplementedException(); //Basic sanity check on the reductions foreach (int reduction in reductionList) Validity.Assert(reduction >= 0, "Negative reductions aren't supported {991CBD60-8B2B-438B-BDEB-734D18B4FE68}"); int maxReductionCount = int.MinValue; foreach (int reduction in reductionList) maxReductionCount = Math.Max(maxReductionCount, reduction); //@PERF This is going to do a O(n^2) cost scan, when we could just build a reverse index once.... int lastSeenReduction = 0; //This is the last instruction that we have seen and don't need to inject further //reductions from //Walk over all the reductions that we're going to do for (int i = 1; i <= maxReductionCount; i++) { if (!reductionList.Contains(i)) continue; //We didn't have a reduction of this phase, we'll insert the padding reductions in the next line //Otherwise look at how many times the reduction was contained. If it was more than once zip, otherwise cartesian List<int> locations = new List<int>(); for (int j = 0; j < reductionList.Count; j++) if (reductionList[j] == i) locations.Add(j); // reductionList.f .FindAll((int x) => x == i); Validity.Assert(locations.Count > 0, "We should have trapped this case and short-cut the loop, {DF3D67B8-F1B5-4C61-BF3B-930D4C860FA9}"); if (locations.Count == 1) { //There was one location, this is a cartesian expansion ReplicationInstruction ri = new ReplicationInstruction() { CartesianIndex = locations[0], ZipIndecies = null, Zipped = false }; ret.Add(ri); if (i - lastSeenReduction > 1) { //Add padding instructions //@TODO(Luke): Suspect cartesian padding is incorrect for (int padding = 0; padding < ((i - lastSeenReduction) - 1); padding++) { ReplicationInstruction riPad = new ReplicationInstruction() { CartesianIndex = locations[0], ZipIndecies = null, Zipped = false }; ret.Add(riPad); } } } else { ReplicationInstruction ri = new ReplicationInstruction() { CartesianIndex = -1, ZipIndecies = locations, Zipped = true }; ret.Add(ri); if (i - lastSeenReduction > 1) { //Add padding instructions //@TODO(Luke): Suspect cartesian padding is incorrect for (int padding = 0; padding < ((i - lastSeenReduction) - 1); padding++) { ReplicationInstruction riPad = new ReplicationInstruction() { CartesianIndex = -1, ZipIndecies = locations, Zipped = true }; ret.Add(riPad); } } } lastSeenReduction = i; } return ret; }
private static List<ReplicationInstruction> Old_BuildPartialReplicationInstructions(List<int?> partialGuides) { Dictionary<int, List<int>> index = new Dictionary<int, List<int>>(); for (int i = 0; i < partialGuides.Count; i++) { if (partialGuides[i].HasValue) { int value = partialGuides[i].Value; if (!index.ContainsKey(value)) index.Add(value, new List<int>()); index[value].Add(i); } } //Now walk over the guides in order creating the replication int[] uniqueGuides = new int[index.Keys.Count]; index.Keys.CopyTo(uniqueGuides, 0); Array.Sort(uniqueGuides); List<ReplicationInstruction> ret = new List<ReplicationInstruction>(); foreach (int i in uniqueGuides) { //Create a new replication instruction ReplicationInstruction ri = new ReplicationInstruction(); if (index[i].Count == 1) { ri.CartesianIndex = index[i][0]; ri.Zipped = false; } else { ri.Zipped = true; ri.ZipIndecies = index[i]; } ret.Add(ri); } return ret; }
/// <summary> /// Calculate partial replication instruciton based on replication guide level. /// For example, for foo(xs<1><2><3>, ys<1><1><2>, zs<1><1><3>), the guides /// are: /// /// level | 0 | 1 | 2 | /// ------+-----+-----+-----+ /// xs | 1 | 2 | 3 | /// ------+-----+-----+-----+ /// ys | 1 | 1 | 2 | /// ------+-----+-----+-----+ /// zs | 1 | 1 | 3 | /// /// This function goes through each level and calculate replication instructions. /// /// replication instructions on level 0: /// Zip replication on (0, 1, 2) (i.e., zip on xs, ys, zs) /// /// replication instructions on level 1: /// Zip replication on (1, 2) (i.e., zip on ys, zs) /// Cartesian replication on 0 (i.e., on xs) /// /// replication instructions on level 2: /// Cartesian replication on 1 (i.e., on ys) /// Zip replication on (0, 2) (i.e., zip on xs, zs) /// </summary> /// <param name="partialRepGuides"></param> /// <returns></returns> public static List <ReplicationInstruction> BuildPartialReplicationInstructions(List <List <ReplicationGuide> > partialRepGuides) { if (!partialRepGuides.Any()) { return(new List <ReplicationInstruction>()); } int maxGuideLevel = partialRepGuides.Max(gs => gs.Count); var instructions = new List <ReplicationInstruction>(); for (int level = 0; level < maxGuideLevel; ++level) { var positions = new Dictionary <int, List <int> >(); var algorithms = new Dictionary <int, ZipAlgorithm>(); var guides = new HashSet <int>(); for (int i = 0; i < partialRepGuides.Count; ++i) { var replicationGuides = partialRepGuides[i]; if (replicationGuides == null || replicationGuides.Count <= level) { continue; } // If it is negative or 0, treat it as a stub var guide = replicationGuides[level].GuideNumber; if (guide <= 0) { continue; } var algorithm = replicationGuides[level].IsLongest ? ZipAlgorithm.Longest : ZipAlgorithm.Shortest; guides.Add(guide); List <int> positionList = null; if (!positions.TryGetValue(guide, out positionList)) { positionList = new List <int>(); positions[guide] = positionList; } positionList.Add(i); ZipAlgorithm zipAlgorithm; if (algorithms.TryGetValue(guide, out zipAlgorithm)) { if (algorithm == ZipAlgorithm.Longest) { algorithms[guide] = ZipAlgorithm.Longest; } } else { algorithms[guide] = algorithm; } } var sortedGuides = guides.ToList(); sortedGuides.Sort(); foreach (var guide in sortedGuides) { ReplicationInstruction repInstruction = new ReplicationInstruction(); var positionList = positions[guide]; if (positionList.Count == 1) { repInstruction.Zipped = false; repInstruction.CartesianIndex = positionList[0]; } else { repInstruction.Zipped = true; repInstruction.ZipIndecies = positionList; repInstruction.ZipAlgorithm = algorithms[guide]; } instructions.Add(repInstruction); } } return(instructions); }
private static List <ReplicationInstruction> BuildPartialReplicationInstructions(List <List <ProtoCore.ReplicationGuide> > partialRepGuides) { //DS code: foo(a<1><2><3>, b<2>, c) //partialGuides {1,2,3}, {2}, {} //Instructions //Check for out of order unboxing // Comment Jun: Convert from new replication guide data struct to the old format where guides are only a list of ints // TODO Luke: Remove this temporary marshalling and use the replicationguide data structure directly List <List <int> > partialGuides = new List <List <int> >(); List <List <ZipAlgorithm> > partialGuidesLace = new List <List <ZipAlgorithm> >(); foreach (List <ProtoCore.ReplicationGuide> guidesOnParam in partialRepGuides) { List <int> tempGuide = new List <int>(); List <ZipAlgorithm> tempGuideLaceStrategy = new List <ZipAlgorithm>(); foreach (ProtoCore.ReplicationGuide guide in guidesOnParam) { tempGuide.Add(guide.guideNumber); tempGuideLaceStrategy.Add(guide.isLongest ? ZipAlgorithm.Longest : ZipAlgorithm.Shortest); } partialGuides.Add(tempGuide); partialGuidesLace.Add(tempGuideLaceStrategy); } //@TODO: remove this limitation VerifyIncreasingGuideOrdering(partialGuides); //Guide -> args Dictionary <int, List <int> > index = new Dictionary <int, List <int> >(); Dictionary <int, ZipAlgorithm> indexLace = new Dictionary <int, ZipAlgorithm>(); int maxGuide = int.MinValue; foreach (List <int> guidesOnParam in partialGuides) { foreach (int guide in guidesOnParam) { maxGuide = Math.Max(maxGuide, guide); } } //There were no guides, exit with no instructions if (maxGuide == int.MinValue) { return(new List <ReplicationInstruction>()); } //Iterate over all of the guides for (int guideCounter = 1; guideCounter <= maxGuide; guideCounter++) { index.Add(guideCounter, new List <int>()); indexLace.Add(guideCounter, ZipAlgorithm.Shortest); for (int i = 0; i < partialGuides.Count; i++) { if (partialGuides[i].Contains(guideCounter)) { index[guideCounter].Add(i); int indexOfGuide = partialGuides[i].IndexOf(guideCounter); if (partialGuidesLace[i][indexOfGuide] == ZipAlgorithm.Longest) { //If we've previous seen a shortest node with this guide if (i > 0 && indexLace[guideCounter] == ZipAlgorithm.Shortest) { throw new ReplicationCaseNotCurrentlySupported("Cannot support Longest and shortest zipped collections"); } //Overwrite the default behaviour indexLace[guideCounter] = ZipAlgorithm.Longest; } else { //it's shortest, if we had something previous saying it should be longest //then we've created a violation foo(a<1>, b1<1L>) is not allowed if (indexLace[guideCounter] == ZipAlgorithm.Longest) { throw new ReplicationCaseNotCurrentlySupported("Cannot support Longest and shortest zipped collections"); } else { //Shortest lacing is actually the default, this call should be redundant indexLace[guideCounter] = ZipAlgorithm.Shortest; } } } } // Validity.Assert(index[guideCounter].Count > 0, "Sorry, non-contiguous replication guides are not yet supported, please try again without leaving any gaps, err code {3E080694}"); } //Now walk over the guides in order creating the replication int[] uniqueGuides = new int[index.Keys.Count]; index.Keys.CopyTo(uniqueGuides, 0); Array.Sort(uniqueGuides); List <ReplicationInstruction> ret = new List <ReplicationInstruction>(); foreach (int i in uniqueGuides) { //Create a new replication instruction ReplicationInstruction ri = new ReplicationInstruction(); if (index[i].Count == 0) { continue; } else if (index[i].Count == 1) { ri.CartesianIndex = index[i][0]; ri.Zipped = false; } else { ri.Zipped = true; ri.ZipIndecies = index[i]; ri.ZipAlgorithm = indexLace[i]; } ret.Add(ri); } return(ret); }
public static List <ReplicationInstruction> ReductionToInstructions(List <int> reductionList, List <ReplicationInstruction> providedControl) { List <ReplicationInstruction> ret = new List <ReplicationInstruction>(); ret.AddRange(providedControl); //if (providedControl.Count > 0) // throw new NotImplementedException(); //Basic sanity check on the reductions foreach (int reduction in reductionList) { Validity.Assert(reduction >= 0, "Negative reductions aren't supported {991CBD60-8B2B-438B-BDEB-734D18B4FE68}"); } int maxReductionCount = int.MinValue; foreach (int reduction in reductionList) { maxReductionCount = Math.Max(maxReductionCount, reduction); } //@PERF This is going to do a O(n^2) cost scan, when we could just build a reverse index once.... int lastSeenReduction = 0; //This is the last instruction that we have seen and don't need to inject further //reductions from //Walk over all the reductions that we're going to do for (int i = 1; i <= maxReductionCount; i++) { if (!reductionList.Contains(i)) { continue; //We didn't have a reduction of this phase, we'll insert the padding reductions in the next line } //Otherwise look at how many times the reduction was contained. If it was more than once zip, otherwise cartesian List <int> locations = new List <int>(); for (int j = 0; j < reductionList.Count; j++) { if (reductionList[j] == i) { locations.Add(j); } } // reductionList.f .FindAll((int x) => x == i); Validity.Assert(locations.Count > 0, "We should have trapped this case and short-cut the loop, {DF3D67B8-F1B5-4C61-BF3B-930D4C860FA9}"); if (locations.Count == 1) { //There was one location, this is a cartesian expansion ReplicationInstruction ri = new ReplicationInstruction() { CartesianIndex = locations[0], ZipIndecies = null, Zipped = false }; ret.Add(ri); if (i - lastSeenReduction > 1) { //Add padding instructions //@TODO(Luke): Suspect cartesian padding is incorrect for (int padding = 0; padding < ((i - lastSeenReduction) - 1); padding++) { ReplicationInstruction riPad = new ReplicationInstruction() { CartesianIndex = locations[0], ZipIndecies = null, Zipped = false }; ret.Add(riPad); } } } else { ReplicationInstruction ri = new ReplicationInstruction() { CartesianIndex = -1, ZipIndecies = locations, Zipped = true }; ret.Add(ri); if (i - lastSeenReduction > 1) { //Add padding instructions //@TODO(Luke): Suspect cartesian padding is incorrect for (int padding = 0; padding < ((i - lastSeenReduction) - 1); padding++) { ReplicationInstruction riPad = new ReplicationInstruction() { CartesianIndex = -1, ZipIndecies = locations, Zipped = true }; ret.Add(riPad); } } } lastSeenReduction = i; } return(ret); }
/// <summary> /// Convert reduction to instruction. Using zip-first strategy. /// /// For example, /// 0 2 4 > Zip on 1,2 /// 0 1 3 > Zip on 1,2 /// 0 0 2 > Cartesian on 2 /// 0 0 1 > Cartesian on 2 /// </summary> /// <param name="reductions"></param> /// <param name="providedControl"></param> /// <returns></returns> public static List<ReplicationInstruction> ReductionToInstructions(List<int> reductions, List<ReplicationInstruction> providedControl) { List<ReplicationInstruction> ret = new List<ReplicationInstruction>(providedControl); while (true) { int zippableItemCount = reductions.Count(x => x > 0); if (zippableItemCount <= 1) break; List<int> locations = new List<int>(); for (int i = 0; i < reductions.Count; i++) { if (reductions[i] >= 1) { locations.Add(i); reductions[i] -= 1; } } ReplicationInstruction ri = new ReplicationInstruction() { CartesianIndex = -1, ZipIndecies = locations, Zipped = true }; ret.Add(ri); } for (int i = 0; i < reductions.Count; i++) { int reduction = reductions[i]; while (reduction > 0) { ReplicationInstruction ri = new ReplicationInstruction() { CartesianIndex = i, ZipIndecies = null, Zipped = false }; ret.Add(ri); reduction--; } } return ret; }
/// <summary> /// Calculate partial replication instruciton based on replication guide level. /// For example, for foo(xs<1><2><3>, ys<1><1><2>, zs<1><1><3>), the guides /// are: /// /// level | 0 | 1 | 2 | /// ------+-----+-----+-----+ /// xs | 1 | 2 | 3 | /// ------+-----+-----+-----+ /// ys | 1 | 1 | 2 | /// ------+-----+-----+-----+ /// zs | 1 | 1 | 3 | /// /// This function goes through each level and calculate replication instructions. /// /// replication instructions on level 0: /// Zip replication on (0, 1, 2) (i.e., zip on xs, ys, zs) /// /// replication instructions on level 1: /// Zip replication on (1, 2) (i.e., zip on ys, zs) /// Cartesian replication on 0 (i.e., on xs) /// /// replication instructions on level 2: /// Cartesian replication on 1 (i.e., on ys) /// Zip replication on (0, 2) (i.e., zip on xs, zs) /// </summary> /// <param name="partialRepGuides"></param> /// <returns></returns> public static List<ReplicationInstruction> BuildPartialReplicationInstructions(List<List<ReplicationGuide>> partialRepGuides) { if (!partialRepGuides.Any()) { return new List<ReplicationInstruction>(); } int maxGuideLevel= partialRepGuides.Max(gs => gs.Count); var instructions = new List<ReplicationInstruction>(); for (int level = 0; level < maxGuideLevel; ++level) { var positions = new Dictionary<int, List<int>>(); var algorithms = new Dictionary<int, ZipAlgorithm>(); var guides = new HashSet<int>(); for (int i = 0; i < partialRepGuides.Count; ++i) { var replicationGuides = partialRepGuides[i]; if (replicationGuides == null || replicationGuides.Count <= level) continue; // If it is negative or 0, treat it as a stub var guide = replicationGuides[level].GuideNumber; if (guide <= 0) continue; var algorithm = replicationGuides[level].IsLongest ? ZipAlgorithm.Longest : ZipAlgorithm.Shortest; guides.Add(guide); List<int> positionList = null; if (!positions.TryGetValue(guide, out positionList)) { positionList = new List<int>(); positions[guide] = positionList; } positionList.Add(i); ZipAlgorithm zipAlgorithm; if (algorithms.TryGetValue(guide, out zipAlgorithm)) { if (algorithm == ZipAlgorithm.Longest) algorithms[guide] = ZipAlgorithm.Longest; } else { algorithms[guide] = algorithm; } } var sortedGuides = guides.ToList(); sortedGuides.Sort(); foreach (var guide in sortedGuides) { ReplicationInstruction repInstruction = new ReplicationInstruction(); var positionList = positions[guide]; if (positionList.Count == 1) { repInstruction.Zipped = false; repInstruction.CartesianIndex = positionList[0]; } else { repInstruction.Zipped = true; repInstruction.ZipIndecies = positionList; repInstruction.ZipAlgorithm = algorithms[guide]; } instructions.Add(repInstruction); } } return instructions; }
private static List <ReplicationInstruction> BuildPartialReplicationInstructions(List <List <int> > partialGuides) { //DS code: foo(a<1><2><3>, b<2>, c) //partialGuides {1,2,3}, {2}, {} //Instructions //Check for out of order unboxing //@TODO: remove this limitation foreach (List <int> guidesOnParam in partialGuides) { List <int> sorted = new List <int>(); sorted.AddRange(guidesOnParam); sorted.Sort(); for (int i = 0; i < sorted.Count; i++) { if (guidesOnParam[i] != sorted[i]) { throw new ReplicationCaseNotCurrentlySupported("Sorry, multiple guides on a single argument that are not in increasing order are not yet supported, please use a for loop instead, err code: {3C5360D1}"); } } } //Guide -> args Dictionary <int, List <int> > index = new Dictionary <int, List <int> >(); int maxGuide = int.MinValue; foreach (List <int> guidesOnParam in partialGuides) { foreach (int guide in guidesOnParam) { maxGuide = Math.Max(maxGuide, guide); } } //There were no guides, exit with no instructions if (maxGuide == int.MinValue) { return(new List <ReplicationInstruction>()); } for (int guideCounter = 1; guideCounter <= maxGuide; guideCounter++) { index.Add(guideCounter, new List <int>()); for (int i = 0; i < partialGuides.Count; i++) { if (partialGuides[i].Contains(guideCounter)) { index[guideCounter].Add(i); } } // Validity.Assert(index[guideCounter].Count > 0, "Sorry, non-contiguous replication guides are not yet supported, please try again without leaving any gaps, err code {3E080694}"); } //Now walk over the guides in order creating the replication int[] uniqueGuides = new int[index.Keys.Count]; index.Keys.CopyTo(uniqueGuides, 0); Array.Sort(uniqueGuides); List <ReplicationInstruction> ret = new List <ReplicationInstruction>(); foreach (int i in uniqueGuides) { //Create a new replication instruction ReplicationInstruction ri = new ReplicationInstruction(); if (index[i].Count == 0) { continue; } else if (index[i].Count == 1) { ri.CartesianIndex = index[i][0]; ri.Zipped = false; } else { ri.Zipped = true; ri.ZipIndecies = index[i]; } ret.Add(ri); } return(ret); }
private static List<ReplicationInstruction> BuildPartialReplicationInstructions(List<List<int>> partialGuides) { //DS code: foo(a<1><2><3>, b<2>, c) //partialGuides {1,2,3}, {2}, {} //Instructions //Check for out of order unboxing //@TODO: remove this limitation foreach (List<int> guidesOnParam in partialGuides) { List<int> sorted = new List<int>(); sorted.AddRange(guidesOnParam); sorted.Sort(); for (int i = 0; i < sorted.Count; i++) { if (guidesOnParam[i] != sorted[i]) { throw new ReplicationCaseNotCurrentlySupported("Sorry, multiple guides on a single argument that are not in increasing order are not yet supported, please use a for loop instead, err code: {3C5360D1}"); } } } //Guide -> args Dictionary<int, List<int>> index = new Dictionary<int, List<int>>(); int maxGuide = int.MinValue; foreach (List<int> guidesOnParam in partialGuides) { foreach (int guide in guidesOnParam) maxGuide = Math.Max(maxGuide, guide); } //There were no guides, exit with no instructions if (maxGuide == int.MinValue) return new List<ReplicationInstruction>(); for (int guideCounter = 1; guideCounter <= maxGuide; guideCounter++ ) { index.Add(guideCounter, new List<int>()); for (int i = 0; i < partialGuides.Count; i++) if (partialGuides[i].Contains(guideCounter)) { index[guideCounter].Add(i); } // Validity.Assert(index[guideCounter].Count > 0, "Sorry, non-contiguous replication guides are not yet supported, please try again without leaving any gaps, err code {3E080694}"); } //Now walk over the guides in order creating the replication int[] uniqueGuides = new int[index.Keys.Count]; index.Keys.CopyTo(uniqueGuides, 0); Array.Sort(uniqueGuides); List<ReplicationInstruction> ret = new List<ReplicationInstruction>(); foreach (int i in uniqueGuides) { //Create a new replication instruction ReplicationInstruction ri = new ReplicationInstruction(); if (index[i].Count == 0) { continue; } else if (index[i].Count == 1) { ri.CartesianIndex = index[i][0]; ri.Zipped = false; } else { ri.Zipped = true; ri.ZipIndecies = index[i]; } ret.Add(ri); } return ret; }