예제 #1
0
        private static IEnumerable <IFusionOperator> Optimize(IFusionOperator[] chain)
        {
            // TODO: these optimizations can be moved to the expression space above the plan

            var cur = default(IFusionOperator);

            foreach (var op in chain)
            {
                if (cur != null)
                {
                    if (cur is WhereFactory where1 && op is WhereFactory where2)
                    {
                        var p1 = where1.Predicate;
                        var p2 = where2.Predicate;
                        var x  = Expression.Parameter(cur.OutputType);
                        var p  = Expression.Lambda(Expression.AndAlso(Expression.Invoke(p1, x), Expression.Invoke(p2, x)), x);
                        cur = new WhereFactory {
                            Predicate = p
                        };
                    }
                    else if (cur is TakeFactory take1 && op is TakeFactory take2)
                    {
                        // TODO: Count should be an expression (which could be constant, allowing for this optimization)
                        var n1 = take1.Count;
                        var n2 = take2.Count;
                        var n  = Math.Min(n1, n2);
                        cur = new TakeFactory {
                            Count = n
                        };
                    }
예제 #2
0
        private static void Take()
        {
            var tf = new TakeFactory
            {
                Count      = 3,
                OutputType = typeof(int)
            };

            var ff = new SinkFactory
            {
                OutputType = typeof(int)
            };

            var chain = new IFusionOperator[]
            {
                tf, // .Take(3)
                ff
            };

            var ivt = Compile(typeof(int), chain);

            var res = new List <int>();
            var err = default(Exception);
            var fin = false;

            var otp = Observer.Create <int>(res.Add, ex => err = ex, () => fin = true);
            var dsp = System.Reactive.Disposables.Disposable.Empty;

            var iv = (IObserver <int>)Activator.CreateInstance(ivt, new object[] { otp, dsp });

            iv.OnNext(0);
            iv.OnNext(1);
            iv.OnNext(2);
            iv.OnNext(3);
            iv.OnNext(4);
            iv.OnCompleted();

            Assert(res.SequenceEqual(new[] { 0, 1, 2 }));
            Assert(err == null);
            Assert(fin);
        }
예제 #3
0
        private static void Old()
        {
            // TODO: implement a few operators in terms of others and see fusion emit the same code
            //       e.g. xs.Last() == xs.Aggreggate((a, x) => x)

            //
            // Aggregate
            // - Count/LongCount
            // Average/Sum/Min/Max
            // Any/All/IsEmpty
            // - First
            // - Last
            // Single
            // Contains
            // ElementAt
            // - IgnoreElements
            // Scan
            // Sample
            // - Take
            // Skip
            // TakeWhile/SkipWhile
            // Finally
            //
            // CombineLatest
            // SequenceEqual
            // TakeUntil
            //
            // SkipUntil
            // StartWith
            //
            // Merge
            // SelectMany
            // Switch
            //

            var wf1 = new WhereFactory
            {
                Predicate = (Expression <Func <int, bool> >)(x => x > 0)
            };

            var wf2 = new WhereIndexedFactory
            {
                Predicate = (Expression <Func <int, int, bool> >)((x, i) => x != 0 && i < int.MaxValue)
            };

            var df = new DistinctUntilChangedFactory
            {
                OutputType = typeof(int)
            };

            var sf1 = new SelectFactory
            {
                Selector = (Expression <Func <int, int> >)(x => x * 2)
            };

            var sf2 = new SelectIndexedFactory
            {
                Selector = (Expression <Func <int, int, int> >)((x, i) => x * 3 + i)
            };

            var tf1 = new TakeFactory
            {
                OutputType = typeof(int),
                Count      = 1000
            };

            var tf2 = new TakeFactory
            {
                OutputType = typeof(int),
                Count      = 2000
            };

            var af = new SumFactory(typeof(int));

            var ff = new SinkFactory
            {
                OutputType = typeof(int)
            };

            var chain = new IFusionOperator[]
            {
                wf1, // .Where(x => x > 0)
                wf2, // .Where((x, i) => x != 0 && i < int.MaxValue)
                df,  // .DistinctUntilChanged()
                sf1, // .Select(x => x * 2)
                sf2, // .Select((x, i) => x * 3 + i)
                tf1, // .Take(1000)
                tf2, // .Take(2000)
                af,  // .Sum()
                ff
            };

            var ivt = Compile(typeof(int), chain);

            Test(ivt);
        }