// remove tuples that satisfy predicate public void Delete(string heading, Func <Tup, bool> selfunc) { var head = CommonHeading.Create(heading); var map = head.CreateMap(Heading); Value = new RelValue(Heading, Value.Where(t => !selfunc(RelStatic.CreateByMap <Tup>(t, map)))); }
// extend by one new attribute value internal static ISet <T> Extend <T1, T>(IEnumerable <T1> body1, Func <T1, object> func) where T : TupBase, new() where T1 : TupBase, new() { var map = RelValueST <T> .Heading.CreateMap(RelValueST <T1> .Heading); return(new HashSet <T>(body1.Select(t => RelStatic.CreateByMap <T>(t, map, func(t))))); }
internal static ISet <T> Project <T1, T>(IEnumerable <T1> body1) where T : TupBase, new() where T1 : TupBase, new() { var map = RelValueST <T> .Heading.CreateMap(RelValueST <T1> .Heading); Logger.Assert(map.All(x => x >= 0), "project heading has missing attribute"); return(new HashSet <T>(body1.Select(t => RelStatic.CreateByMap <T>(t, map)))); }
// update tuples that satisfy predicate public void Update(string heading, Func <Tup, bool> selfunc, object newvalue) { // map for selection tuple var head1 = CommonHeading.Create(heading); var map1 = head1.CreateMap(Heading); // map for replace tuple var head2 = Heading.Remove(head1.Fields.Last()).Append(CommonField.Empty); var map2 = head2.CreateMap(Heading); Value = new RelValue(Heading, Value.Select(t => selfunc(RelStatic.CreateByMap <Tup>(t, map1)) ? RelStatic.CreateByMap <Tup>(t, map2, newvalue) : t)); }
// natural semijoin/antijoin (fields from left only) internal static HashSet <T> SemiJoin <T, T1, T2>(IEnumerable <T1> body1, IEnumerable <T2> body2, int[] map1, int[] jmap1, int[] jmap2, bool issemi = true) where T : TupBase, new() where T1 : TupBase, new() where T2 : TupBase, new() { var index = RelStatic.BuildSet(body2, jmap2); return(new HashSet <T>(body1 .Where(b => issemi == index.Contains(RelStatic.CreateByMap <T>(b, jmap1))) .Select(b => RelStatic.CreateByMap <T>(b, map1)))); }
protected void Init(RelNode value) { var equal = value.Heading.IsEqual(Heading); var compat = equal || value.Heading.IsCompatible(Heading); if (!compat) { throw Error.Fatal($"headings are not compatible: <{value.Heading}> and <{Heading}>"); } var map = Heading.CreateMap(value.Heading); Value = Rel.Create(value.Select(t => RelStatic.CreateByMap <T>(t, map))); }
// agregation internal static HashSet <T> Aggregate <T1, T, T2>(IEnumerable <T1> body1, Func <T1, T2, T2> func) where T : TupBase, new() where T1 : TupBase, new() where T2 : new() { var jhead = RelValueST <T> .Heading.Intersect(RelValueST <T1> .Heading); var jmap = jhead.CreateMap(RelValueST <T1> .Heading); var map = RelValueST <T> .Heading.CreateMap(jhead); var dict = new Dictionary <TupBase, T2>(); foreach (var t in body1) { var tup = RelStatic.CreateByMap <T>(t, jmap); dict[tup] = (dict.ContainsKey(tup)) ? func(t, dict[tup]) : dict[tup] = func(t, new T2()); //BUG } return(new HashSet <T>(dict.Select(p => RelStatic.CreateByMap <T>(p.Key, map, p.Value)))); }
// build an index of tuples (because that's where Equals lives) static internal Dictionary <TupBase, IList <TupBase> > BuildIndex(IEnumerable <TupBase> values, int[] keymap) { var index = new Dictionary <TupBase, IList <TupBase> >(); foreach (var tuple in values) { var newkey = RelStatic.CreateByMap <TupNoneST>(tuple, keymap); if (index.ContainsKey(newkey)) { index[newkey].Add(tuple); } else { index[newkey] = new List <TupBase> { tuple } }; } return(index); }
// natural join T = T1 join T2 internal static ISet <T> Join <T, T1, T2>(IEnumerable <T1> body1, IEnumerable <T2> body2) where T : TupBase, new() where T1 : TupBase, new() where T2 : TupBase, new() { var map1 = RelValueST <T> .Heading.CreateMap(RelValueST <T1> .Heading); var map2 = RelValueST <T> .Heading.CreateMap(RelValueST <T2> .Heading); var jhead = RelValueST <T1> .Heading.Intersect(RelValueST <T2> .Heading); var jmap1 = jhead.CreateMap(RelValueST <T1> .Heading); var jmap2 = jhead.CreateMap(RelValueST <T2> .Heading); if (map2.All(x => x == -1)) { return(SemiJoin <T, T1, T2>(body1, body2, map1, jmap1, jmap2)); } var index = RelStatic.BuildIndex(body2, jmap2); var output = new HashSet <T>(); foreach (var t1 in body1) { var key = RelStatic.CreateByMap <T>(t1, jmap1); if (index.ContainsKey(key)) { foreach (var t2 in index[key]) { var newtuple = RelStatic.CreateByMap <T>(t1, map1, t2, map2); output.Add(newtuple); } } } return(output); }
static internal HashSet <TupBase> BuildSet(IEnumerable <TupBase> values, int[] map) { return(new HashSet <TupBase>(values.Select(v => RelStatic.CreateByMap <Tup>(v, map)))); }