Beispiel #1
0
        public void DisjointUnionNegativeWatermarkRepro()
        {
            const int leftKey  = 1;
            const int rightKey = 2;
            var       left     = new Subject <PartitionedStreamEvent <int, int> >();
            var       right    = new Subject <PartitionedStreamEvent <int, int> >();

            var qc         = new QueryContainer();
            var leftInput  = qc.RegisterInput(left);
            var rightInput = qc.RegisterInput(right);

            var actualOutput = new List <PartitionedStreamEvent <int, int> >();
            var inputs       = new IStreamable <PartitionKey <int>, int>[] { leftInput, rightInput };
            var union        = new MultiUnionStreamable <PartitionKey <int>, int>(inputs, guaranteedDisjoint: true);
            var egress       = qc.RegisterOutput(union).ForEachAsync(o => actualOutput.Add(o));
            var process      = qc.Restore();

            left.OnNext(PartitionedStreamEvent.CreatePoint(leftKey, 100, 1));
            right.OnNext(PartitionedStreamEvent.CreatePoint(rightKey, 100, 1));

            process.Flush();

            left.OnCompleted();
            right.OnCompleted();

            var expected = new PartitionedStreamEvent <int, int>[]
            {
                PartitionedStreamEvent.CreatePoint(leftKey, 100, 1),
                PartitionedStreamEvent.CreatePoint(rightKey, 100, 1),
                PartitionedStreamEvent.CreateLowWatermark <int, int>(StreamEvent.InfinitySyncTime),
            };

            Assert.IsTrue(expected.SequenceEqual(actualOutput));
        }
        public void FilterTest()
        {
            // Creates a basic filter for even-timestamped events, punctuations
            var inputSubject = new Subject <StreamEvent <int> >();
            var qc           = new QueryContainer();
            var input        = qc.RegisterInput(inputSubject, this.disorderPolicy, this.flushPolicy, this.punctuationPolicy, this.completedPolicy);
            IStreamable <Empty, int> query = input;

            // Add a no-op operator that isn't simply a batch-in-batch-out operator
            query = query.ClipEventDuration(IntervalLength);

            query = query.Where(this.FilterExpression);
            query = query.ClipEventDuration(IntervalLength);
            var filtered = qc.RegisterOutput(query).ForEachAsync(o => OnEgress(o));
            var process  = qc.Restore();

            for (int i = 0; i < IngressEventCount; i++)
            {
                OnIngress(inputSubject, StreamEvent.CreateInterval(i, i + IntervalLength, i));
                if (i > 0 && i % PunctuationGenerationPeriod == 0)
                {
                    OnIngress(inputSubject, StreamEvent.CreatePunctuation <int>(i));
                }

                // Make sure we don't have any pending events we expected to be egressed at this point
                Assert.IsTrue(this.expectedOutput.Count == 0);
            }

            OnCompleted(inputSubject);
        }
Beispiel #3
0
        public void SurrogateTest()
        {
            var qc = new QueryContainer(new MySurrogate());

            var output1 = new List <StreamEvent <IMyInterface> >();
            var input   = new Subject <StreamEvent <IMyInterface> >();

            var ingress = qc.RegisterInput(input);
            var egress  = qc.RegisterOutput(ingress).ForEachAsync(o => output1.Add(o));
            var process = qc.Restore();

            input.OnNext(StreamEvent.CreatePoint(1, (IMyInterface) new MyType(1)));

            var stream = new MemoryStream();

            process.Checkpoint(stream);
            stream.Position = 0;

            input.OnCompleted();

            var input2  = new Subject <StreamEvent <IMyInterface> >();
            var output2 = new List <StreamEvent <IMyInterface> >();

            var qc2      = new QueryContainer(new MySurrogate());
            var ingress2 = qc2.RegisterInput(input2);
            var egress2  = qc2.RegisterOutput(ingress2).ForEachAsync(o => output2.Add(o));
            var process2 = qc2.Restore(stream);

            input2.OnCompleted();

            Assert.AreEqual(2, output2.Count);
            Assert.AreEqual(1, output2[0].Payload.GetValue());
            Assert.AreEqual(StreamEvent.InfinitySyncTime, output2[1].SyncTime);
        }
        public void PartitionedStitch()
        {
            var subject = new Subject <PartitionedStreamEvent <string, string> >();

            var qc    = new QueryContainer();
            var input = qc.RegisterInput(subject);

            var output  = new List <PartitionedStreamEvent <string, string> >();
            var egress  = qc.RegisterOutput(input.Stitch()).ForEachAsync(o => output.Add(o));
            var process = qc.Restore();

            var payload = new[] { "c1payload", "c2payload" };

            // c1 - [1,7),[7,10),[11,12) => [1,10),[11,12)
            subject.OnNext(PartitionedStreamEvent.CreateStart("c1", 1, payload: payload[0]));
            subject.OnNext(PartitionedStreamEvent.CreateEnd("c1", 7, 1, payload: payload[0]));
            subject.OnNext(PartitionedStreamEvent.CreateStart("c1", 7, payload: payload[0]));
            subject.OnNext(PartitionedStreamEvent.CreateEnd("c1", 10, 7, payload: payload[0]));
            subject.OnNext(PartitionedStreamEvent.CreateStart("c1", 11, payload: payload[0]));
            subject.OnNext(PartitionedStreamEvent.CreateEnd("c1", 12, 11, payload: payload[0]));

            // c2 - [2,3),[5,10),[10,12) => [2,3),[5,12)
            subject.OnNext(PartitionedStreamEvent.CreateStart("c2", 2, payload: payload[1]));
            subject.OnNext(PartitionedStreamEvent.CreateEnd("c2", 3, 2, payload: payload[1]));
            subject.OnNext(PartitionedStreamEvent.CreateStart("c2", 5, payload: payload[1]));
            subject.OnNext(PartitionedStreamEvent.CreateEnd("c2", 10, 5, payload: payload[1]));
            subject.OnNext(PartitionedStreamEvent.CreateStart("c2", 10, payload: payload[1]));
            subject.OnNext(PartitionedStreamEvent.CreateEnd("c2", 12, 10, payload: payload[1]));

            subject.OnCompleted();

            process.Flush();

            var expected = new[]
            {
                new List <PartitionedStreamEvent <string, string> >
                {
                    PartitionedStreamEvent.CreateStart("c1", 1, payload: payload[0]),
                    PartitionedStreamEvent.CreateEnd("c1", 10, 1, payload: payload[0]),
                    PartitionedStreamEvent.CreateStart("c1", 11, payload: payload[0]),
                    PartitionedStreamEvent.CreateEnd("c1", 12, 11, payload: payload[0]),
                },
                new List <PartitionedStreamEvent <string, string> >
                {
                    PartitionedStreamEvent.CreateStart("c2", 2, payload: payload[1]),
                    PartitionedStreamEvent.CreateEnd("c2", 3, 2, payload: payload[1]),
                    PartitionedStreamEvent.CreateStart("c2", 5, payload: payload[1]),
                    PartitionedStreamEvent.CreateEnd("c2", 12, 5, payload: payload[1]),
                },
            };

            var outputData = new[]
            {
                output.Where(o => o.IsData && o.PartitionKey == "c1").ToList(),
                output.Where(o => o.IsData && o.PartitionKey == "c2").ToList(),
            };

            Assert.IsTrue(expected[0].SequenceEqual(outputData[0]));
            Assert.IsTrue(expected[1].SequenceEqual(outputData[1]));
        }
Beispiel #5
0
        public void PointAtEndTest2()
        {
            // nothing interesting happens here
            var inputList = new[] {
                StreamEvent.CreateInterval(1, 5, "A"),
                StreamEvent.CreateInterval(2, 10, "A"),
                StreamEvent.CreateInterval(3, 8, "A"),
                StreamEvent.CreateInterval(4, 6, "A"),
                StreamEvent.CreateInterval(8, 9, "A"),
            };

            var compareTo = new[] {
                StreamEvent.CreatePoint(5, "A"),
                StreamEvent.CreatePoint(6, "A"),
                StreamEvent.CreatePoint(8, "A"),
                StreamEvent.CreatePoint(9, "A"),
                StreamEvent.CreatePoint(10, "A"),
                END
            };

            var inputObservable = inputList.ToList().ToObservable();

            var container = new QueryContainer();
            var input     = container.RegisterInput(inputObservable);

            var outputStream = input.PointAtEnd();

            var output = container.RegisterOutput(outputStream);
            var result = new List <StreamEvent <string> >();

            output.Subscribe(t => result.Add(t));
            container.Restore(null);

            Assert.IsTrue(result.SequenceEqual(compareTo));
        }
Beispiel #6
0
        public void DisjointUnionPunctuations()
        {
            var left  = new Subject <StreamEvent <int> >();
            var right = new Subject <StreamEvent <int> >();

            var qc         = new QueryContainer();
            var leftInput  = qc.RegisterInput(left);
            var rightInput = qc.RegisterInput(right);

            var actualOutput = new List <StreamEvent <int> >();
            var union        = new MultiUnionStreamable <Empty, int>(new IStreamable <Empty, int>[] { leftInput, rightInput }, guaranteedDisjoint: true);
            var egress       = qc.RegisterOutput(union).ForEachAsync(o => actualOutput.Add(o));
            var process      = qc.Restore();

            left.OnNext(StreamEvent.CreatePoint(100, 1));
            left.OnNext(StreamEvent.CreatePunctuation <int>(101));

            right.OnNext(StreamEvent.CreatePoint(100, 1));
            right.OnNext(StreamEvent.CreatePunctuation <int>(110));

            process.Flush();

            left.OnNext(StreamEvent.CreatePoint(101, 1));
            right.OnNext(StreamEvent.CreatePoint(110, 1));

            process.Flush();

            left.OnCompleted();
            right.OnCompleted();

            var expected = new StreamEvent <int>[]
            {
                StreamEvent.CreatePoint(100, 1),
                StreamEvent.CreatePoint(100, 1),
                StreamEvent.CreatePunctuation <int>(101),
                StreamEvent.CreatePoint(101, 1),
                StreamEvent.CreatePoint(110, 1),
                StreamEvent.CreatePunctuation <int>(110),
                StreamEvent.CreatePunctuation <int>(StreamEvent.InfinitySyncTime),
            };

            Assert.IsTrue(expected.SequenceEqual(actualOutput));
        }
Beispiel #7
0
        private static void JoinPointsTest(bool fixedInterval = false)
        {
            var left  = new Subject <StreamEvent <string> >();
            var right = new Subject <StreamEvent <string> >();


            var qc = new QueryContainer();
            IStreamable <Empty, string> leftInput  = qc.RegisterInput(left);
            IStreamable <Empty, string> rightInput = qc.RegisterInput(right);

            if (fixedInterval)
            {
                leftInput  = leftInput.AlterEventDuration(1);
                rightInput = rightInput.AlterEventDuration(1);
            }

            var query = leftInput.Join(
                rightInput,
                l => (l != null ? l[0].ToString() : null),
                r => (r != null ? r[0].ToString() : null),
                (l, r) => $"{l},{r}");

            var output = new List <StreamEvent <string> >();

            qc.RegisterOutput(query).ForEachAsync(o => output.Add(o));
            var process = qc.Restore();

            // Should match and egress immediately
            left.OnNext(StreamEvent.CreatePoint(100, "A1"));
            right.OnNext(StreamEvent.CreatePoint(100, "A2"));
            process.Flush();

            var expected = new StreamEvent <string>[]
            {
                StreamEvent.CreatePoint(100, "A1,A2"),
            };

            Assert.IsTrue(expected.SequenceEqual(output));
            output.Clear();

            left.OnCompleted();
            right.OnCompleted();
        }
Beispiel #8
0
        private QueryContainer CreateQuery()
        {
            var query = new QueryContainer();

            Config.ForceRowBasedExecution = true;

            // incoming events are received via a conduit
            _tweetConduit = new Subject <StreamEvent <Tweet> >();
            var streamInput = query.RegisterInput(_tweetConduit, OnCompletedPolicy.None(), DisorderPolicy.Drop(TimeSpan.FromSeconds(3).Ticks),
                                                  PeriodicPunctuationPolicy.Time((ulong)TimeSpan.FromMilliseconds(1).Ticks));

            // outgoing events are pushed to the dashboard
            var myOutput = query.RegisterOutput(TwitterAnalytics(streamInput), ReshapingPolicy.None());

            myOutput.Subscribe(tweetEvent => Publish(tweetEvent));
            return(query);
        }
Beispiel #9
0
        public void ExtendTest1()
        {
            // nothing interesting happens here
            var inputList = new[]
            {
                StreamEvent.CreateStart(1, "A"),
                StreamEvent.CreateEnd(2, 1, "A"),
                StreamEvent.CreateStart(2, "A"),
                StreamEvent.CreateEnd(3, 2, "A"),
                StreamEvent.CreateStart(3, "A"),
                StreamEvent.CreateEnd(4, 3, "A"),
                StreamEvent.CreateStart(4, "A"),
                StreamEvent.CreateEnd(5, 4, "A")
            };

            var compareTo = new[]
            {
                StreamEvent.CreateStart(1, "A"),
                StreamEvent.CreateStart(2, "A"),
                StreamEvent.CreateStart(3, "A"),
                StreamEvent.CreateStart(4, "A"),
                StreamEvent.CreateEnd(5, 1, "A"),
                StreamEvent.CreateEnd(6, 2, "A"),
                StreamEvent.CreateEnd(7, 3, "A"),
                StreamEvent.CreateEnd(8, 4, "A"),
                END
            };

            var inputObservable = inputList.ToList().ToObservable();
            var container       = new QueryContainer();
            var input           = container.RegisterInput(inputObservable);

            input.SetProperty().IsIntervalFree(true);

            var outputStream = input.ExtendLifetime(3);

            var output = container.RegisterOutput(outputStream);
            var result = new List <StreamEvent <string> >();

            output.Subscribe(t => result.Add(t));

            container.Restore(null);

            Assert.IsTrue(result.SequenceEqual(compareTo));
        }
        private void SetupQuery(
            DisorderPolicy disorderPolicy,
            PartitionedFlushPolicy flushPolicy            = PartitionedFlushPolicy.FlushOnLowWatermark,
            PeriodicPunctuationPolicy punctuationPolicy   = null, // Default: PeriodicPunctuationPolicy.None()
            PeriodicLowWatermarkPolicy lowWatermarkPolicy = null, // Default: PeriodicLowWatermarkPolicy.None()
            OnCompletedPolicy completedPolicy             = OnCompletedPolicy.EndOfStream)
        {
            var qc = new QueryContainer();

            this.input = new Subject <PartitionedStreamEvent <int, int> >();
            var ingress = qc.RegisterInput(this.input, disorderPolicy, flushPolicy, punctuationPolicy,
                                           lowWatermarkPolicy, completedPolicy);

            this.output              = new List <PartitionedStreamEvent <int, int> >();
            this.egress              = qc.RegisterOutput(ingress).ForEachAsync(o => this.output.Add(o));
            this.process             = qc.Restore();
            this.validateByPartition = disorderPolicy.reorderLatency > 0;
        }
Beispiel #11
0
        private void SetupQuery <TInput>(
            Func <IPartitionedIngressStreamable <int, TInput>, IStreamable <PartitionKey <int>, double> > createQuery,
            out Subject <PartitionedStreamEvent <int, TInput> > input)
        {
            const uint generationPeriod         = 10;
            const uint lowWatermarkTimestampLag = 20;

            var qc = new QueryContainer();

            input = new Subject <PartitionedStreamEvent <int, TInput> >();
            var ingress = qc.RegisterInput(input, null, PartitionedFlushPolicy.None, null, PeriodicLowWatermarkPolicy.Time(generationPeriod, lowWatermarkTimestampLag));

            var query = createQuery(ingress);

            this.output  = new List <PartitionedStreamEvent <int, double> >();
            this.egress  = qc.RegisterOutput(query).ForEachAsync(o => this.output.Add(o));
            this.process = qc.Restore();
        }
        private void ProcessInput(
            out List <OutOfOrderPartitionedStreamEvent <int, int> > diagnosticEvents,
            out List <PartitionedStreamEvent <int, int> > dataEvents)
        {
            var qc      = new QueryContainer();
            var ingress = qc.RegisterInput(this.input.ToObservable(), this.disorderPolicy,
                                           PartitionedFlushPolicy.None, PeriodicPunctuationPolicy.None(), this.lowWatermarkPolicy);

            var outOfOrderEvents = new List <OutOfOrderPartitionedStreamEvent <int, int> >();

            ingress.GetDroppedAdjustedEventsDiagnostic().Subscribe(o => outOfOrderEvents.Add(o));

            var output  = new List <PartitionedStreamEvent <int, int> >();
            var egress  = qc.RegisterOutput(ingress).ForEachAsync(o => output.Add(o));
            var process = qc.Restore();

            process.Flush();
            egress.Wait();

            diagnosticEvents = outOfOrderEvents;
            dataEvents       = output;
        }
Beispiel #13
0
        private static void PassThrough()
        {
            // var inputStream = GetTollReadings();
            // Display(inputStream);
            // var subscription = TollReadingEvents.ToAtemporalStreamable();
            // Display(subscription);

            {
                var queryContainer = new QueryContainer();
                var inputStream    = queryContainer.RegisterInput(
                    TollReadingEvents,
                    DisorderPolicy.Drop(),
                    FlushPolicy.FlushOnPunctuation,
                    PeriodicPunctuationPolicy.Time(1));
                var query = inputStream.HoppingWindowLifetime(TimeSpan.FromSeconds(10).Ticks, TimeSpan.FromSeconds(1).Ticks)
                            .Count()
                            .AlterEventDuration(1);
                var async = queryContainer.RegisterOutput(query);
                Display("1) ", 1, async);
                queryProcess1 = queryContainer.Restore();
            }
        }
        public void SelectManyWithFlush()
        {
            var data = new PartitionedStreamEvent <int, double>[]
            {
                PartitionedStreamEvent.CreatePoint(0, 0, 0.0),
                PartitionedStreamEvent.CreatePoint(0, 1, 1.0),
                PartitionedStreamEvent.CreatePoint(0, 2, 2.0),
                PartitionedStreamEvent.CreatePoint(1, 1, 1.0),
                PartitionedStreamEvent.CreatePoint(1, 2, 2.0),
                PartitionedStreamEvent.CreatePoint(1, 3, 3.0),
                PartitionedStreamEvent.CreatePoint(2, 2, 2.0),
                PartitionedStreamEvent.CreatePoint(2, 3, 3.0),
                PartitionedStreamEvent.CreatePoint(2, 4, 4.0),
            };

            var j   = new Subject <PartitionedStreamEvent <int, double> >();
            var res = new List <Notification <PartitionedStreamEvent <int, double> > >();

            var qc     = new QueryContainer();
            var input  = qc.RegisterInput(j);
            var output = qc.RegisterOutput(input.SelectMany(e => new[] { e, 100.0 * e }));

            using (j)
                using (output.Subscribe(res.NotificationListObserver()))
                {
                    Process p = qc.Restore(null);
                    foreach (var x in data)
                    {
                        j.OnNext(x);
                    }

                    p.Flush();
                    Assert.IsTrue(res.Count > data.Length, "Flush should push all events out.");

                    j.OnCompleted();
                }
        }
Beispiel #15
0
        private static IObservable <StreamEvent <Toll> > GetTollObservable(QueryContainer queryContainer)
        {
            var inputStream = queryContainer.RegisterInput(TollReadingEvents,
                                                           DisorderPolicy.Drop(),
                                                           FlushPolicy.FlushOnPunctuation,
                                                           PeriodicPunctuationPolicy.Time(1));
            var partitionedSlidingWindow1 =
                inputStream.AlterEventDuration((start, end) => end - start + TimeSpan.FromSeconds(2).Ticks)
                .HoppingWindowLifetime(TimeSpan.FromSeconds(2).Ticks, TimeSpan.FromSeconds(2).Ticks)
                .GroupApply(
                    r => r.TollId,
                    r =>
                    r.Multicast(
                        perTollBoth =>
                        perTollBoth.Sum(e => e.Toll)
                        .Join(perTollBoth.Count(), (sum, count) => new { Sum = sum, Count = count })),
                    (key, result) =>
                    new Toll {
                TollId = key.Key, TollAmount = result.Sum, VehicleCount = result.Count
            });
            var retval = queryContainer.RegisterOutput(partitionedSlidingWindow1);

            return(retval);
        }
Beispiel #16
0
        public static void Test()
        {
            // This version of checkpointing works only with row-oriented mode. This restriction will eventually be relaxed.
            Config.ForceRowBasedExecution = true;

            // Subjects to feed pre- and post-checkpoint data to the query
            var preCheckpointSubject  = new Subject <StreamEvent <StructTuple <int, int> > >();
            var postCheckpointSubject = new Subject <StreamEvent <StructTuple <int, int> > >();

            // Outputs of queries with and without checkpointing
            var outputListWithCheckpoint    = new List <StructTuple <int, ulong> >();
            var outputListWithoutCheckpoint = new List <StructTuple <int, ulong> >();

            // Containers are an abstraction to hold queries and are the unit of checkpointing
            var container1 = new QueryContainer();
            var container2 = new QueryContainer();
            var container3 = new QueryContainer();

            // Query state is written to and read from a .NET stream
            Stream state = new MemoryStream();

            // Input data: first half of the dataset before a checkpoint is taken
            var preCheckpointData = Enumerable.Range(0, 10000).ToList()
                                    .ToObservable()
                                    .Select(e => StreamEvent.CreateStart(e, new StructTuple <int, int> {
                Item1 = e % 10, Item2 = e
            }));

            // Input data: second half of the dataset after a checkpoint is taken
            var postCheckpointData = Enumerable.Range(10000, 10000).ToList()
                                     .ToObservable()
                                     .Select(e => StreamEvent.CreateStart(e, new StructTuple <int, int> {
                Item1 = e % 10, Item2 = e
            }));

            // For comparison, we run the same query directly on the full dataset
            var fullData = Enumerable.Range(0, 20000).ToList()
                           .ToObservable()
                           .Select(e => StreamEvent.CreateStart(e, new StructTuple <int, int> {
                Item1 = e % 10, Item2 = e
            }));

            // Query 1: Run with first half of the dataset, then take a checkpoint
            var input1 = container1.RegisterInput(preCheckpointSubject);
            var query1 = input1.GroupApply(e => e.Item1, str => str.Sum(e => (ulong)e.Item2), (g, c) => new StructTuple <int, ulong> {
                Item1 = g.Key, Item2 = c
            });

            var output1 = container1.RegisterOutput(query1);

            var outputAsync1 = output1.Where(e => e.IsData).Select(e => e.Payload).ForEachAsync(o => outputListWithCheckpoint.Add(o));
            var pipe1        = container1.Restore(null);

            preCheckpointData.ForEachAsync(e => preCheckpointSubject.OnNext(e)).Wait();
            preCheckpointSubject.OnNext(StreamEvent.CreatePunctuation <StructTuple <int, int> >(9999));
            pipe1.Checkpoint(state);

            // Seek to the beginning of the stream that represents checkpointed state
            state.Seek(0, SeekOrigin.Begin);

            // Query 2: Restore the state from the saved checkpoint, and feed the second half of the dataset
            var input2 = container2.RegisterInput(postCheckpointSubject);
            var query2 = input2.GroupApply(e => e.Item1, str => str.Sum(e => (ulong)e.Item2), (g, c) => new StructTuple <int, ulong> {
                Item1 = g.Key, Item2 = c
            });
            var output2 = container2.RegisterOutput(query2);

            var outputAsync2 = output2.Where(e => e.IsData).Select(e => e.Payload).ForEachAsync(o => outputListWithCheckpoint.Add(o));
            var pipe2        = container2.Restore(state);

            postCheckpointData.ForEachAsync(e => postCheckpointSubject.OnNext(e)).Wait();
            postCheckpointSubject.OnCompleted();
            outputAsync2.Wait();

            // Sort the payloads in the query result
            outputListWithCheckpoint.Sort((a, b) => a.Item1.CompareTo(b.Item1) == 0 ? a.Item2.CompareTo(b.Item2) : a.Item1.CompareTo(b.Item1));

            // Query 3: For comparison, run the query directly on the entire dataset without any checkpoint/restore
            var input3 = container3.RegisterInput(fullData /*, OnCompletedPolicy.EndOfStream()*/);
            var query3 = input3.GroupApply(e => e.Item1, str => str.Sum(e => (ulong)e.Item2), (g, c) => new StructTuple <int, ulong> {
                Item1 = g.Key, Item2 = c
            });
            var output3 = container3.RegisterOutput(query3);

            var outputAsync3 = output3.Where(e => e.IsData).Select(e => e.Payload).ForEachAsync(o => outputListWithoutCheckpoint.Add(o));

            container3.Restore(null); // The parameter of "null" to restore causes it to run from scratch
            outputAsync3.Wait();

            // Sort the payloads in the query result
            outputListWithoutCheckpoint.Sort((a, b) => a.Item1.CompareTo(b.Item1) == 0 ? a.Item2.CompareTo(b.Item2) : a.Item1.CompareTo(b.Item1));

            // Perform a comparison of the checkpoint/restore query result and the result of the original query run directly on the entire dataset
            if (outputListWithCheckpoint.SequenceEqual(outputListWithoutCheckpoint))
            {
                Console.WriteLine("SUCCESS: Output of query with checkpoint/restore matched output of uninterrupted query");
            }
            else
            {
                Console.WriteLine("ERROR: Output of query with checkpoint/restore did not match the output of uninterrupted query");
            }
            Console.ReadLine();
        }
Beispiel #17
0
        public void LOJ1Row()
        {
            var container = new QueryContainer(null);

            var left = new StreamEvent <MyData>[]
            {
                StreamEvent.CreatePoint(10, new MyData {
                    field1 = 1, field2 = "A"
                }),
                StreamEvent.CreatePoint(10, new MyData {
                    field1 = 1, field2 = "B"
                }),
                StreamEvent.CreatePoint(10, new MyData {
                    field1 = 2, field2 = "D"
                }),
                StreamEvent.CreatePoint(10, new MyData {
                    field1 = 2, field2 = "E"
                })
            };

            var right = new StreamEvent <MyData2>[]
            {
                StreamEvent.CreatePoint(10, new MyData2 {
                    field3 = 1, field4 = "W"
                }),
                StreamEvent.CreatePoint(10, new MyData2 {
                    field3 = 1, field4 = "X"
                }),
                StreamEvent.CreatePoint(10, new MyData2 {
                    field3 = 2, field4 = "Y"
                })
            };

            var output   = new List <StreamEvent <MyData3> >();
            var expected = new StreamEvent <MyData3>[]
            {
                StreamEvent.CreatePoint(10, new MyData3 {
                    field1 = 2, field2 = "E", field3 = -1, field4 = "null"
                }),
                StreamEvent.CreatePoint(10, new MyData3 {
                    field1 = 1, field2 = "B", field3 = 1, field4 = "W"
                }),
                StreamEvent.CreatePoint(10, new MyData3 {
                    field1 = 1, field2 = "A", field3 = 1, field4 = "W"
                }),
                StreamEvent.CreatePoint(10, new MyData3 {
                    field1 = 1, field2 = "B", field3 = 1, field4 = "X"
                }),
                StreamEvent.CreatePoint(10, new MyData3 {
                    field1 = 1, field2 = "A", field3 = 1, field4 = "X"
                }),
                StreamEvent.CreatePoint(10, new MyData3 {
                    field1 = 2, field2 = "D", field3 = 2, field4 = "Y"
                }),
            };

            var leftStream  = container.RegisterInput(left.ToObservable());
            var rightStream = container.RegisterInput(right.ToObservable());

            int    tmp1 = -1;
            string tmp2 = "null";

            var query =
                leftStream.LeftOuterJoin(rightStream, e => e.field1, e => e.field3,
                                         (l, r) => l.field2 != "E",
                                         (l) => new MyData3 {
                field1 = l.field1, field2 = l.field2, field3 = tmp1, field4 = tmp2
            },
                                         (l, r) => new MyData3 {
                field1 = l.field1, field2 = l.field2, field3 = r.field3, field4 = r.field4
            });

            var result      = container.RegisterOutput(query, ReshapingPolicy.CoalesceEndEdges).Where(e => e.IsData);
            var resultAsync = result.ForEachAsync(o => output.Add(o));

            container.Restore(null); // start the query

            Assert.IsTrue(output.ToArray().SequenceEqual(expected));
        }