コード例 #1
0
        public void FlushOnLowWatermarkDualStream()
        {
            SetupQuery(DisorderPolicy.Throw(reorderLatency: 500));

            // These will be buffered due to reorderLatency
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(0, 1, 0));    // key 0: 1-2
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(0, 101, 0));  // key 0: 101-102

            // This will batch the first point (0: 1-2)); but the second point ( key 0: 101-102) remains batched, since 101 > 100.
            // Since we use the default policy, FlushOnLowWatermark, the first point will also be flushed at this point.
            this.input.OnNext(PartitionedStreamEvent.CreateLowWatermark <int, int>(100));

            this.input.OnNext(PartitionedStreamEvent.CreatePoint(0, 1005, 0));
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(0, 1100, 0));

            // OnCompletedPolicy.EndOfStream adds the last two points to the batch then flushes all
            var expected = new PartitionedStreamEvent <int, int>[]
            {
                // Flushed in response to low watermark
                PartitionedStreamEvent.CreatePoint(0, 1, 0),
                PartitionedStreamEvent.CreateLowWatermark <int, int>(100),

                // Flushed in response to OnCompleted
                PartitionedStreamEvent.CreatePoint(0, 101, 0),
                PartitionedStreamEvent.CreatePoint(0, 1005, 0),
                PartitionedStreamEvent.CreatePoint(0, 1100, 0),

                // Generated by the default OnCompletedPolicy EndOfStream
                PartitionedStreamEvent.CreateLowWatermark <int, int>(StreamEvent.InfinitySyncTime),
            };

            FinishQuery(expected);
        }
コード例 #2
0
        protected void ReorderLatencyDisorderingBase(DisorderPolicy disorderPolicy, PeriodicLowWatermarkPolicy lowWatermarkPolicy)
        {
            TestSetup(disorderPolicy, lowWatermarkPolicy);

            // Partition 0 - locally disordered
            AddEvent(0, 100);
            AddEvent(0, 95);
            AddEvent(0, 89);

            // Partition 1 - globally disordered
            AddEvent(1, 80);
            AddEvent(1, 85);
            AddEvent(1, 90);
            AddEvent(1, 95);
            AddEvent(1, 100);

            // Partition 2 - locally and globally disordered
            AddEvent(2, 80);
            AddEvent(2, 85);
            AddEvent(2, 90);
            AddEvent(2, 95);
            AddEvent(2, 100);
            AddEvent(2, 99);
            AddEvent(2, 94);
            AddEvent(2, 89);
            AddEvent(2, 84);
            AddEvent(2, 79);

            RunAndValidate();
        }
コード例 #3
0
        public void ReorderTest2ColumnarSmallBatch()
        {
            var oldSortingTechnique = Config.IngressSortingTechnique;

            Config.IngressSortingTechnique = SortingTechnique.PriorityQueue;

            var outputList = new List <StreamEvent <int> >();

            double disorderFraction = 0.5;
            int    reorderLatency   = 202;
            int    disorderAmount   = 200;
            var    rand             = new Random(2);
            var    disorderedData   =
                Enumerable.Range(disorderAmount, 500000).ToList()
                .Select(e => StreamEvent.CreateStart(rand.NextDouble() < disorderFraction ? e - rand.Next(0, disorderAmount) : e, 0))
                .ToList();

            var stream = disorderedData.ToObservable().ToStreamable(DisorderPolicy.Drop(reorderLatency));

            stream.ToStreamEventObservable().ForEachAsync(e => { if (e.IsData)
                                                                 {
                                                                     outputList.Add(e);
                                                                 }
                                                          }).Wait();

            disorderedData.Sort((a, b) => a.SyncTime.CompareTo(b.SyncTime));

            Assert.IsTrue(disorderedData.SequenceEqual(outputList));

            Config.IngressSortingTechnique = oldSortingTechnique;
        }
コード例 #4
0
 /// <summary>
 ///
 /// </summary>
 /// <typeparam name="TPayload"></typeparam>
 /// <param name="observable"></param>
 /// <param name="startEdgeSelector"></param>
 /// <param name="endEdgeSelector"></param>
 /// <param name="disorderPolicy"></param>
 /// <param name="partitionPolicy"></param>
 /// <returns></returns>
 public IQStreamable <TPayload> RegisterStream <TPayload>(
     IObservable <TPayload> observable,
     Expression <Func <TPayload, long> > startEdgeSelector,
     Expression <Func <TPayload, long> > endEdgeSelector,
     DisorderPolicy disorderPolicy,
     PartitionPolicy partitionPolicy)
 => throw new NotImplementedException();
コード例 #5
0
        public void TestSetup(DisorderPolicy disorderPolicy, PeriodicLowWatermarkPolicy lowWatermarkPolicy)
        {
            this.disorderPolicy     = disorderPolicy;
            this.lowWatermarkPolicy = lowWatermarkPolicy;

            // This establishes three partitions with keys 0,1,2
            PartitionedStreamEvent <int, int> point;

            for (int key = 0; key < 3; key++)
            {
                point = PartitionedStreamEvent.CreatePoint(key, 0, key);
                this.input.Add(point);
                this.expected[key].Add(point);
                this.batchMarker[key] = 1;
            }

            // Add a point at 100 for key 0 as a baseline, and a low watermark if necessary
            this.highWatermark = 100;
            point = PartitionedStreamEvent.CreatePoint(0, this.highWatermark, 0);
            this.input.Add(point);
            UpdateExpectedLowWatermark(this.highWatermark);
            this.expected[0].Insert(this.batchMarker[0]++, point);

            // If we have a nonzero reorder latency, the event at 100 will be buffered, so add another point at
            // 100+ReorderLatency to push the real highwatermark to 100
            if (this.ReorderLatency > 0)
            {
                AddEvent(0, this.highWatermark + this.ReorderLatency);
            }
        }
コード例 #6
0
        public void ReorderTest1Row()
        {
            using (var modifier = new ConfigModifier().IngressSortingTechnique(SortingTechnique.ImpatienceSort).Modify())
            {
                var outputList = new List <StreamEvent <int> >();

                double disorderFraction = 0.5;
                int    reorderLatency   = 202;
                int    disorderAmount   = 200;
                var    rand             = new Random(2);
                var    disorderedData   =
                    Enumerable.Range(disorderAmount, 500000).ToList()
                    .Select(e => StreamEvent.CreateStart(rand.NextDouble() < disorderFraction ? e - rand.Next(0, disorderAmount) : e, 0))
                    .ToList();

                var stream = disorderedData.ToObservable().ToStreamable(DisorderPolicy.Drop(reorderLatency));

                stream.ToStreamEventObservable().ForEachAsync(e => { if (e.IsData)
                                                                     {
                                                                         outputList.Add(e);
                                                                     }
                                                              }).Wait();

                disorderedData.Sort((a, b) => a.SyncTime.CompareTo(b.SyncTime));

                Assert.IsTrue(disorderedData.SequenceEqual(outputList));
            }
        }
コード例 #7
0
 internal TriPartitionedOrderedTestsBase(
     ConfigModifier config,
     DisorderPolicy disorderPolicy,
     PeriodicPunctuationPolicy punctuationPolicy,
     PeriodicLowWatermarkPolicy lowWatermarkPolicy) : base(config)
 {
     this.disorderPolicy     = disorderPolicy;
     this.punctuationPolicy  = punctuationPolicy;
     this.lowWatermarkPolicy = lowWatermarkPolicy;
 }
コード例 #8
0
 internal FlushTestBase(
     DisorderPolicy disorderPolicy,
     FlushPolicy flushPolicy,
     PeriodicPunctuationPolicy punctuationPolicy,
     OnCompletedPolicy completedPolicy) : base(baseConfigModifier)
 {
     this.disorderPolicy    = disorderPolicy;
     this.flushPolicy       = flushPolicy;
     this.punctuationPolicy = punctuationPolicy;
     this.completedPolicy   = completedPolicy;
 }
コード例 #9
0
        public void AlterLifeTimeWithFlushDoubles()
        {
            var startDate = new DateTime(100);
            var data      = new[]
            {
                new { Time = startDate, DeviceId = 4, Value = 4 },
                new { Time = startDate, DeviceId = 4, Value = 4 },
                new { Time = startDate, DeviceId = 6, Value = 6 },
                new { Time = startDate, DeviceId = 6, Value = 6 },
                new { Time = startDate.AddMinutes(1), DeviceId = 6, Value = 6 },
                new { Time = startDate.AddMinutes(1), DeviceId = 6, Value = 6 },
                new { Time = startDate.AddMinutes(2), DeviceId = 6, Value = 6 },
                new { Time = startDate.AddMinutes(2), DeviceId = 6, Value = 6 },
                new { Time = startDate.AddMinutes(3), DeviceId = 6, Value = 6 },
                new { Time = startDate.AddMinutes(3), DeviceId = 6, Value = 6 },
                new { Time = startDate.AddMinutes(11), DeviceId = 6, Value = 6 },
                new { Time = startDate.AddMinutes(11), DeviceId = 6, Value = 6 },
                new { Time = startDate.AddMinutes(5), DeviceId = 4, Value = 4 },
                new { Time = startDate.AddMinutes(5), DeviceId = 4, Value = 4 },
                new { Time = startDate.AddMinutes(12), DeviceId = 6, Value = 6 },
                new { Time = startDate.AddMinutes(12), DeviceId = 6, Value = 6 },
                new { Time = startDate.AddMinutes(13), DeviceId = 6, Value = 6 },
                new { Time = startDate.AddMinutes(13), DeviceId = 6, Value = 6 },
                new { Time = startDate.AddMinutes(14), DeviceId = 6, Value = 6 },
                new { Time = startDate.AddMinutes(14), DeviceId = 6, Value = 6 },
                new { Time = startDate.AddMinutes(15), DeviceId = 6, Value = 6 },
                new { Time = startDate.AddMinutes(15), DeviceId = 6, Value = 6 },
                new { Time = startDate.AddMinutes(16), DeviceId = 6, Value = 6 },
                new { Time = startDate.AddMinutes(16), DeviceId = 6, Value = 6 },
                new { Time = startDate.AddMinutes(17), DeviceId = 4, Value = 4 },
                new { Time = startDate.AddMinutes(17), DeviceId = 4, Value = 4 },
                new { Time = startDate.AddMinutes(21), DeviceId = 6, Value = 6 },
                new { Time = startDate.AddMinutes(21), DeviceId = 6, Value = 6 },
            }
            .Select(e => PartitionedStreamEvent.CreateInterval(e.DeviceId, e.Time.Ticks, StreamEvent.MaxSyncTime, e.Value));

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

            using (data.ToObservable()
                   .ToStreamable(
                       DisorderPolicy.Adjust(0),
                       PartitionedFlushPolicy.FlushOnLowWatermark,
                       PeriodicPunctuationPolicy.Time(36000))
                   .AlterEventDuration(1)
                   .ToStreamEventObservable()
                   .Subscribe(res.NotificationListObserver()))
            {
            }

            Assert.IsTrue(res.Count > 0, "There should be some results.");
        }
コード例 #10
0
        public void ReorderLatencyWithExplicitPunctuation()
        {
            var disorderPolicy = DisorderPolicy.Drop(reorderLatency: 10);

            SetupQuery(disorderPolicy);

            // These will be buffered and reordered due to reorderLatency of 10
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(0, 30, 0));
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(0, 25, 0));
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(0, 20, 0));

            // This will update partition 0's current time to 30. Anything before 30 after this point will be out of order.
            this.input.OnNext(PartitionedStreamEvent.CreatePunctuation <int, int>(0, 30));

            // Even though these events are before the partitions high watermark (30) - reorder latency (10) = 20,
            // they will still be dropped due to the punctuation at 30.
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(0, 25, 0));
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(0, 20, 0));

            // Events at or after the punctuation are still valid
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(0, 30, 0));
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(0, 35, 0));

            // Each partition is independent, so a new partition is unaffected by another's high watermark/reorderLatency
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(1, 1, 0));
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(1, 10, 0));
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(1, 5, 0));

            var expected = new PartitionedStreamEvent <int, int>[]
            {
                // Events are reordered within the reorderLatency
                PartitionedStreamEvent.CreatePoint(0, 20, 0),
                PartitionedStreamEvent.CreatePoint(0, 25, 0),
                PartitionedStreamEvent.CreatePoint(0, 30, 0),

                PartitionedStreamEvent.CreatePunctuation <int, int>(0, 30),
                PartitionedStreamEvent.CreatePoint(0, 30, 0),
                PartitionedStreamEvent.CreatePoint(0, 35, 0),

                // Each partition acts independently
                PartitionedStreamEvent.CreatePoint(1, 1, 0),
                PartitionedStreamEvent.CreatePoint(1, 5, 0),
                PartitionedStreamEvent.CreatePoint(1, 10, 0),

                // Generated by the default OnCompletedPolicy EndOfStream
                PartitionedStreamEvent.CreateLowWatermark <int, int>(StreamEvent.InfinitySyncTime),
            };

            FinishQuery(expected);
        }
コード例 #11
0
ファイル: EventProcessor.cs プロジェクト: zhrjin/TrillSamples
        /// <summary>
        /// Create query and register subscriber
        /// </summary>
        private void CreateQuery()
        {
            this.queryContainer = new QueryContainer();
            this.input          = new Subject <StreamEvent <long> >();
            var inputStream = this.queryContainer.RegisterInput(
                this.input,
                DisorderPolicy.Drop(),
                FlushPolicy.FlushOnPunctuation,
                PeriodicPunctuationPolicy.Time(1));
            var query = inputStream.AlterEventDuration(StreamEvent.InfinitySyncTime).Count();
            var async = this.queryContainer.RegisterOutput(query);

            async.Where(e => e.IsStart).ForEachAsync(o => Console.WriteLine($"{o}"));
        }
コード例 #12
0
        public void SorterDequeueUntillRow()
        {
            var oldSortingTechnique = Config.IngressSortingTechnique;

            Config.IngressSortingTechnique = SortingTechnique.ImpatienceSort;

            var input = new List <Tuple <int, int> >()
            {
                Tuple.Create(0, 1),
                Tuple.Create(1, 1),
                Tuple.Create(0, 3),
                Tuple.Create(0, 5),
                Tuple.Create(1, 3),
                Tuple.Create(1, 20),
                Tuple.Create(0, 6),
                Tuple.Create(0, 7),
                Tuple.Create(0, 8),
                Tuple.Create(1, 2),
                Tuple.Create(0, 2),
                Tuple.Create(1, 30),
                Tuple.Create(0, 13)
            };

            var expectedoutput = new List <Tuple <int, int> >()
            {
                Tuple.Create(1, 1),
                Tuple.Create(1, 3),
                Tuple.Create(1, 20),
                Tuple.Create(0, 1),
                Tuple.Create(0, 2),
                Tuple.Create(0, 3),
                Tuple.Create(0, 5),
                Tuple.Create(0, 6),
                Tuple.Create(0, 7),
                Tuple.Create(0, 8),
                Tuple.Create(0, 13),
                Tuple.Create(1, 30)
            };

            var prog = input.Select(x => PartitionedStreamEvent.CreateStart(x.Item1, x.Item2, x.Item2)).ToObservable()
                       .ToStreamable(DisorderPolicy.Drop(10)).ToStreamEventObservable();
            var outevents = prog.ToEnumerable().ToList();
            var output    = outevents.Where(o => o.IsData).ToList();
            var success   = output.SequenceEqual(expectedoutput.Select(t => PartitionedStreamEvent.CreateStart(t.Item1, t.Item2, t.Item2)));

            Config.IngressSortingTechnique = oldSortingTechnique;

            Assert.IsTrue(success);
        }
コード例 #13
0
        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;
        }
コード例 #14
0
        public void ReorderLatencyAdjust()
        {
            var disorderPolicy = DisorderPolicy.Adjust(reorderLatency: 10);

            SetupQuery(disorderPolicy);

            // These will be buffered and reordered due to reorderLatency of 10
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(0, 30, 0));
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(0, 25, 0));
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(0, 20, 0));

            // These will be adjusted to the minimum, since they are before the partition's high watermark (30) - reorder latency (10) = 20
            this.input.OnNext(PartitionedStreamEvent.CreateInterval(0, 8, 30, 0)); // Will be adjusted to 20
            this.input.OnNext(PartitionedStreamEvent.CreateInterval(0, 9, 30, 0)); // Will be adjusted to 20

            // This will be dropped, since Trill will not adjust intervals whose end times are before the minimum
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(0, 8, 0)); // Will be dropped
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(0, 9, 0)); // Will be dropped

            // Each partition is independent, so a new partition is unaffected by another's high watermark/reorderLatency
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(1, 1, 0));
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(1, 10, 0));
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(1, 5, 0));

            var expected = new PartitionedStreamEvent <int, int>[]
            {
                // Events are reordered within the reorderLatency, and out of order events are adjusted to minimum
                PartitionedStreamEvent.CreatePoint(0, 20, 0),
                PartitionedStreamEvent.CreateInterval(0, 20, 30, 0),
                PartitionedStreamEvent.CreateInterval(0, 20, 30, 0),
                PartitionedStreamEvent.CreatePoint(0, 25, 0),
                PartitionedStreamEvent.CreatePoint(0, 30, 0),

                // Each partition acts independently
                PartitionedStreamEvent.CreatePoint(1, 1, 0),
                PartitionedStreamEvent.CreatePoint(1, 5, 0),
                PartitionedStreamEvent.CreatePoint(1, 10, 0),

                // Generated by the default OnCompletedPolicy EndOfStream
                PartitionedStreamEvent.CreateLowWatermark <int, int>(StreamEvent.InfinitySyncTime),
            };

            FinishQuery(expected);
        }
コード例 #15
0
        public void FlushOnLowWatermarkSimple()
        {
            SetupQuery(DisorderPolicy.Throw(reorderLatency: 10), PartitionedFlushPolicy.FlushOnLowWatermark,
                       null, null, OnCompletedPolicy.None);

            // This will be buffered due to reorderLatency
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(0, 1, 0));

            // Since we specify FlushOnLowWatermark, this will flush the point above, as well as the low watermark itself
            this.input.OnNext(PartitionedStreamEvent.CreateLowWatermark <int, int>(9000));

            var expected = new PartitionedStreamEvent <int, int>[]
            {
                // Flushed in response to low watermark
                PartitionedStreamEvent.CreatePoint(0, 1, 0),
                PartitionedStreamEvent.CreateLowWatermark <int, int>(9000),
            };

            FinishQuery(expected);
        }
コード例 #16
0
        public void LowWatermark()
        {
            var disorderPolicy = DisorderPolicy.Drop(reorderLatency: 10);

            SetupQuery(disorderPolicy, PartitionedFlushPolicy.None);

            // This will be buffered due to reorderLatency
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(0, 1, 0));

            // This will set the entire stream's lower bound to 100
            this.input.OnNext(PartitionedStreamEvent.CreateLowWatermark <int, int>(100));

            // If any partition, new or existing, specifies a timestamp before 100, it is considered out of order
            // and since we specify DisorderPolicy.Drop, they will be dropped
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(0, 50, 0));
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(1, 50, 0));

            // Any points at or after the low watermark of 100 will be processed as usual
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(0, 100, 0));
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(1, 100, 0));
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(0, 105, 0));
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(1, 105, 0));

            var expected = new PartitionedStreamEvent <int, int>[]
            {
                // Flushed in response to the default OnCompletedPolicy.EndOfStream
                PartitionedStreamEvent.CreatePoint(0, 1, 0),
                PartitionedStreamEvent.CreateLowWatermark <int, int>(100),

                // Points at time 50 are dropped
                PartitionedStreamEvent.CreatePoint(0, 100, 0),
                PartitionedStreamEvent.CreatePoint(1, 100, 0),
                PartitionedStreamEvent.CreatePoint(0, 105, 0),
                PartitionedStreamEvent.CreatePoint(1, 105, 0),

                // Generated by the default OnCompletedPolicy EndOfStream
                PartitionedStreamEvent.CreateLowWatermark <int, int>(StreamEvent.InfinitySyncTime),
            };

            FinishQuery(expected);
        }
コード例 #17
0
        protected void LocalDisorderingBase(DisorderPolicy disorderPolicy, PeriodicLowWatermarkPolicy lowWatermarkPolicy)
        {
            TestSetup(disorderPolicy, lowWatermarkPolicy);

            // Add events that are locally disordered

            // Partition 0
            AddEvent(0, 100);

            // Partition 1
            AddEvent(1, 100);
            AddEvent(1, 95);
            AddEvent(1, 89);

            // Partition 2
            AddEvent(2, 96);
            AddEvent(2, 94);
            AddEvent(2, 91);

            RunAndValidate();
        }
コード例 #18
0
        public void PunctuationTimeGeneration()
        {
            SetupQuery(
                DisorderPolicy.Throw(),
                PartitionedFlushPolicy.FlushOnLowWatermark,
                PeriodicPunctuationPolicy.Time(generationPeriod: 1000));

            // This establishes three partitions with keys 1,2,3
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(0, 0, 0));
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(1, 0, 1));
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(2, 0, 2));

            // Since the next point arrives at 10001, which is exactly PeriodicPunctuationPolicy.generationPeriod after
            // the first point, this will generate a punctuation at 10001
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(0, 10001, 0));

            // These are still valid, since the punctuation generated above only affects key 0
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(1, 1, 1));
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(2, 1, 2));

            var expected = new PartitionedStreamEvent <int, int>[]
            {
                // Flushed in response to OnCompleted
                PartitionedStreamEvent.CreatePoint(0, 0, 0),
                PartitionedStreamEvent.CreatePoint(1, 0, 1),
                PartitionedStreamEvent.CreatePoint(2, 0, 2),

                // Punctuation snapped to the leftmost generationPeriod boundary
                PartitionedStreamEvent.CreatePunctuation <int, int>(0, 10000),
                PartitionedStreamEvent.CreatePoint(0, 10001, 0),

                PartitionedStreamEvent.CreatePoint(1, 1, 1),
                PartitionedStreamEvent.CreatePoint(2, 1, 2),

                // Generated by the default OnCompletedPolicy EndOfStream
                PartitionedStreamEvent.CreateLowWatermark <int, int>(StreamEvent.InfinitySyncTime),
            };

            FinishQuery(expected);
        }
コード例 #19
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();
            }
        }
コード例 #20
0
        public void ReorderLatencyDrop()
        {
            var disorderPolicy = DisorderPolicy.Drop(reorderLatency: 10);

            SetupQuery(disorderPolicy);

            // These will be buffered and reordered due to reorderLatency of 10
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(0, 30, 0));
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(0, 25, 0));
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(0, 20, 0));

            // These will be dropped since they are before the partition's high watermark (30) - reorder latency (10) = 20
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(0, 8, 0));
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(0, 9, 0));

            // Each partition is independent, so a new partition is unaffected by another's high watermark/reorderLatency
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(1, 1, 0));
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(1, 10, 0));
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(1, 5, 0));

            var expected = new PartitionedStreamEvent <int, int>[]
            {
                // Events are reordered within the reorderLatency
                PartitionedStreamEvent.CreatePoint(0, 20, 0),
                PartitionedStreamEvent.CreatePoint(0, 25, 0),
                PartitionedStreamEvent.CreatePoint(0, 30, 0),

                // Each partition acts independently
                PartitionedStreamEvent.CreatePoint(1, 1, 0),
                PartitionedStreamEvent.CreatePoint(1, 5, 0),
                PartitionedStreamEvent.CreatePoint(1, 10, 0),

                // Generated by the default OnCompletedPolicy EndOfStream
                PartitionedStreamEvent.CreateLowWatermark <int, int>(StreamEvent.InfinitySyncTime),
            };

            FinishQuery(expected);
        }
コード例 #21
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);
        }
コード例 #22
0
 public FlushOnBatchBoundary_OnCompletedEndOfStream() : base(DisorderPolicy.Throw(), FlushPolicy.FlushOnBatchBoundary, PeriodicPunctuationPolicy.None(), OnCompletedPolicy.EndOfStream)
 {
 }
コード例 #23
0
 public FlushNone_OnCompletedEndOfStream() : base(DisorderPolicy.Throw(), FlushPolicy.None, PeriodicPunctuationPolicy.None(), OnCompletedPolicy.EndOfStream)
 {
 }
コード例 #24
0
 public FlushOnPunctuation_OnCompletedFlush() : base(DisorderPolicy.Throw(), FlushPolicy.FlushOnPunctuation, PeriodicPunctuationPolicy.None(), OnCompletedPolicy.Flush)
 {
 }
コード例 #25
0
        public static void Main(string[] args)
        {
            // start networking
            string ip   = "127.0.0.1";
            int    port = 8000;

            // We make a new thread dedicated to the Socket
            // detach from observer logic to provide multiple subscriptions
            ThreadedListener listener       = new ThreadedListener(ip, port);
            Thread           listenerThread = new Thread(new ThreadStart(listener.StartListener));

            listenerThread.Start();

            /*
             * source: Observable that adds an Observer to the listener when subscribed to, i.e. called ToObservable() on
             */
            IObservable <StreamEvent <Payload> > source = Observable.Create <StreamEvent <Payload> >(
                observer => {
                listener.AddObserver(observer);
                return(Disposable.Create(() => Console.WriteLine("Unsubscribed")));
            });

            /*
             * inputStream: Streamable that ingresses from source
             * Uses a FlushPolicy and Punctuations, which inject empty events in order to force the stream to process
             * Flush policy does not take precedence over windows, i.e. HoppingWindows retain their time frame when queries are being run
             */
            var inputStream = source.ToStreamable(
                DisorderPolicy.Drop());

            // a sample query
            var query1 = inputStream.Where(e => e.EventID == 0);


            ///////////////////////////
            ///// BEGIN USE CASES /////
            ///////////////////////////


            /*
             * TEMPORAL CASES: use *temporal* stream
             * control window with temporalWindow
             */
            var temporalWindow = 8.0;
            var temporal       = inputStream
                                 .HoppingWindowLifetime(TimeSpan.FromSeconds(temporalWindow).Ticks, TimeSpan.FromSeconds(1.0).Ticks);

            /*
             * 1: Detect when event B occurs within x minutes of event A
             */
            var temporalA = temporal.Where(e => e.EventID == 0);
            var temporalB = temporal.Where(e => e.EventID == 1);
            // join currently matches on IsTemporal, which is always null...
            var temporal1 = temporalA.Join(temporalB, e => e.IsTemporal, e => e.IsTemporal,
                                           (left, right) => new {
                leftID       = left.DeviceID,
                rightID      = right.DeviceID,
                leftTS       = left.Timestamp,
                rightTS      = left.Timestamp,
                leftEventID  = left.EventID,
                rightEventID = right.EventID
            })
                            .Select(e => new { e.leftID, e.rightID, e.leftEventID, e.rightEventID });

            // Linq-syntax analog of the above
            var temporalFinalLinq = from left in temporalA
                                    join right in temporalB on
                                    left.IsTemporal equals right.IsTemporal
                                    select new {
                leftID       = left.DeviceID,
                rightID      = right.DeviceID,
                leftTS       = left.Timestamp,
                rightTS      = left.Timestamp,
                leftEventID  = left.EventID,
                rightEventID = right.EventID
            };

            /*
             * 2: Detect when event A occurs at least n times within x minutes
             */
            // reuse the temporalA above
            var temporal2 = temporalA.Count();

            ////////////////////////////

            /*
             * Spatial cases: use spatial stream
             * control window with spatialWindow
             */
            var spatialWindow = 30.0;
            var spatial       = inputStream
                                .Select(payload => new { payload.DeviceID, payload.EventID, Location = new Location(payload.EventData) })
                                .HoppingWindowLifetime(TimeSpan.FromSeconds(spatialWindow).Ticks, TimeSpan.FromSeconds(1.0).Ticks);

            /*
             * 1: Detect two objects within x feet of each other
             */
            double spatialThreshold = 15.0;
            var    spatialLat       = spatial.Select(payload => new { payload.DeviceID, payload.Location.latitude });
            var    spatialLong      = spatial.Select(payload => new { payload.DeviceID, payload.Location.longitude });

            var latitudes = spatialLat
                            .Join(
                spatialLat,
                (left, right) => new { leftID = left.DeviceID, rightID = right.DeviceID, difference = Math.Abs(left.latitude - right.latitude) })
                            .Where(e => (e.leftID != e.rightID) && (e.difference <= spatialThreshold));

            var longitudes = spatialLong
                             .Join(
                spatialLong,
                (left, right) => new { leftID = left.DeviceID, rightID = right.DeviceID, difference = Math.Abs(left.longitude - right.longitude) })
                             .Where(e => (e.leftID != e.rightID) && (e.difference <= spatialThreshold));

            var spatial1 = from e1 in latitudes
                           join e2 in longitudes
                           on new { e1.leftID, e1.rightID } equals new { e2.leftID, e2.rightID }
            select new {
                e1.leftID,
                e1.rightID,
                latDiff  = e1.difference,
                longDiff = e2.difference
            };

            ////////////////////////////

            /*
             * SEQUENTIAL CASES
             * control window with seqWindow
             */

            var seqWindow = 60.0;
            var sequence  = inputStream;

            /*
             * 1: Detect when event A occurs, followed by event B, followed by event C
             */
            var sequence1 = sequence.FollowedByImmediate(
                (event1) => event1.EventID == 0,
                (event2) => event2.EventID == 1,
                (first, second) => second,
                TimeSpan.FromSeconds(seqWindow).Ticks)
                            .FollowedByImmediate(
                sequence,
                (event2) => event2.EventID == 1,
                (event3) => event3.EventID == 2,
                (second, third) => third,
                TimeSpan.FromSeconds(seqWindow).Ticks);

            /*
             * 2: Detect when event A occurs, followed by event B or event C, followed by event D
             */
            var sequence2 = sequence.FollowedByImmediate(
                (event1) => event1.EventID == 0,
                (event2) => event2.EventID == 1 || event2.EventID == 2,
                (first, second) => second,
                TimeSpan.FromSeconds(seqWindow).Ticks)
                            .FollowedByImmediate(
                sequence,
                (event2) => true,
                (event3) => event3.EventID == 3,
                (second, third) => third,
                TimeSpan.FromSeconds(seqWindow).Ticks);

            ////////////////////////////

            /*
             * EVALUATION CASES
             * value to compare is evalThreshold
             * control window with evalWindow
             */
            var evalThreshold = 20;
            var evalWindow    = 10.0;
            var evaluation    = inputStream
                                .HoppingWindowLifetime(TimeSpan.FromSeconds(evalWindow).Ticks, TimeSpan.FromSeconds(1.0).Ticks);

            //var evaluation1 = evaluation.Where(e => Int32.Parse(e.EventData) > evalThreshold);


            ///////////////////////////
            ////// END USE CASES //////
            ///////////////////////////


            /*
             * Egress: each stream query is egressed to an Observable
             * Objects in the Observable are written via the arrow function (`() => new { }`)
             * Constructor parameters (`(start, end, payload)`) determine the data to pull from the query
             * action code goes in ForEachAsync block
             */
            inputStream.ToStreamEventObservable().Where(e => e.IsData).ForEachAsync(m => Console.WriteLine("Events detected! " + m.Payload.EventData));

            // Temporal output
            //temporal1.ToStreamEventObservable().Where(e => e.IsData).ForEachAsync(m => Console.WriteLine("Events detected! " + m));
            //temporal2.ToStreamEventObservable()
            //    .Where(e => e.IsData)
            //    .ForEachAsync(m => {
            //        Console.WriteLine("Number of event A detected: " + m.Payload);
            //        // do things with m here...
            //        ulong n = 4;
            //        if (m.Payload >= n) {
            //            Console.WriteLine("More than n event A detected!");
            //        }
            //    });

            // Spatial output
            spatial1.ToStreamEventObservable().Where(e => e.IsData).ForEachAsync(m => Console.WriteLine("Devices " + m.Payload.leftID + " and " + m.Payload.rightID + " have a lat/long diff of (" + m.Payload.latDiff + ", " + m.Payload.longDiff + ")"));

            // Sequence output
            //sequence1.ToStreamEventObservable().Where(e => e.IsData).ForEachAsync(m => Console.WriteLine(m.StartTime + ", " + m.EndTime));
            //sequence2.ToStreamEventObservable().Where(e => e.IsData).ForEachAsync(m => Console.WriteLine(m));

            // Evaluation output
            //evaluation1.ToTemporalObservable((start, end, payload) => new { payload.DeviceID, payload.EventID }).ForEachAsync(m => Console.WriteLine(m));
        }
コード例 #26
0
        public static void Test()
        {
            // This program is a supplement to the Trill Users Guide

            #region Section 2

            IObservable <ContextSwitch> cSTicksObs = new[]
            {
                new ContextSwitch(0, 1, 1, 120),
                new ContextSwitch(0, 3, 2, 121),
                new ContextSwitch(0, 5, 3, 124),
                new ContextSwitch(120, 2, 1, 123),
                new ContextSwitch(300, 1, 1, 122),
                new ContextSwitch(1800, 4, 2, 125),
                new ContextSwitch(3540, 2, 1, 119),
                new ContextSwitch(3600, 1, 1, 120),
            }.ToObservable();

            Console.WriteLine("Figure 11: Complete Pass-Through Trill Query Program");

            var cSTicksEventObs = cSTicksObs.Select(
                e => StreamEvent.CreateInterval(e.CSTicks, e.CSTicks + 1, e));
            var cSTicksStream =
                cSTicksEventObs.ToStreamable(DisorderPolicy.Drop());
            var origCSTicksEventObs = cSTicksStream.ToStreamEventObservable();
            origCSTicksEventObs.Where(e => e.IsData).ForEachAsync(e => Console.WriteLine(
                                                                      "Start Time={0}\tEnd Time={1}\tCSTicks={2}\tPID={3}\tCID={4}\tCPUTemp={5}",
                                                                      e.StartTime, e.EndTime, e.Payload.CSTicks, e.Payload.PID, e.Payload.CID,
                                                                      e.Payload.CPUTemp)).Wait();
            Console.WriteLine();

            #endregion

            #region Section 3

            Console.WriteLine("Figure 13: Where Query Code");

            var cSTicks2Cores = cSTicksStream.Where(p => p.CID == 1 || p.CID == 2);
            cSTicks2Cores.ToStreamEventObservable().Where(e => e.IsData).ForEachAsync(e => Console.WriteLine(
                                                                                          "Start Time={0}\tEnd Time={1}\tCSTicks={2}\tPID={3}\tCID={4}\tCPUTemp={5}",
                                                                                          e.StartTime, e.EndTime, e.Payload.CSTicks, e.Payload.PID, e.Payload.CID,
                                                                                          e.Payload.CPUTemp)).Wait();
            Console.WriteLine();

            Console.WriteLine("Figure 16: Select Query Code");
            var cSNarrowTicks2Cores = cSTicks2Cores.Select(
                e => new { CSTicks = e.CSTicks, PID = e.PID, CID = e.CID });
            cSNarrowTicks2Cores.ToStreamEventObservable().Where(e => e.IsData).ForEachAsync(e => Console.WriteLine(
                                                                                                "Start Time={0}\tEnd Time={1}\tCSTicks={2}\tPID={3}\tCID={4}",
                                                                                                e.StartTime, e.EndTime, e.Payload.CSTicks, e.Payload.PID, e.Payload.CID)).Wait();
            Console.WriteLine();

            Console.WriteLine("Figure 17: Alternate Select Query Code");
            var cSNarrowTicks2Cores2 = cSTicks2Cores.Select(
                e => new { CSTicks = e.CSTicks, PID = e.PID, CID = e.CID });
            cSNarrowTicks2Cores2.ToStreamEventObservable().Where(e => e.IsData).ForEachAsync(e => Console.WriteLine(
                                                                                                 "Start Time={0}\tEnd Time={1}\tCSTicks={2}\tPID={3}\tCID={4}",
                                                                                                 e.StartTime, e.EndTime, e.Payload.CSTicks, e.Payload.PID, e.Payload.CID)).Wait();
            Console.WriteLine();

            Console.WriteLine("Figure 19: Where and Select with the LinQ Comprehension Syntax");
            var cSNarrowTicks2Cores3 = from e in cSTicksStream
                                       where e.CID == 1 || e.CID == 2
                                       select new { e.CSTicks, e.PID, e.CID };
            cSNarrowTicks2Cores3.ToStreamEventObservable().Where(e => e.IsData).ForEachAsync(e => Console.WriteLine(
                                                                                                 "Start Time={0}\tEnd Time={1}\tCSTicks={2}\tPID={3}\tCID={4}",
                                                                                                 e.StartTime, e.EndTime, e.Payload.CSTicks, e.Payload.PID, e.Payload.CID)).Wait();
            Console.WriteLine();

            #endregion

            #region Section 4

            Console.WriteLine("Figure 22: Join Query Code");

            var processNamesObs = new[]
            {
                new ProcessName(1, "Word"),
                new ProcessName(2, "Internet Explorer"),
                new ProcessName(3, "Excel"),
                new ProcessName(4, "Visual Studio"),
                new ProcessName(5, "Outlook"),
            }.ToObservable();
            var pNamesStream = processNamesObs.
                               Select(e => StreamEvent.CreateInterval(0, 10000, e)).
                               ToStreamable();
            var cSTicks2CoresWithPNames = cSNarrowTicks2Cores.Join(pNamesStream, e => e.PID, e => e.PID,
                                                                   (leftPayload, rightPayload) => new
            {
                leftPayload.CSTicks,
                leftPayload.PID,
                leftPayload.CID,
                PName = rightPayload.PName
            });
            cSTicks2CoresWithPNames.ToStreamEventObservable().Where(e => e.IsData).ForEachAsync(e => Console.WriteLine(
                                                                                                    "Start Time={0}\tEnd Time={1}\tCSTicks={2}\tPID={3}\tCID={4}\tPName={5}",
                                                                                                    e.StartTime, e.EndTime, e.Payload.CSTicks, e.Payload.PID, e.Payload.CID, e.Payload.PName)).Wait();
            Console.WriteLine();

            Console.WriteLine("Figure 24: Join Query Comprehension Syntax");
            var cSTicks2CoresWithPNames2 = from leftPayload in cSNarrowTicks2Cores
                                           join rightPayload in pNamesStream on
                                           leftPayload.PID equals rightPayload.PID
                                           select new
            {
                leftPayload.CSTicks,
                leftPayload.PID,
                leftPayload.CID,
                PName = rightPayload.PName
            };
            cSTicks2CoresWithPNames2.ToStreamEventObservable().Where(e => e.IsData).ForEachAsync(e => Console.WriteLine(
                                                                                                     "Start Time={0}\tEnd Time={1}\tCSTicks={2}\tPID={3}\tCID={4}\tPName={5}",
                                                                                                     e.StartTime, e.EndTime, e.Payload.CSTicks, e.Payload.PID, e.Payload.CID, e.Payload.PName)).Wait();
            Console.WriteLine();

            Console.WriteLine("Figure 25: Entire Join Query Comprehension Syntax");
            var cSTicks2CoresWithPNames3 = from leftPayload in cSTicksStream
                                           join rightPayload in pNamesStream on
                                           leftPayload.PID equals rightPayload.PID
                                           where leftPayload.CID == 1 || leftPayload.CID == 2
                                           select new
            {
                leftPayload.CSTicks,
                leftPayload.PID,
                leftPayload.CID,
                rightPayload.PName
            };
            cSTicks2CoresWithPNames3.ToStreamEventObservable().Where(e => e.IsData).ForEachAsync(e => Console.WriteLine(
                                                                                                     "Start Time={0}\tEnd Time={1}\tCSTicks={2}\tPID={3}\tCID={4}\tPName={5}",
                                                                                                     e.StartTime, e.EndTime, e.Payload.CSTicks, e.Payload.PID, e.Payload.CID, e.Payload.PName)).Wait();
            Console.WriteLine();

            #endregion

            #region Section 5

            Console.WriteLine("Figure 26: AlterEventDuration Query Code");
            var infinitecSTicks2Cores =
                cSTicks2CoresWithPNames.AlterEventDuration(StreamEvent.InfinitySyncTime);
            infinitecSTicks2Cores.ToStreamEventObservable().Where(e => e.IsData).ForEachAsync(e => Console.WriteLine(
                                                                                                  "Start Time={0}\tEnd Time={1}\tCSTicks={2}\tPID={3}\tCID={4}\tPName={5}",
                                                                                                  e.StartTime, e.EndTime, e.Payload.CSTicks, e.Payload.PID, e.Payload.CID, e.Payload.PName)).Wait();
            Console.WriteLine();

            #endregion Section 6

            #region Section 6

            Console.WriteLine("Figure 28: ClipEventDuration Query Code");
            var clippedCSTicks2Cores = infinitecSTicks2Cores.
                                       ClipEventDuration(infinitecSTicks2Cores, e => e.CID, e => e.CID);
            clippedCSTicks2Cores.ToStreamEventObservable(ReshapingPolicy.CoalesceEndEdges).Where(e => e.IsData).ForEachAsync(e => Console.WriteLine(
                                                                                                                                 "Start Time={0}\tEnd Time={1}\tCSTicks={2}\tPID={3}\tCID={4}\tPName={5}",
                                                                                                                                 e.StartTime, e.EndTime, e.Payload.CSTicks, e.Payload.PID, e.Payload.CID, e.Payload.PName)).Wait();
            Console.WriteLine();

            #endregion

            #region Section 7

            Console.WriteLine("Figure 30: Multicast Version of ClipEventDuration Query Code");
            var clippedCSTicks2Cores2 = infinitecSTicks2Cores.Multicast(
                s => s.ClipEventDuration(s, e => e.CID, e => e.CID));
            clippedCSTicks2Cores2.ToStreamEventObservable(ReshapingPolicy.CoalesceEndEdges).Where(e => e.IsData).ForEachAsync(e => Console.WriteLine(
                                                                                                                                  "Start Time={0}\tEnd Time={1}\tCSTicks={2}\tPID={3}\tCID={4}\tPName={5}",
                                                                                                                                  e.StartTime, e.EndTime, e.Payload.CSTicks, e.Payload.PID, e.Payload.CID, e.Payload.PName)).Wait();
            Console.WriteLine();

            #endregion

            #region Section 8

            Console.WriteLine("Figure 32: ShiftEventLifetime Query Code");
            var shiftedClippedCS = clippedCSTicks2Cores.ShiftEventLifetime(startTime => 1);
            shiftedClippedCS.ToStreamEventObservable(ReshapingPolicy.CoalesceEndEdges).Where(e => e.IsData).ForEachAsync(e => Console.WriteLine(
                                                                                                                             "Start Time={0}\tEnd Time={1}\tCSTicks={2}\tPID={3}\tCID={4}\tPName={5}",
                                                                                                                             e.StartTime, e.EndTime, e.Payload.CSTicks, e.Payload.PID, e.Payload.CID, e.Payload.PName)).Wait();
            Console.WriteLine();

            Console.WriteLine("Figure 34: Timeslices Query Code");
            var timeslices = shiftedClippedCS.Join(cSTicks2CoresWithPNames, e => e.CID, e => e.CID,
                                                   (left, right) => new
            {
                left.PID,
                left.CID,
                left.PName,
                Timeslice = right.CSTicks - left.CSTicks
            });
            timeslices.ToStreamEventObservable(ReshapingPolicy.CoalesceEndEdges).Where(e => e.IsData).ForEachAsync(e => Console.WriteLine(
                                                                                                                       "Start Time={0}\tEnd Time={1}\tPID={2}\tCID={3}\tPName={4}\tTimeslice={5}",
                                                                                                                       e.StartTime, e.EndTime, e.Payload.PID, e.Payload.CID, e.Payload.PName, e.Payload.Timeslice)).Wait();
            Console.WriteLine();

            Console.WriteLine("Figure 36: Timeslices Query Code Using Multicast");
            var timeslices2 = cSTicks2CoresWithPNames.Multicast(
                t => t.AlterEventDuration(StreamEvent.InfinitySyncTime).
                Multicast(s => s.ClipEventDuration(s, e => e.CID, e => e.CID)).
                ShiftEventLifetime(startTime => 1).
                Join(t, e => e.CID, e => e.CID, (left, right) => new
            {
                left.PID,
                left.CID,
                left.PName,
                Timeslice = right.CSTicks - left.CSTicks
            }));
            timeslices2.ToStreamEventObservable(ReshapingPolicy.CoalesceEndEdges).Where(e => e.IsData).ForEachAsync(e => Console.WriteLine(
                                                                                                                        "Start Time={0}\tEnd Time={1}\tPID={2}\tCID={3}\tPName={4}\tTimeslice={5}",
                                                                                                                        e.StartTime, e.EndTime, e.Payload.PID, e.Payload.CID, e.Payload.PName, e.Payload.Timeslice)).Wait();
            Console.WriteLine();

            #endregion

            #region Section 9

            Console.WriteLine("Figure 40: Rassigning Timeslice Lifetimes with AlterEventLifetime");
            var pID1CID1Timeslices = timeslices.Where(e => e.PID == 1 && e.CID == 1);
            var windowedTimeslices = pID1CID1Timeslices.
                                     AlterEventLifetime(origStartTime => (1 + (origStartTime - 1) / 3600) * 3600, 3600);
            windowedTimeslices.ToStreamEventObservable().Where(e => e.IsData).ForEachAsync(e => Console.WriteLine(
                                                                                               "Start Time={0}\tEnd Time={1}\tPID={2}\tCID={3}\tPName={4}\tTimeslice={5}",
                                                                                               e.StartTime, e.EndTime, e.Payload.PID, e.Payload.CID, e.Payload.PName, e.Payload.Timeslice)).Wait();
            Console.WriteLine();

            Console.WriteLine("Figure 41: Reassigning Lifetimes with HoppingWindowLifetime");
            var windowedTimeslices2 = pID1CID1Timeslices.HoppingWindowLifetime(3600, 3600);
            windowedTimeslices2.ToStreamEventObservable().Where(e => e.IsData).ForEachAsync(e => Console.WriteLine(
                                                                                                "Start Time={0}\tEnd Time={1}\tPID={2}\tCID={3}\tPName={4}\tTimeslice={5}",
                                                                                                e.StartTime, e.EndTime, e.Payload.PID, e.Payload.CID, e.Payload.PName, e.Payload.Timeslice)).Wait();
            Console.WriteLine();

            Console.WriteLine("Figure 42: Sum Query Code");
            var totalConsumptionPerPeriod = windowedTimeslices.Sum(e => e.Timeslice);
            totalConsumptionPerPeriod.ToStreamEventObservable(ReshapingPolicy.CoalesceEndEdges).Where(e => e.IsData).ForEachAsync(e => Console.WriteLine(
                                                                                                                                      "Start Time={0}\tEnd Time={1}\tPayload={2}",
                                                                                                                                      e.StartTime, e.EndTime, e.Payload)).Wait();
            Console.WriteLine();

            #endregion

            #region Section 10

            Console.WriteLine("Figure 44: Group and Apply Query Code");
            var totalConsumptionPerPeriodAllCoresAllProcesses = timeslices.GroupApply(
                e => new { e.CID, e.PID, e.PName },
                s => s.HoppingWindowLifetime(3600, 3600).Sum(e => e.Timeslice),
                (g, p) => new { g.Key.CID, g.Key.PName, TotalTime = p });
            totalConsumptionPerPeriodAllCoresAllProcesses.ToStreamEventObservable(ReshapingPolicy.CoalesceEndEdges).Where(e => e.IsData).ForEachAsync(e => Console.WriteLine(
                                                                                                                                                          "Start Time={0}\tEnd Time={1}\tCID={2}\tPName={3}\tTotaltime={4}",
                                                                                                                                                          e.StartTime, e.EndTime, e.Payload.CID, e.Payload.PName, e.Payload.TotalTime)).Wait();
            Console.WriteLine();

            #endregion

            #region Section 11

            Console.WriteLine("Figure 49: Chop Query Code");
            Console.WriteLine("NB: This query is expected to fail!");
            var altCSTicksObs = new[]
            {
                new ContextSwitch(0, 1, 1, 120),
                new ContextSwitch(0, 3, 2, 121),
                new ContextSwitch(0, 5, 3, 124),
                new ContextSwitch(120, 2, 1, 123),
                new ContextSwitch(300, 1, 1, 122),
                new ContextSwitch(1800, 4, 2, 125),
                new ContextSwitch(3540, 2, 1, 119),
                new ContextSwitch(3600, 1, 1, 120),
                new ContextSwitch(5400, 3, 2, 122),
                new ContextSwitch(7200, 4, 2, 121),
            }.ToObservable();
            var altCSTicksEventObs = altCSTicksObs.Select(
                e => StreamEvent.CreateInterval(e.CSTicks, e.CSTicks + 1, e));
            var altCSTicksStream =
                altCSTicksEventObs.ToStreamable(DisorderPolicy.Drop());
            var cSTicksWithExtraCS = altCSTicksStream.AlterEventDuration(StreamEvent.InfinitySyncTime).
                                     Multicast(s => s.ClipEventDuration(s, e => e.CID, e => e.CID)).
                                     Chop(0, 3600).
                                     Select((origStartTime, e) =>
                                            new { CSTicks = origStartTime, e.PID, e.CID, e.CPUTemp }).
                                     AlterEventDuration(1);
            try
            {
                cSTicksWithExtraCS.ToStreamEventObservable().Where(e => e.IsData).ForEachAsync(e => Console.WriteLine(
                                                                                                   "Start Time={0}\tEnd Time={1}\tCSTicks{2}\tPID={3}\tCID={4}\tCPUTemp{5}",
                                                                                                   e.StartTime, e.EndTime, e.Payload.CSTicks, e.Payload.PID, e.Payload.CID, e.Payload.CPUTemp)).Wait();
            }
            catch (AggregateException e)
            {
                foreach (var ex in e.InnerExceptions)
                {
                    Console.WriteLine("{0}", ex.Message);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("{0}", e.Message);
            }
            Console.WriteLine();

            Console.WriteLine("Figure 51: Improved Chop Query Code");
            var cSTicksWithExtraCSImp = altCSTicksStream.
                                        AlterEventDuration(StreamEvent.InfinitySyncTime).
                                        Multicast(s => s.ClipEventDuration(s, e => e.CID, e => e.CID)).
                                        Join(new[] { StreamEvent.CreateInterval(0, 10800, Unit.Default) }.
                                             ToObservable().ToStreamable(),
                                             (left, right) => left).Chop(0, 3600).Select((origStartTime, e) =>
                                                                                         new { e.CID, e.PID, e.CPUTemp, CSTicks = origStartTime }).
                                        AlterEventDuration(1);
            cSTicksWithExtraCSImp.ToStreamEventObservable().Where(e => e.IsData).ForEachAsync(e => Console.WriteLine(
                                                                                                  "Start Time={0}\tEnd Time={1}\tCSTicks{2}\tPID={3}\tCID={4}\tCPUTemp{5}",
                                                                                                  e.StartTime, e.EndTime, e.Payload.CSTicks, e.Payload.PID, e.Payload.CID, e.Payload.CPUTemp)).Wait();
            Console.WriteLine();

            #endregion

            #region Section 12

            Console.WriteLine("Figure 53: Out of Order Input (Throw)");
            var ooStreamableThrow = new[]
            {
                StreamEvent.CreateInterval(10, 100, 1),
                StreamEvent.CreateInterval(0, 50, 2),
                StreamEvent.CreateInterval(0, 10, 3),
                StreamEvent.CreateInterval(11, 90, 4)
            }.ToObservable().ToStreamable(DisorderPolicy.Throw());
            try
            {
                ooStreamableThrow.ToStreamEventObservable().Where(e => e.IsData || e.IsPunctuation).ForEachAsync(e => WriteEvent(e)).Wait();
            }
            catch (Exception e)
            {
                Console.WriteLine("{0}", e.Message);
            }
            Console.WriteLine();

            Console.WriteLine("Figure 54: Out of Order Input (Drop)");
            var ooStreamableDrop = new[]
            {
                StreamEvent.CreateInterval(10, 100, 1),
                StreamEvent.CreateInterval(0, 50, 2),
                StreamEvent.CreateInterval(0, 10, 3),
                StreamEvent.CreateInterval(11, 90, 4)
            }.ToObservable().ToStreamable(DisorderPolicy.Drop());
            ooStreamableDrop.ToStreamEventObservable().Where(e => e.IsData || e.IsPunctuation).ForEachAsync(e => WriteEvent(e)).Wait();
            Console.WriteLine();

            Console.WriteLine("Figure 55: Out of Order Input (Adjust)");
            var ooStreamableAdjust = new[]
            {
                StreamEvent.CreateInterval(10, 100, 1),
                StreamEvent.CreateInterval(0, 50, 2),
                StreamEvent.CreateInterval(0, 10, 3),
                StreamEvent.CreateInterval(11, 90, 4)
            }.ToObservable().ToStreamable(DisorderPolicy.Adjust());
            ooStreamableAdjust.ToStreamEventObservable().Where(e => e.IsData || e.IsPunctuation).ForEachAsync(e => WriteEvent(e)).Wait();
            Console.WriteLine();

            Console.WriteLine("Figure 57: Creating PNamesStream with Edge Events");
            var pNamesStream2 = processNamesObs.Select(e => StreamEvent.CreateStart(0, e)).
                                Concat(processNamesObs.Select(
                                           e => StreamEvent.CreateEnd(10000, 0, e))).
                                ToStreamable();
            pNamesStream2.ToStreamEventObservable().Where(e => e.IsData || e.IsPunctuation).ForEachAsync(e => WriteEvent(e)).Wait();
            Console.WriteLine();

            Console.WriteLine("Figure 58: Creating PNameStream using Interval and Edge Events");
            var processNamesObs1 = new[]
            {
                new ProcessName(1, "Word"),
                new ProcessName(2, "Internet Explorer"),
                new ProcessName(3, "Excel"),
            }.ToObservable();
            var processNamesObs2 = new[]
            {
                new ProcessName(4, "Visual Studio"),
                new ProcessName(5, "Outlook"),
            }.ToObservable();
            var pNamesStream3 = processNamesObs1.Select(e => StreamEvent.CreateInterval(0, 10000, e)).
                                Concat(processNamesObs2.Select(e => StreamEvent.CreateStart(0, e))).
                                Concat(processNamesObs2.Select(e => StreamEvent.CreateEnd(10000, 0, e))).
                                ToStreamable();
            pNamesStream3.ToStreamEventObservable().Where(e => e.IsData || e.IsPunctuation).ForEachAsync(e => WriteEvent(e)).Wait();
            Console.WriteLine();

            Console.WriteLine("Figure 59: Coalescing Matching Edges");
            pNamesStream3.ToStreamEventObservable(ReshapingPolicy.CoalesceEndEdges).Where(e => e.IsData || e.IsPunctuation).ForEachAsync(e => WriteEvent(e)).Wait();
            Console.WriteLine();

            Console.WriteLine("Figure 60: Input with Punctuations");
            var streamablePunctuations = new[]
            {
                StreamEvent.CreateInterval(0, 1, 1),
                StreamEvent.CreateInterval(3, 4, 2),
                StreamEvent.CreatePunctuation <int>(10),
                StreamEvent.CreatePunctuation <int>(20),
                StreamEvent.CreatePunctuation <int>(30),
                StreamEvent.CreatePunctuation <int>(40),
                StreamEvent.CreateInterval(40, 41, 3)
            }.ToObservable().ToStreamable(DisorderPolicy.Drop());
            streamablePunctuations.ToStreamEventObservable().Where(e => e.IsData || e.IsPunctuation).ForEachAsync(e => WriteEvent(e)).Wait();
            Console.WriteLine();

            /*
             * Console.WriteLine("Figure 61: Input with Generated Punctuations After Every Event");
             * var streamableIthEventPunctuations = new[]
             * {
             *  StreamEvent.CreateInterval(0, 1, 1),
             *  StreamEvent.CreateInterval(3, 4, 2),
             *  StreamEvent.CreateInterval(40, 41, 3)
             * }.ToObservable().ToStreamable(DisorderPolicy.Drop(),
             *                            PeriodicPunctuationPolicy.Count(1));
             * streamableIthEventPunctuations.ToStreamEventObservable().Where(e => e.IsData || e.IsPunctuation).ForEachAsync(e => WriteEvent(e)).Wait();
             * Console.WriteLine();
             */
            Console.WriteLine("Figure 62: Input with Generated Punctuations After 10 Tick Periods");
            var streamableTimePeriodEventPunctuations = new[]
            {
                StreamEvent.CreateInterval(0, 1, 1),
                StreamEvent.CreateInterval(10, 4, 2),
                StreamEvent.CreateInterval(19, 4, 3),
                StreamEvent.CreateInterval(40, 41, 4)
            }.ToObservable().ToStreamable(DisorderPolicy.Drop(),
                                          FlushPolicy.FlushOnPunctuation,
                                          PeriodicPunctuationPolicy.Time(10));
            streamableTimePeriodEventPunctuations.ToStreamEventObservable().Where(e => e.IsData || e.IsPunctuation).ForEachAsync(e => WriteEvent(e)).Wait();
            Console.WriteLine();
            Console.WriteLine("Figure 63: Query with No Output");
            var IncompleteOutputQuery1 = new[]
            {
                StreamEvent.CreateInterval(0, 10, 1),
                StreamEvent.CreateInterval(1, 11, 2)
            }.ToObservable().ToStreamable().Count().ToStreamEventObservable();
            IncompleteOutputQuery1.Where(e => e.IsData || e.IsPunctuation).ForEachAsync(e => WriteEvent(e)).Wait();
            Console.WriteLine();

            Console.WriteLine("Figure 64: Query with Output up to Time 1");
            var IncompleteOutputQuery2 = new[]
            {
                StreamEvent.CreateInterval(0, 10, 1),
                StreamEvent.CreateInterval(1, 11, 2),
                StreamEvent.CreatePunctuation <int>(1)
            }.ToObservable().ToStreamable().Count().ToStreamEventObservable();
            IncompleteOutputQuery2.Where(e => e.IsData || e.IsPunctuation).ForEachAsync(e => WriteEvent(e)).Wait();
            Console.WriteLine();

            Console.WriteLine("Figure 65: Alternate Query with Output up to Time 1");
            var IncompleteOutputQuery3 = new[]
            {
                StreamEvent.CreateInterval(0, 10, 1),
                StreamEvent.CreateInterval(1, 11, 2)
            }.ToObservable().ToStreamable().Count().ToStreamEventObservable();
            IncompleteOutputQuery3.Where(e => e.IsData || e.IsPunctuation).ForEachAsync(e => WriteEvent(e)).Wait();
            Console.WriteLine();

            Console.WriteLine("Figure 66: Query with all Output");
            var CompleteOutputQuery1 = new[]
            {
                StreamEvent.CreateInterval(0, 10, 1),
                StreamEvent.CreateInterval(1, 11, 2),
                StreamEvent.CreatePunctuation <int>(StreamEvent.InfinitySyncTime)
            }.ToObservable().ToStreamable().Count().ToStreamEventObservable();
            CompleteOutputQuery1.Where(e => e.IsData || e.IsPunctuation).ForEachAsync(e => WriteEvent(e)).Wait();
            Console.WriteLine();

            Console.WriteLine("Figure 67: Alternate Query with all Output");
            var CompleteOutputQuery2 = new[]
            {
                StreamEvent.CreateInterval(0, 10, 1),
                StreamEvent.CreateInterval(1, 11, 2)
            }.ToObservable().ToStreamable().Count().
            ToStreamEventObservable();
            CompleteOutputQuery2.Where(e => e.IsData || e.IsPunctuation).ForEachAsync(e => WriteEvent(e)).Wait();
            Console.WriteLine("The end ...");
            #endregion
        }
コード例 #27
0
        public static void Main(string[] args)
        {
            // This program is a supplement to the Trill Query Writing Guide

            #region Section 2

            IObservable <ContextSwitch> contextSwitchObservable = new[]
            {
                new ContextSwitch(0, 1, 1, 120),
                new ContextSwitch(0, 3, 2, 121),
                new ContextSwitch(0, 5, 3, 124),
                new ContextSwitch(120, 2, 1, 123),
                new ContextSwitch(300, 1, 1, 122),
                new ContextSwitch(1800, 4, 2, 125),
                new ContextSwitch(3540, 2, 1, 119),
                new ContextSwitch(3600, 1, 1, 120),
            }.ToObservable();

            Console.WriteLine("Figure 11: Complete Pass-Through Trill Query Program");

            IObservable <StreamEvent <ContextSwitch> > contextSwitchStreamEventObservable =
                contextSwitchObservable.Select(e => StreamEvent.CreateInterval(e.Tick, e.Tick + 1, e));

            IObservableIngressStreamable <ContextSwitch> contextSwitchIngressStreamable =
                contextSwitchStreamEventObservable.ToStreamable(DisorderPolicy.Drop());
            var contextSwitchStreamable =
                (IStreamable <Empty, ContextSwitch>)contextSwitchIngressStreamable;

            IObservable <StreamEvent <ContextSwitch> > passthroughContextSwitchStreamEventObservable =
                contextSwitchStreamable.ToStreamEventObservable();

            passthroughContextSwitchStreamEventObservable.Where(e => e.IsData)
            .ForEachAsync(e => WriteEvent(e)).Wait();
            Console.WriteLine();

            Console.WriteLine("Figure 12: Non-StreamEvent Passthrough");

            var payloadStreamable            = contextSwitchObservable.ToTemporalStreamable(cs => cs.Tick);
            var passthroughPayloadObservable = payloadStreamable.ToTemporalObservable((start, cs) => cs);
            passthroughPayloadObservable.ForEachAsync(cs => Console.WriteLine(cs.ToString())).Wait();
            Console.WriteLine();

            #endregion

            #region Section 3

            Console.WriteLine("Figure 14: Where Query Code");

            var contextSwitchTwoCores = contextSwitchStreamable.Where(p => p.CpuId == 1 || p.CpuId == 2);
            contextSwitchTwoCores.ToStreamEventObservable()
            .Where(e => e.IsData)
            .ForEachAsync(e => WriteEvent(e))
            .Wait();
            Console.WriteLine();

            Console.WriteLine("Figure 17: Select Query Code");

            var contextSwitchTwoCoresNoTemp = contextSwitchTwoCores.Select(
                e => new { e.Tick, e.ProcessId, e.CpuId });
            contextSwitchTwoCoresNoTemp.ToStreamEventObservable()
            .Where(e => e.IsData)
            .ForEachAsync(e => Console.WriteLine(
                              $"StartTime = {e.StartTime, 4}\tEndTime = {e.EndTime, 4}\t" +
                              $"Tick = {e.Payload.Tick, 4}\tProcessId = {e.Payload.ProcessId}\tCpuId = {e.Payload.CpuId}"))
            .Wait();
            Console.WriteLine();

            Console.WriteLine("Figure 18: Alternate Select Query Code");

            contextSwitchTwoCoresNoTemp = contextSwitchTwoCores.Select(
                e => new { e.Tick, e.ProcessId, e.CpuId });
            contextSwitchTwoCoresNoTemp.ToStreamEventObservable()
            .Where(e => e.IsData)
            .ForEachAsync(e => Console.WriteLine(
                              $"StartTime = {e.StartTime, 4}\tEndTime = {e.EndTime, 4}\t" +
                              $"Tick = {e.Payload.Tick, 4}\tProcessId = {e.Payload.ProcessId}\tCpuId = {e.Payload.CpuId}"))
            .Wait();
            Console.WriteLine();

            Console.WriteLine("Figure 20: Where and Select with the LINQ Comprehension Syntax");

            contextSwitchTwoCoresNoTemp = from e in contextSwitchStreamable
                                          where e.CpuId == 1 || e.CpuId == 2
                                          select new { e.Tick, e.ProcessId, e.CpuId };
            contextSwitchTwoCoresNoTemp.ToStreamEventObservable()
            .Where(e => e.IsData)
            .ForEachAsync(e => Console.WriteLine(
                              $"StartTime = {e.StartTime, 4}\tEndTime = {e.EndTime, 4}\t" +
                              $"Tick = {e.Payload.Tick, 4}\tProcessId = {e.Payload.ProcessId}\tCpuId = {e.Payload.CpuId}"))
            .Wait();
            Console.WriteLine();

            #endregion

            #region Section 4

            Console.WriteLine("Figure 23: Join Query Code");

            var processNamesObservable = new[]
            {
                new ProcessName(1, "Word"),
                new ProcessName(2, "Internet Explorer"),
                new ProcessName(3, "Excel"),
                new ProcessName(4, "Visual Studio"),
                new ProcessName(5, "Outlook"),
            }.ToObservable();
            var namesStream = processNamesObservable.
                              Select(e => StreamEvent.CreateInterval(0, 10000, e)).
                              ToStreamable();
            var contextSwitchWithNames = contextSwitchTwoCoresNoTemp.Join(namesStream,
                                                                          e => e.ProcessId, e => e.ProcessId,
                                                                          (leftPayload, rightPayload) => new
            {
                leftPayload.Tick,
                leftPayload.ProcessId,
                leftPayload.CpuId,
                rightPayload.Name
            });
            contextSwitchWithNames.ToStreamEventObservable()
            .Where(e => e.IsData)
            .ForEachAsync(e => Console.WriteLine(
                              $"StartTime = {e.StartTime, 4}\tEndTime = {e.EndTime, 4}\t" +
                              $"Tick = {e.Payload.Tick, 4}\tProcessId = {e.Payload.ProcessId}\t" +
                              $"CpuId = {e.Payload.CpuId}\tName = {e.Payload.Name, 18}"))
            .Wait();
            Console.WriteLine();

            Console.WriteLine("Figure 25: Join Query Comprehension Syntax");

            contextSwitchWithNames = from leftPayload in contextSwitchTwoCoresNoTemp
                                     join rightPayload in namesStream on
                                     leftPayload.ProcessId equals rightPayload.ProcessId
                                     select new
            {
                leftPayload.Tick,
                leftPayload.ProcessId,
                leftPayload.CpuId,
                rightPayload.Name
            };
            contextSwitchWithNames.ToStreamEventObservable().Where(e => e.IsData)
            .ForEachAsync(e => Console.WriteLine(
                              $"StartTime = {e.StartTime, 4}\tEndTime = {e.EndTime, 4}\t" +
                              $"Tick = {e.Payload.Tick, 4}\tProcessId = {e.Payload.ProcessId}\t" +
                              $"CpuId = {e.Payload.CpuId}\tName = {e.Payload.Name, 18}"))
            .Wait();
            Console.WriteLine();

            Console.WriteLine("Figure 26: Entire Join Query Comprehension Syntax");

            contextSwitchWithNames = from leftPayload in contextSwitchStreamable
                                     join rightPayload in namesStream on
                                     leftPayload.ProcessId equals rightPayload.ProcessId
                                     where leftPayload.CpuId == 1 || leftPayload.CpuId == 2
                                     select new
            {
                leftPayload.Tick,
                leftPayload.ProcessId,
                leftPayload.CpuId,
                rightPayload.Name
            };
            contextSwitchWithNames.ToStreamEventObservable().Where(e => e.IsData)
            .ForEachAsync(e => Console.WriteLine(
                              $"StartTime = {e.StartTime, 4}\tEndTime = {e.EndTime, 4}\t" + $"Tick = {e.Payload.Tick, 4}\t" +
                              $"ProcessId = {e.Payload.ProcessId}\tCpuId = {e.Payload.CpuId}\tName = {e.Payload.Name, 18}"))
            .Wait();
            Console.WriteLine();

            #endregion

            #region Section 5

            Console.WriteLine("Figure 27: AlterEventDuration Query Code");

            var infiniteContextSwitch = contextSwitchWithNames.AlterEventDuration(StreamEvent.InfinitySyncTime);
            infiniteContextSwitch.ToStreamEventObservable()
            .Where(e => e.IsData)
            .ForEachAsync(e => Console.WriteLine(
                              $"StartTime = {e.StartTime, 4}\tEndTime = {e.EndTime, 20}\tTick = {e.Payload.Tick, 4}\t" +
                              $"ProcessId = {e.Payload.ProcessId}\tCpuId = {e.Payload.CpuId}\tName = {e.Payload.Name, 18}"))
            .Wait();
            Console.WriteLine();

            #endregion

            #region Section 6

            Console.WriteLine("Figure 29: ClipEventDuration Query Code");

            var clippedContextSwitch = infiniteContextSwitch
                                       .ClipEventDuration(infiniteContextSwitch, e => e.CpuId, e => e.CpuId);
            clippedContextSwitch.ToStreamEventObservable(ReshapingPolicy.CoalesceEndEdges)
            .Where(e => e.IsData)
            .ForEachAsync(e => Console.WriteLine(
                              $"StartTime = {e.StartTime, 4}\tEndTime = {e.EndTime, 20}\tTick = {e.Payload.Tick, 4}\t" +
                              $"ProcessId = {e.Payload.ProcessId}\tCpuId = {e.Payload.CpuId}\tName = {e.Payload.Name, 18}"))
            .Wait();
            Console.WriteLine();

            #endregion

            #region Section 7

            Console.WriteLine("Figure 31: Multicast Version of ClipEventDuration Query Code");

            clippedContextSwitch = infiniteContextSwitch.Multicast(
                s => s.ClipEventDuration(s, e => e.CpuId, e => e.CpuId));
            clippedContextSwitch.ToStreamEventObservable(ReshapingPolicy.CoalesceEndEdges)
            .Where(e => e.IsData)
            .ForEachAsync(e => Console.WriteLine(
                              $"StartTime = {e.StartTime, 4}\tEndTime = {e.EndTime, 20}\tTick = {e.Payload.Tick, 4}\t" +
                              $"ProcessId = {e.Payload.ProcessId}\tCpuId = {e.Payload.CpuId}\tName = {e.Payload.Name, 18}"))
            .Wait();
            Console.WriteLine();

            #endregion

            #region Section 8

            Console.WriteLine("Figure 33: ShiftEventLifetime Query Code");

            var shiftedClippedContextSwitch = clippedContextSwitch.ShiftEventLifetime(1);
            shiftedClippedContextSwitch.ToStreamEventObservable(ReshapingPolicy.CoalesceEndEdges)
            .Where(e => e.IsData)
            .ForEachAsync(e => Console.WriteLine(
                              $"StartTime = {e.StartTime, 4}\tEndTime = {e.EndTime, 20}\tTick = {e.Payload.Tick, 4}\t" +
                              $"ProcessId = {e.Payload.ProcessId}\tCpuId = {e.Payload.CpuId}\tName = {e.Payload.Name, 18}"))
            .Wait();
            Console.WriteLine();

            Console.WriteLine("Figure 35: Timeslices Query Code");

            var timeslices = shiftedClippedContextSwitch.Join(contextSwitchWithNames,
                                                              e => e.CpuId, e => e.CpuId,
                                                              (left, right) => new
            {
                left.ProcessId,
                left.CpuId,
                left.Name,
                Timeslice = right.Tick - left.Tick
            });
            timeslices.ToStreamEventObservable(ReshapingPolicy.CoalesceEndEdges)
            .Where(e => e.IsData)
            .ForEachAsync(e => Console.WriteLine(
                              $"StartTime = {e.StartTime, 4}\tEndTime = {e.EndTime, 4}\tProcessId = {e.Payload.ProcessId}\t" +
                              $"CpuId = {e.Payload.CpuId}\tName = {e.Payload.Name, 18}\tTimeslice = {e.Payload.Timeslice}"))
            .Wait();
            Console.WriteLine();

            Console.WriteLine("Figure 37: Timeslices Query Code Using Multicast");

            timeslices = contextSwitchWithNames.Multicast(t => t
                                                          .AlterEventDuration(StreamEvent.InfinitySyncTime)
                                                          .Multicast(s => s
                                                                     .ClipEventDuration(s, e => e.CpuId, e => e.CpuId))
                                                          .ShiftEventLifetime(1)
                                                          .Join(t,
                                                                e => e.CpuId, e => e.CpuId,
                                                                (left, right) => new
            {
                left.ProcessId,
                left.CpuId,
                left.Name,
                Timeslice = right.Tick - left.Tick
            }));
            timeslices.ToStreamEventObservable(ReshapingPolicy.CoalesceEndEdges)
            .Where(e => e.IsData)
            .ForEachAsync(e => Console.WriteLine(
                              $"StartTime = {e.StartTime, 4}\tEndTime = {e.EndTime, 4}\tProcessId = {e.Payload.ProcessId}\t" +
                              $"CpuId = {e.Payload.CpuId}\tName = {e.Payload.Name, 18}\tTimeslice = {e.Payload.Timeslice}"))
            .Wait();
            Console.WriteLine();

            #endregion

            #region Section 9

            Console.WriteLine("Figure 41: Rassigning Timeslice Lifetimes with AlterEventLifetime");

            var timeslicesForProcess1Cpu1         = timeslices.Where(e => e.ProcessId == 1 && e.CpuId == 1);
            var windowedTimeslicesForProcess1Cpu1 = timeslicesForProcess1Cpu1.
                                                    AlterEventLifetime(origStartTime => (1 + ((origStartTime - 1) / 3600)) * 3600, 3600);
            windowedTimeslicesForProcess1Cpu1.ToStreamEventObservable()
            .Where(e => e.IsData)
            .ForEachAsync(e => Console.WriteLine(
                              $"StartTime = {e.StartTime, 4}\tEndTime = {e.EndTime, 4}\tProcessId = {e.Payload.ProcessId}\t" +
                              $"CpuId = {e.Payload.CpuId}\tName = {e.Payload.Name}\tTimeslice = {e.Payload.Timeslice}"))
            .Wait();
            Console.WriteLine();

            Console.WriteLine("Figure 42: Reassigning Lifetimes with HoppingWindowLifetime");

            var windowedTimeslices2 = timeslicesForProcess1Cpu1.HoppingWindowLifetime(3600, 3600);
            windowedTimeslices2.ToStreamEventObservable()
            .Where(e => e.IsData)
            .ForEachAsync(e => Console.WriteLine(
                              $"StartTime = {e.StartTime, 4}\tEndTime = {e.EndTime, 4}\tProcessId = {e.Payload.ProcessId}\t" +
                              $"CpuId = {e.Payload.CpuId}\tName = {e.Payload.Name}\tTimeslice = {e.Payload.Timeslice}"))
            .Wait();
            Console.WriteLine();

            Console.WriteLine("Figure 43: Sum Query Code");

            var totalConsumptionPerPeriodForProcess1Cpu1 = windowedTimeslicesForProcess1Cpu1.Sum(e => e.Timeslice);
            totalConsumptionPerPeriodForProcess1Cpu1.ToStreamEventObservable(ReshapingPolicy.CoalesceEndEdges)
            .Where(e => e.IsData)
            .ForEachAsync(e => Console.WriteLine(
                              $"StartTime = {e.StartTime, 4}\tEndTime = {e.EndTime, 4}\tPayload = {e.Payload}"))
            .Wait();
            Console.WriteLine();

            #endregion

            #region Section 10

            Console.WriteLine("Figure 45: Group and Apply Query Code");

            var totalConsumptionPerPeriod = timeslices.GroupApply(
                e => new { e.CpuId, e.ProcessId, e.Name },
                s => s.HoppingWindowLifetime(3600, 3600).Sum(e => e.Timeslice),
                (g, p) => new { g.Key.CpuId, g.Key.Name, TotalTime = p });
            totalConsumptionPerPeriod.ToStreamEventObservable(ReshapingPolicy.CoalesceEndEdges)
            .Where(e => e.IsData)
            .ForEachAsync(e => Console.WriteLine(
                              $"StartTime = {e.StartTime, 4}\tEndTime = {e.EndTime, 4}\t" +
                              $"CpuId = {e.Payload.CpuId}\tName = {e.Payload.Name, 18}\tTotalTime = {e.Payload.TotalTime}"))
            .Wait();
            Console.WriteLine();

            #endregion

            #region Section 11

            Console.WriteLine("Figure 50: Chop Query Code");
            Console.WriteLine("NB: This query is expected to fail!");

            var alternativeContextSwitchStream = new[]
            {
                new ContextSwitch(0, 1, 1, 120),
                new ContextSwitch(0, 3, 2, 121),
                new ContextSwitch(0, 5, 3, 124),
                new ContextSwitch(120, 2, 1, 123),
                new ContextSwitch(300, 1, 1, 122),
                new ContextSwitch(1800, 4, 2, 125),
                new ContextSwitch(3540, 2, 1, 119),
                new ContextSwitch(3600, 1, 1, 120),
                new ContextSwitch(5400, 3, 2, 122),
                new ContextSwitch(7200, 4, 2, 121),
            }.ToObservable()
            .Select(e => StreamEvent.CreateInterval(e.Tick, e.Tick + 1, e))
            .ToStreamable(DisorderPolicy.Drop());

            var contextSwitchChoppedUnbounded = alternativeContextSwitchStream
                                                .AlterEventDuration(StreamEvent.InfinitySyncTime)
                                                .Multicast(s => s.ClipEventDuration(s, e => e.CpuId, e => e.CpuId))
                                                .Chop(0, 3600)
                                                .Select((origStartTime, e) =>
                                                        new { Tick = origStartTime, e.ProcessId, e.CpuId, e.CpuTemp })
                                                .AlterEventDuration(1);
            try
            {
                contextSwitchChoppedUnbounded.ToStreamEventObservable()
                .Where(e => e.IsData)
                .ForEachAsync(e => Console.WriteLine(
                                  $"StartTime = {e.StartTime, 4}\tEndTime = {e.EndTime, 4}\tTick{e.Payload.Tick, 4}\t" +
                                  $"ProcessId = {e.Payload.ProcessId}\tCpuId = {e.Payload.CpuId}\tCPUTemp{e.Payload.CpuTemp}"))
                .Wait();
            }
            catch (AggregateException e)
            {
                foreach (var ex in e.InnerExceptions)
                {
                    Console.WriteLine("{0}", ex.Message);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("{0}", e.Message);
            }
            Console.WriteLine();

            Console.WriteLine("Figure 52: Improved Chop Query Code");

            var fixedInterval = new[] { StreamEvent.CreateInterval(0, 10800, Unit.Default) }
            .ToObservable().ToStreamable();
            var contextSwitchChopped = alternativeContextSwitchStream
                                       .AlterEventDuration(StreamEvent.InfinitySyncTime)
                                       .Multicast(s => s.ClipEventDuration(s, e => e.CpuId, e => e.CpuId))
                                       .Join(fixedInterval, (left, right) => left)
                                       .Chop(0, 3600)
                                       .Select((origStartTime, e) =>
                                               new { e.CpuId, e.ProcessId, e.CpuTemp, Tick = origStartTime })
                                       .AlterEventDuration(1);
            contextSwitchChopped.ToStreamEventObservable()
            .Where(e => e.IsData)
            .ForEachAsync(e => Console.WriteLine(
                              $"StartTime = {e.StartTime, 4}\tEndTime = {e.EndTime, 4}\tTick = {e.Payload.Tick, 4}\t" +
                              $"ProcessId = {e.Payload.ProcessId}\tCpuId = {e.Payload.CpuId}\tCPUTemp = {e.Payload.CpuTemp}"))
            .Wait();
            Console.WriteLine();

            #endregion

            #region Section 12

            Console.WriteLine("Figure 54: Final Query");

            var choppedContextSwitch = alternativeContextSwitchStream
                                       .Where(cs => cs.CpuId == 1 || cs.CpuId == 2)
                                       .AlterEventDuration(StreamEvent.InfinitySyncTime)
                                       .Multicast(s => s.ClipEventDuration(s, e => e.CpuId, e => e.CpuId))
                                       .Join(fixedInterval, (left, right) => left)
                                       .Chop(0, 3600)
                                       .Select((start, e) => new { Tick = start, e.ProcessId, e.CpuId, e.CpuTemp })
                                       .AlterEventDuration(1);

            var choppedContextSwitchWithNames = choppedContextSwitch
                                                .Join(namesStream, e => e.ProcessId, e => e.ProcessId, (left, right) => new
            {
                left.Tick,
                left.ProcessId,
                left.CpuId,
                right.Name
            });

            var timeslicesPerCpu = choppedContextSwitchWithNames
                                   .Multicast(t => t
                                              .AlterEventDuration(StreamEvent.InfinitySyncTime)
                                              .Multicast(s => s.ClipEventDuration(s, e => e.CpuId, e => e.CpuId))
                                              .ShiftEventLifetime(1)
                                              .Join(t,
                                                    e => e.CpuId, e => e.CpuId,
                                                    (left, right) => new
            {
                left.ProcessId,
                left.CpuId,
                left.Name,
                Timeslice = right.Tick - left.Tick
            }));

            var mostCpuConsumedPerPeriod = timeslicesPerCpu
                                           .GroupApply(
                e => new { e.ProcessId, e.Name },
                s => s.HoppingWindowLifetime(3600, 3600).Sum(e => e.Timeslice),
                (g, p) => new { g.Key.Name, TotalTime = p })
                                           .Max((l, r) => l.TotalTime.CompareTo(r.TotalTime))
                                           .Select((startTime, payload) => new
            {
                PeriodStart      = startTime - 3600,
                PeriodEnd        = startTime,
                ProcessName      = payload.Name,
                TotalCpuConsumed = payload.TotalTime
            });

            mostCpuConsumedPerPeriod.ToStreamEventObservable(ReshapingPolicy.CoalesceEndEdges)
            .Where(e => e.IsData)
            .ForEachAsync(e => Console.WriteLine(
                              $"PeriodStart = {e.Payload.PeriodStart, 4}\tPeriodEnd = {e.Payload.PeriodEnd, 4}\t" +
                              $"Name = {e.Payload.ProcessName}\tTotalTime = {e.Payload.TotalCpuConsumed}"))
            .Wait();
            Console.WriteLine();

            #endregion

            #region Section 13.1

            Console.WriteLine("Figure 56: Out of Order Input (Throw)");

            var outOfOrderStreamableThrow = new[]
            {
                StreamEvent.CreateInterval(10, 100, 1),
                StreamEvent.CreateInterval(0, 50, 2),
                StreamEvent.CreateInterval(0, 10, 3),
                StreamEvent.CreateInterval(11, 90, 4)
            }.ToObservable().ToStreamable(DisorderPolicy.Throw());
            try
            {
                outOfOrderStreamableThrow.ToStreamEventObservable()
                .Where(e => e.IsData)
                .ForEachAsync(e => WriteEvent(e))
                .Wait();
            }
            catch (Exception e)
            {
                Console.WriteLine("{0}", e.Message);
            }
            Console.WriteLine();

            Console.WriteLine("Figure 57: Out of Order Input (Drop)");

            var outOfOrderStreamableDrop = new[]
            {
                StreamEvent.CreateInterval(10, 100, 1),
                StreamEvent.CreateInterval(0, 50, 2),
                StreamEvent.CreateInterval(0, 10, 3),
                StreamEvent.CreateInterval(11, 90, 4)
            }.ToObservable().ToStreamable(DisorderPolicy.Drop());
            outOfOrderStreamableDrop.ToStreamEventObservable()
            .Where(e => e.IsData)
            .ForEachAsync(e => WriteEvent(e))
            .Wait();
            Console.WriteLine();

            Console.WriteLine("Figure 58: Out of Order Input (Adjust)");

            var outOfOrderStreamableAdjust = new[]
            {
                StreamEvent.CreateInterval(10, 100, 1),
                StreamEvent.CreateInterval(0, 50, 2),
                StreamEvent.CreateInterval(0, 10, 3),
                StreamEvent.CreateInterval(11, 90, 4)
            }.ToObservable().ToStreamable(DisorderPolicy.Adjust());
            outOfOrderStreamableAdjust.ToStreamEventObservable()
            .Where(e => e.IsData)
            .ForEachAsync(e => WriteEvent(e))
            .Wait();
            Console.WriteLine();

            #endregion

            #region Section 13.3

            Console.WriteLine("Figure 60: Creating namesStream with Edge Events");

            namesStream = processNamesObservable.Select(e => StreamEvent.CreateStart(0, e)).
                          Concat(processNamesObservable.Select(e => StreamEvent.CreateEnd(10000, 0, e))).
                          ToStreamable();
            namesStream.ToStreamEventObservable()
            .Where(e => e.IsData)
            .ForEachAsync(e => WriteEvent(e))
            .Wait();
            Console.WriteLine();

            Console.WriteLine("Figure 61: Creating namesStream using Interval and Edge Events");

            var namesObservable1 = new[]
            {
                new ProcessName(1, "Word"),
                new ProcessName(2, "Internet Explorer"),
                new ProcessName(3, "Excel"),
            }.ToObservable();
            var namesObservable2 = new[]
            {
                new ProcessName(4, "Visual Studio"),
                new ProcessName(5, "Outlook"),
            }.ToObservable();
            namesStream = namesObservable1.Select(e => StreamEvent.CreateInterval(0, 10000, e))
                          .Concat(namesObservable2.Select(e => StreamEvent.CreateStart(0, e)))
                          .Concat(namesObservable2.Select(e => StreamEvent.CreateEnd(10000, 0, e)))
                          .ToStreamable();
            namesStream.ToStreamEventObservable()
            .Where(e => e.IsData)
            .ForEachAsync(e => WriteEvent(e))
            .Wait();
            Console.WriteLine();

            Console.WriteLine("Figure 62: Coalescing Matching Edges");

            namesStream.ToStreamEventObservable(ReshapingPolicy.CoalesceEndEdges)
            .Where(e => e.IsData)
            .ForEachAsync(e => WriteEvent(e))
            .Wait();
            Console.WriteLine();

            #endregion

            #region Section 13.4

            Console.WriteLine("Figure 63: Input with Punctuations");

            var streamablePunctuations = new[]
            {
                StreamEvent.CreateInterval(0, 1, 1),
                StreamEvent.CreateInterval(3, 4, 2),
                StreamEvent.CreatePunctuation <int>(10),
                StreamEvent.CreatePunctuation <int>(20),
                StreamEvent.CreatePunctuation <int>(30),
                StreamEvent.CreatePunctuation <int>(40),
                StreamEvent.CreateInterval(40, 41, 3)
            }.ToObservable().ToStreamable(DisorderPolicy.Drop(), FlushPolicy.FlushOnPunctuation,
                                          null, OnCompletedPolicy.None);
            streamablePunctuations.ToStreamEventObservable()
            .ForEachAsync(e => WriteEvent(e)).Wait();
            Console.WriteLine();

            Console.WriteLine("Figure 64: Input with Generated Punctuations After 10 Tick Periods");

            var streamableTimePeriodEventPunctuations = new[]
            {
                StreamEvent.CreateInterval(0, 1, 1),
                StreamEvent.CreateInterval(10, 4, 2),
                StreamEvent.CreateInterval(19, 4, 3),
                StreamEvent.CreateInterval(40, 41, 4)
            }.ToObservable().ToStreamable(DisorderPolicy.Drop(), FlushPolicy.FlushOnPunctuation,
                                          PeriodicPunctuationPolicy.Time(10), OnCompletedPolicy.None);
            streamableTimePeriodEventPunctuations.ToStreamEventObservable()
            .ForEachAsync(e => WriteEvent(e)).Wait();
            Console.WriteLine();

            Console.WriteLine("Figure 65: Query with No Output");

            var incompleteOutputQuery = new[]
            {
                StreamEvent.CreateInterval(0, 10, 1),
                StreamEvent.CreateInterval(1, 11, 2)
            }.ToObservable()
            .ToStreamable(null, FlushPolicy.FlushOnPunctuation, null, OnCompletedPolicy.None)
            .Count()
            .ToStreamEventObservable();
            incompleteOutputQuery.ForEachAsync(e => WriteEvent(e)).Wait();
            Console.WriteLine();

            Console.WriteLine("Figure 66: Query with Output up to Time 1");

            incompleteOutputQuery = new[]
            {
                StreamEvent.CreateInterval(0, 10, 1),
                StreamEvent.CreateInterval(1, 11, 2),
                StreamEvent.CreatePunctuation <int>(1)
            }.ToObservable()
            .ToStreamable(null, FlushPolicy.FlushOnPunctuation, null, OnCompletedPolicy.None)
            .Count()
            .ToStreamEventObservable();
            incompleteOutputQuery.ForEachAsync(e => WriteEvent(e)).Wait();
            Console.WriteLine();

            Console.WriteLine("Figure 67: Alternate Query with Output up to Time 1");

            incompleteOutputQuery = new[]
            {
                StreamEvent.CreateInterval(0, 10, 1),
                StreamEvent.CreateInterval(1, 11, 2)
            }.ToObservable()
            .ToStreamable(null, FlushPolicy.FlushOnPunctuation, null, OnCompletedPolicy.Flush)
            .Count()
            .ToStreamEventObservable();
            incompleteOutputQuery.ForEachAsync(e => WriteEvent(e)).Wait();
            Console.WriteLine();

            Console.WriteLine("Figure 68: Query with all Output");

            var completeOutputQuery = new[]
            {
                StreamEvent.CreateInterval(0, 10, 1),
                StreamEvent.CreateInterval(1, 11, 2),
                StreamEvent.CreatePunctuation <int>(StreamEvent.InfinitySyncTime)
            }.ToObservable()
            .ToStreamable(null, FlushPolicy.FlushOnPunctuation, null, OnCompletedPolicy.None)
            .Count()
            .ToStreamEventObservable();
            completeOutputQuery.ForEachAsync(e => WriteEvent(e)).Wait();
            Console.WriteLine();

            Console.WriteLine("Figure 69: Alternate Query with all Output");

            completeOutputQuery = new[]
            {
                StreamEvent.CreateInterval(0, 10, 1),
                StreamEvent.CreateInterval(1, 11, 2)
            }.ToObservable()
            .ToStreamable(null, FlushPolicy.FlushOnPunctuation, null, OnCompletedPolicy.EndOfStream)
            .Count()
            .ToStreamEventObservable();
            completeOutputQuery.ForEachAsync(e => WriteEvent(e)).Wait();
            Console.WriteLine();

            #endregion

            Console.ReadLine();
        }
コード例 #28
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);
        }
コード例 #29
0
        public void LowWatermarkAndPunctuationGeneration()
        {
            SetupQuery(DisorderPolicy.Throw(), PartitionedFlushPolicy.None,
                       PeriodicPunctuationPolicy.Time(generationPeriod: 20),
                       PeriodicLowWatermarkPolicy.Time(generationPeriod: 50, lowWatermarkTimestampLag: 0));

            // This establishes three partitions with keys 0,1
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(0, 0, 0));
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(1, 0, 1));

            // These points do not generate punctuations or low watermarks since neither period has lapsed.
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(0, 15, 0));
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(1, 19, 1));

            // These points generate punctuations (period of 20) but not low watermarks (period of 50)
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(0, 22, 0));
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(1, 20, 1));

            // This point generates a low watermark, since it is >= the last watermark (none/0) + the low watermark
            // generation period of 50
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(0, 50, 0));

            // These points do not generate punctuations, even though "punctuations" specifically haven't been generated
            // for these partitions since time 22/20, because the low watermark at 50 supersedes punctuations.
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(1, 55, 1));

            // Punctuation generation continues once the punctuation generation period lapses from the low watermark
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(0, 70, 2));
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(1, 71, 1));

            this.input.OnNext(PartitionedStreamEvent.CreatePoint(0, 90, 2));
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(1, 91, 1));

            var expected = new PartitionedStreamEvent <int, int>[]
            {
                PartitionedStreamEvent.CreatePoint(0, 0, 0),
                PartitionedStreamEvent.CreatePoint(1, 0, 1),

                PartitionedStreamEvent.CreatePoint(0, 15, 0),
                PartitionedStreamEvent.CreatePoint(1, 19, 1),

                // Punctuations generated after the punctuation period of 20 from time 0, snapped to the leftmost generationPeriod boundary
                PartitionedStreamEvent.CreatePunctuation <int, int>(0, 20),
                PartitionedStreamEvent.CreatePoint(0, 22, 0),
                PartitionedStreamEvent.CreatePunctuation <int, int>(1, 20),
                PartitionedStreamEvent.CreatePoint(1, 20, 1),

                // Low watermark generated after the low watermark period of 50 from time 0
                PartitionedStreamEvent.CreateLowWatermark <int, int>(50),
                PartitionedStreamEvent.CreatePoint(0, 50, 0),

                PartitionedStreamEvent.CreatePoint(1, 55, 1),

                // Punctuations generated after the punctuation period of 20 from time 50 (low watermark time), snapped to the leftmost generationPeriod boundary
                PartitionedStreamEvent.CreatePunctuation <int, int>(0, 60),
                PartitionedStreamEvent.CreatePoint(0, 70, 2),
                PartitionedStreamEvent.CreatePunctuation <int, int>(1, 60),
                PartitionedStreamEvent.CreatePoint(1, 71, 1),

                // Punctuations generated after the punctuation period of 20 from times 60 (last punctuation time), snapped to the leftmost generationPeriod boundary
                PartitionedStreamEvent.CreatePunctuation <int, int>(0, 80),
                PartitionedStreamEvent.CreatePoint(0, 90, 2),
                PartitionedStreamEvent.CreatePunctuation <int, int>(1, 80),
                PartitionedStreamEvent.CreatePoint(1, 91, 1),

                // Generated by the default OnCompletedPolicy EndOfStream
                PartitionedStreamEvent.CreateLowWatermark <int, int>(StreamEvent.InfinitySyncTime),
            };

            FinishQuery(expected);
        }
コード例 #30
0
        public void LowWatermarkGenerationWithReorderLatency()
        {
            SetupQuery(
                DisorderPolicy.Drop(reorderLatency: 50),
                PartitionedFlushPolicy.None,
                PeriodicPunctuationPolicy.None(),
                PeriodicLowWatermarkPolicy.Time(generationPeriod: 100, lowWatermarkTimestampLag: 10));

            // This establishes three partitions with keys 0,1,2
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(0, 0, 0));
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(1, 0, 1));
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(2, 0, 2));

            // This will not yet generate a low watermark, since 99 - 0 is less than the generation period of 100
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(0, 99, 0));

            // This will generate a low watermark, since (110 - lowWatermarkTimestampLag of 10) is greater than the
            // last watermark timestamp (in this case, none) + generation period (100).
            // The timestamp will be 110 - (lowWatermarkTimestampLag of 10) = 100.
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(2, 110, 0));

            // These will be dropped due to our PartitionedDisorderPolicy.Drop, since the low watermark is now 100,
            // even as they approach the low watermark, since any event before the low watermark is out of order.
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(0, 90, 0));
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(1, 99, 1));

            // These will be honored, since they are >= low watermark
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(0, 100, 1));
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(1, 105, 2));

            // This will be reordered since it is >= low watermark and within the partition's
            // high watermark (110) - reorderLatency (50)
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(2, 100, 0));

            this.input.OnNext(PartitionedStreamEvent.CreatePoint(0, 120, 0));
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(1, 150, 1));
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(2, 190, 2));

            // This will generate a low watermark, since (260 - lowWatermarkTimestampLag of 10) is greater than the
            // last watermark timestamp (100) + generation period (100).
            // The timestamp will be 260 - (lowWatermarkTimestampLag of 10) = 250.
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(2, 260, 0));

            // An explicitly ingressed low watermark will update/reset the generationPeriod
            this.input.OnNext(PartitionedStreamEvent.CreateLowWatermark <int, int>(300));

            // Even though (370 - lowWatermarkTimestampLag of 10) is greater than the last automatically generated
            // low watermark timestamp (100) + the generation period (100)); the lowWatermarkGeneration period was
            // updated to start at 300, so the next generated low watermark will be at timestamp >=
            // (300 + generationPeriod of 100)
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(0, 370, 1));

            // This will generate a low watermark, since (410 - lowWatermarkTimestampLag of 10) is >= the last low
            // watermark timestamp (300) + the generation period (100).
            // The timestamp will be 410 - (lowWatermarkTimestampLag of 10) = 400.
            this.input.OnNext(PartitionedStreamEvent.CreatePoint(0, 410, 1));

            var expected = new PartitionedStreamEvent <int, int>[]
            {
                PartitionedStreamEvent.CreatePoint(0, 0, 0),
                PartitionedStreamEvent.CreatePoint(1, 0, 1),
                PartitionedStreamEvent.CreatePoint(2, 0, 2),

                PartitionedStreamEvent.CreatePoint(0, 99, 0),

                // Generated automatically because of PeriodicLowWatermarkPolicy in response to point (key 2:100)
                PartitionedStreamEvent.CreateLowWatermark <int, int>(100),

                PartitionedStreamEvent.CreatePoint(0, 100, 1),
                PartitionedStreamEvent.CreatePoint(2, 100, 0),
                PartitionedStreamEvent.CreatePoint(1, 105, 2),
                PartitionedStreamEvent.CreatePoint(2, 110, 0),

                PartitionedStreamEvent.CreatePoint(0, 120, 0),
                PartitionedStreamEvent.CreatePoint(1, 150, 1),
                PartitionedStreamEvent.CreatePoint(2, 190, 2),

                // Generated automatically because of PeriodicLowWatermarkPolicy in response to point (key 2:260),
                // snapped to the leftmost generationPeriod boundary
                PartitionedStreamEvent.CreateLowWatermark <int, int>(200),
                PartitionedStreamEvent.CreatePoint(2, 260, 0),

                // Explicitly ingressed low watermark
                PartitionedStreamEvent.CreateLowWatermark <int, int>(300),

                PartitionedStreamEvent.CreatePoint(0, 370, 1),

                // Generated automatically because of PeriodicLowWatermarkPolicy in response to point (key 0:410)
                PartitionedStreamEvent.CreateLowWatermark <int, int>(400),
                PartitionedStreamEvent.CreatePoint(0, 410, 1),

                // Generated by the default OnCompletedPolicy EndOfStream
                PartitionedStreamEvent.CreateLowWatermark <int, int>(StreamEvent.InfinitySyncTime),
            };

            FinishQuery(expected);
        }