static IEnumerable <TupBase> While(CommonHeading heading, IEnumerable <TupBase> body, Func <RelNode, RelNode> func) { var stack = new Stack <TupBase>(body); var hash = new HashSet <TupBase>(); while (stack.Count > 0) { var top = stack.Pop(); if (!hash.Contains(top)) { hash.Add(top); var result = func(new WrapperNode(heading, Enumerable.Repeat(top, 1))); var eq = result.Heading.IsEqual(heading); var map = heading.CreateMap(result.Heading); if (result.Heading.Degree != heading.Degree || map.Any(x => x < 0)) { throw Error.Fatal("While", $"heading mismatch: {result.Heading} {heading}"); } // convert compatible if needed foreach (var t in result) { stack.Push(eq ? t : RelStatic.CreateByMap <Tup>(t, map)); } } } return(hash); }
public override IEnumerator <Tup> GetEnumerator() { var hash = new HashSet <TupBase>(); switch (_setop) { case SetOp.Union: foreach (var tuple in _left) { hash.Add(tuple); Logger.Assert(tuple.Degree == Heading.Degree); yield return(tuple); } foreach (var tuple in _right) { var newtuple = RelStatic.CreateByMap <Tup>(tuple, _othermap); Logger.Assert(tuple.Degree == Heading.Degree); if (!hash.Contains(newtuple)) { yield return(newtuple); } } break; case SetOp.Minus: foreach (var tuple in _right) { var newtuple = RelStatic.CreateByMap <Tup>(tuple, _othermap); hash.Add(newtuple); } foreach (var tuple in _left) { Logger.Assert(tuple.Degree == Heading.Degree); if (!hash.Contains(tuple)) { yield return(tuple); } } break; case SetOp.Intersect: foreach (var tuple in _left) { hash.Add(tuple); } foreach (var tuple in _right) { var newtuple = RelStatic.CreateByMap <Tup>(tuple, _othermap); Logger.Assert(tuple.Degree == Heading.Degree); if (hash.Contains(newtuple)) { yield return(newtuple); } } break; default: break; } }
// enumerate tuple unwrapping IEnumerator <Tup> GetUnwrapEnumerator() { foreach (var tuple in _source) { var row = (CommonRow)tuple[_nodemap[0]]; var newtuple = RelStatic.CreateByMap <Tup>(tuple.Values, _map1, row.Values, _map2); Logger.Assert(newtuple.Degree == Heading.Degree); yield return(newtuple); } }
IEnumerator <Tup> GetWrapEnumerator() { foreach (var tuple in _source) { var tva = new CommonRow(_tmap.Select(x => tuple[x])); var newtuple = RelStatic.CreateByMap <Tup>(tuple, _map, tva); Logger.Assert(newtuple.Degree == Heading.Degree); yield return(newtuple); } }
public override IEnumerator <Tup> GetEnumerator() { foreach (var tuple in _source) { // pick out the argument values, pass them to the function, get return var argtuple = RelStatic.CreateByMap <Tup>(tuple, _argmap); var result = _func.Call(argtuple.Values); var newtuple = RelStatic.CreateByMap <Tup>(tuple, _outmap, result); Logger.Assert(newtuple.Degree == Heading.Degree); yield return(newtuple); } }
IEnumerator <Tup> GetGroupEnumerator() { var index = RelStatic.BuildIndex(_source, _kmap); foreach (var kvp in index) { var rva = kvp.Value.Select(t => new CommonRow(_tmap.Select(x => t[x]))).ToArray(); var newtuple = RelStatic.CreateByMap <Tup>(kvp.Key, _map, rva); Logger.Assert(newtuple.Degree == Heading.Degree); yield return(newtuple); } }
public override IEnumerator <Tup> GetEnumerator() { foreach (var tuple in _source) { var newtuple = RelStatic.CreateByMap <Tup>(tuple, _restmap); Logger.Assert(tuple.Degree == Heading.Degree); if ((bool)_restfunc.Call(newtuple.Values)) { yield return(tuple); } //if (_restfunc(newtuple)) yield return tuple; } }
// enumerator for semijoin and antijoin (only the logic test is different) IEnumerator <Tup> GetSemi(bool isanti) { var set = RelStatic.BuildSet(_rightarg, _jmapright); foreach (var tuple in _leftarg) { var key = RelStatic.CreateByMap <Tup>(tuple, _jmapleft); if (!isanti == set.Contains(key)) { Logger.Assert(tuple.Degree == Heading.Degree); yield return(tuple); } } }
// possible alternative??? IEnumerable <T> GetSemi <T>(bool isanti, IEnumerable <T> leftarg, IEnumerable <T> rightarg, int[] jmapleft, int[] jmapright) where T : TupBase, new() { var set = RelStatic.BuildSet(rightarg, jmapright); foreach (var tuple in leftarg) { var key = RelStatic.CreateByMap <T>(tuple, jmapleft); if (!isanti == set.Contains(key)) { Logger.Assert(tuple.Degree == Heading.Degree); yield return(tuple); } } }
public override IEnumerator <Tup> GetEnumerator() { var hash = new HashSet <TupBase>(); foreach (var tuple in _source) { var newtuple = RelStatic.CreateByMap <Tup>(tuple, _map); if (hash.Contains(newtuple)) { continue; } hash.Add(newtuple); Logger.Assert(newtuple.Degree == Heading.Degree); yield return(newtuple); } }
public override IEnumerator <Tup> GetEnumerator() { var dict = new Dictionary <TupBase, object>(); foreach (var tuple in _source) { var tupkey = RelStatic.CreateByMap <Tup>(tuple, _jmap1); var value = tuple.Values[_vmap[0]]; dict[tupkey] = (dict.ContainsKey(tupkey)) ? _func.Call(new object[] { value, dict[tupkey] }) : (_initial != null) ? _func.Call(new object[] { value, dict[tupkey], _initial }) : value; } foreach (var kv in dict) { var newtuple = RelStatic.CreateByMap <Tup>(kv.Key, _jmap2, kv.Value); Logger.Assert(newtuple.Degree == Heading.Degree); yield return(newtuple); } }
// enumerator for full join and compose (only the output is different) IEnumerator <Tup> GetFull() { var index = RelStatic.BuildIndex(_rightarg, _jmapright); var hash = new HashSet <TupBase>(); foreach (var tuple in _leftarg) { var key = RelStatic.CreateByMap <Tup>(tuple, _jmapleft); if (index.ContainsKey(key)) { foreach (var tother in index[key]) { var newtuple = RelStatic.CreateByMap <Tup>(tuple, _tmapleft, tother, _tmapright); if (!hash.Contains(newtuple)) { hash.Add(newtuple); Logger.Assert(newtuple.Degree == Heading.Degree); yield return(newtuple); } } } } }