} // IgnoreEmptyPeriods

        // ----------------------------------------------------------------------
        protected virtual void StartEvaluation()
        {
            if (periods.Count > 0)
            {
                TimeLineMomentCollection timeLineMoments = new TimeLineMomentCollection();
                timeLineMoments.AddAll(periods);
                if (timeLineMoments.Count > 1)
                {
                    int periodCount = 0;
                    for (int i = 0; i < timeLineMoments.Count - 1; i++)
                    {
                        ITimeLineMoment start = timeLineMoments[i];
                        ITimeLineMoment end   = timeLineMoments[i + 1];

                        if (i == 0)
                        {
                            periodCount += start.StartCount;
                            periodCount -= start.EndCount;
                        }

                        ITimePeriod period = new TimeRange(MapPeriodStart(start.Moment), MapPeriodEnd(end.Moment));
                        if (!(IgnoreEmptyPeriods && period.IsMoment))
                        {
                            if (EvaluatePeriod(period, periodCount) == false)
                            {
                                break;
                            }
                        }

                        periodCount += end.StartCount;
                        periodCount -= end.EndCount;
                    }
                }
            }
        } // StartEvaluation
Exemple #2
0
        }         // GetTimeLineMoments

        // ----------------------------------------------------------------------
        private static ITimePeriodCollection CombinePeriods(ITimeLineMomentCollection timeLineMoments)
        {
            TimePeriodCollection periods = new TimePeriodCollection();

            if (timeLineMoments.IsEmpty)
            {
                return(periods);
            }

            // search for periods
            int itemIndex = 0;

            while (itemIndex < timeLineMoments.Count)
            {
                ITimeLineMoment periodStart = timeLineMoments[itemIndex];
                if (periodStart.StartCount == 0)
                {
                    throw new InvalidOperationException();
                }

                // search next period end
                // use balancing to handle overlapping periods
                int             balance   = periodStart.StartCount;
                ITimeLineMoment periodEnd = null;
                while (itemIndex < timeLineMoments.Count - 1 && balance > 0)
                {
                    itemIndex++;
                    periodEnd = timeLineMoments[itemIndex];
                    balance  += periodEnd.StartCount;
                    balance  -= periodEnd.EndCount;
                }

                if (periodEnd == null)
                {
                    throw new InvalidOperationException();
                }

                if (periodEnd.StartCount > 0)                   // touching
                {
                    itemIndex++;
                    continue;
                }

                // found a period
                if (itemIndex < timeLineMoments.Count)
                {
                    T period = new T();
                    period.Setup(periodStart.Moment, periodEnd.Moment);
                    periods.Add(period);
                }

                itemIndex++;
            }

            return(periods);
        }         // CombinePeriods
        } // Remove

        // ----------------------------------------------------------------------
        public ITimeLineMoment Find(DateTime moment)
        {
            ITimeLineMoment timeLineMoment = null;

            if (Count > 0)
            {
                timeLineMomentLookup.TryGetValue(moment, out timeLineMoment);
            }
            return(timeLineMoment);
        } // Find
        } // AddStart

        // ----------------------------------------------------------------------
        protected virtual void AddEnd(DateTime moment, ITimePeriod period)
        {
            ITimeLineMoment timeLineMoment = Find(moment);

            if (timeLineMoment == null)
            {
                timeLineMoment = new TimeLineMoment(moment);
                timeLineMoments.Add(moment, timeLineMoment);
            }
            timeLineMoment.AddEnd();
        } // AddEnd
        }         // IEnumerable.GetEnumerator

        // ----------------------------------------------------------------------
        private void AddPeriod(DateTime moment, ITimePeriod period)
        {
            ITimeLineMoment timeLineMoment = Find(moment);

            if (timeLineMoment == null)
            {
                timeLineMoment = new TimeLineMoment(moment);
                timeLineMoments.Add(timeLineMoment);
            }
            timeLineMoment.Periods.Add(period);
        }         // AddPeriod
        } // IEnumerable.GetEnumerator

        // ----------------------------------------------------------------------
        protected virtual void AddStart(DateTime moment)
        {
            ITimeLineMoment timeLineMoment = Find(moment);

            if (timeLineMoment == null)
            {
                timeLineMoment = new TimeLineMoment(moment);
                timeLineMoments.Add(timeLineMoment);
                timeLineMomentLookup.Add(moment, timeLineMoment);
            }
            timeLineMoment.AddStart();
        } // AddStart
        } // RemoveStart

        // ----------------------------------------------------------------------
        protected virtual void RemoveEnd(DateTime moment, ITimePeriod period)
        {
            ITimeLineMoment timeLineMoment = Find(moment);

            if (timeLineMoment == null)
            {
                throw new InvalidOperationException();
            }

            timeLineMoment.RemoveEnd();
            if (timeLineMoment.IsEmpty)
            {
                timeLineMoments.Remove(moment);
            }
        } // RemoveEnd
        }         // AddPeriod

        // ----------------------------------------------------------------------
        private void RemovePeriod(DateTime moment, ITimePeriod period)
        {
            ITimeLineMoment timeLineMoment = Find(moment);

            if (timeLineMoment == null || !timeLineMoment.Periods.Contains(period))
            {
                throw new InvalidOperationException();
            }

            timeLineMoment.Periods.Remove(period);
            if (timeLineMoment.Periods.Count == 0)
            {
                timeLineMoments.Remove(timeLineMoment);
            }
        }         // RemovePeriod
        } // AddEnd

        // ----------------------------------------------------------------------
        protected virtual void RemoveStart(DateTime moment)
        {
            ITimeLineMoment timeLineMoment = Find(moment);

            if (timeLineMoment == null)
            {
                throw new InvalidOperationException();
            }

            timeLineMoment.RemoveStart();
            if (timeLineMoment.IsEmpty)
            {
                timeLineMoments.Remove(timeLineMoment);
                timeLineMomentLookup.Remove(moment);
            }
        } // RemoveStart
        }         // CombinePeriods

        // ----------------------------------------------------------------------
        private static ITimePeriodCollection IntersectCombinedPeriods(ITimeLineMomentCollection timeLineMoments)
        {
            TimePeriodCollection periods = new TimePeriodCollection();

            if (timeLineMoments.IsEmpty)
            {
                return(periods);
            }

            // search for periods
            int intersectionStart = -1;
            int balance           = 0;

            for (int i = 0; i < timeLineMoments.Count; i++)
            {
                ITimeLineMoment moment = timeLineMoments[i];

                int startCount = moment.StartCount;
                int endCount   = moment.EndCount;
                balance += startCount;
                balance -= endCount;

                // intersection is starting by a period start
                if (startCount > 0 && balance > 1 && intersectionStart < 0)
                {
                    intersectionStart = i;
                    continue;
                }

                // intersection is starting by a period end
                if (endCount <= 0 || balance > 1 || intersectionStart < 0)
                {
                    continue;
                }

                T period = new T();
                period.Setup(timeLineMoments[intersectionStart].Moment, moment.Moment);
                periods.Add(period);
                intersectionStart = -1;
            }

            return(periods);
        }         // IntersectCombinedPeriods
        } // IntersectCombinedPeriods

        // ----------------------------------------------------------------------
        private static ITimePeriodCollection IntersectPeriods(ITimeLineMomentCollection timeLineMoments)
        {
            TimePeriodCollection periods = new TimePeriodCollection();

            if (timeLineMoments.IsEmpty)
            {
                return(periods);
            }

            // search for periods
            int intersectionStart = -1;
            int balance           = 0;

            foreach (var i in Enumerable.Range(0, timeLineMoments.Count))
            {
                ITimeLineMoment moment = timeLineMoments[i];

                balance += moment.BalanceCount;

                // intersection is starting by a period start
                if (balance > 1 && intersectionStart < 0)
                {
                    intersectionStart = i;
                    continue;
                }

                // intersection is starting by a period end
                if (intersectionStart < 0)
                {
                    continue;
                }

                T period = new T();
                period.Setup(timeLineMoments[intersectionStart].Moment, moment.Moment);
                periods.Add(period);
                intersectionStart = balance > 1 ? i : -1;
            }

            return(periods);
        } // IntersectCombinedPeriods
        } // HasOverlaps

        // ----------------------------------------------------------------------
        public bool HasGaps()
        {
            bool hasGaps = false;

            if (Count > 1)
            {
                int momentCount = 0;
                for (int index = 0; index < timeLineMoments.Count; index++)
                {
                    ITimeLineMoment timeLineMoment = timeLineMoments[index];
                    momentCount += timeLineMoment.StartCount;
                    momentCount -= timeLineMoment.EndCount;
                    if (momentCount == 0 && index > 0 && index < timeLineMoments.Count - 1)
                    {
                        hasGaps = true;
                        break;
                    }
                }
            }

            return(hasGaps);
        } // HasGaps
        } // HasOverlaps

        // ----------------------------------------------------------------------
        public bool HasGaps()
        {
            bool hasGaps = false;

            if (Count > 1)
            {
                int momentCount = 0;
                foreach (var index in Enumerable.Range(0, timeLineMoments.Count))
                {
                    ITimeLineMoment timeLineMoment = timeLineMoments[index];
                    momentCount += timeLineMoment.StartCount;
                    momentCount -= timeLineMoment.EndCount;
                    if (momentCount == 0 && index > 0 && index < timeLineMoments.Count - 1)
                    {
                        hasGaps = true;
                        break;
                    }
                }
            }

            return(hasGaps);
        } // HasGaps
 public Task AddMoment(ITimelineParticipant grain, ITimeLineMoment moment)
 {
     throw new System.NotImplementedException();
 }
Exemple #15
0
        /// <summary>
        /// ITimeLineMoment 컬렉션의 모든 기간의 합집합을 구합니다.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="timeLineMoments">결합할 기간들</param>
        /// <returns></returns>
        public static ITimePeriodCollection CombinePeriods <T>(this ITimeLineMomentCollection timeLineMoments) where T : ITimePeriod
        {
            if (IsDebugEnabled)
            {
                log.Debug("ITimeLineMoment 컬렉션의 모든 기간의 합집합을 구합니다...");
            }

            var periods = new TimePeriodCollection();

            if (timeLineMoments.IsEmpty)
            {
                return(periods);
            }

            // search for periods
            var itemIndex = 0;

            while (itemIndex < timeLineMoments.Count)
            {
                var periodStart = timeLineMoments[itemIndex];
                Guard.Assert(periodStart.StartCount != 0, "StartCount 값은 0이 아니여야 합니다. periodStart.StartCount=[{0}]",
                             periodStart.StartCount);

                // search next period end
                // use balancing to handle overlapping periods
                var             balance   = periodStart.StartCount;
                ITimeLineMoment periodEnd = null;
                while (itemIndex < timeLineMoments.Count - 1 && balance > 0)
                {
                    itemIndex++;
                    periodEnd = timeLineMoments[itemIndex];
                    balance  += periodEnd.StartCount;
                    balance  -= periodEnd.EndCount;
                }

                periodEnd.ShouldNotBeNull("periodEnd");

                if (periodEnd.StartCount > 0) // touching
                {
                    itemIndex++;
                    continue;
                }

                // found a period
                if (itemIndex < timeLineMoments.Count)
                {
                    var period = ActivatorTool.CreateInstance <T>();
                    period.Setup(periodStart.Moment, periodEnd.Moment);

                    if (IsDebugEnabled)
                    {
                        log.Debug("Combine Period를 추가합니다. period=[{0}]" + period);
                    }

                    periods.Add(period);
                }

                itemIndex++;
            }

            if (IsDebugEnabled)
            {
                log.Debug("기간들을 결합했습니다. periods=[{0}]", periods.CollectionToString());
            }

            return(periods);
        }
Exemple #16
0
        }         // IntersectCombinedPeriods

        // ----------------------------------------------------------------------
        private static ITimePeriodCollection CalculateGaps(ITimePeriod range, ITimeLineMomentCollection timeLineMoments)
        {
            TimePeriodCollection gaps = new TimePeriodCollection();

            if (timeLineMoments.IsEmpty)
            {
                return(gaps);
            }

            // range leading gap
            ITimeLineMoment periodStart = timeLineMoments.Min;

            if (periodStart != null && range.Start < periodStart.Moment)
            {
                T startingGap = new T();
                startingGap.Setup(range.Start, periodStart.Moment);
                gaps.Add(startingGap);
            }

            // search for gaps
            int itemIndex = 0;

            while (itemIndex < timeLineMoments.Count)
            {
                ITimeLineMoment moment = timeLineMoments[itemIndex];
                if (moment.StartCount == 0)
                {
                    throw new InvalidOperationException();
                }

                // search next gap start
                // use balancing to handle overlapping periods
                int             balance  = moment.StartCount;
                ITimeLineMoment gapStart = null;
                while (itemIndex < timeLineMoments.Count - 1 && balance > 0)
                {
                    itemIndex++;
                    gapStart = timeLineMoments[itemIndex];
                    balance += gapStart.StartCount;
                    balance -= gapStart.EndCount;
                }

                if (gapStart == null)
                {
                    throw new InvalidOperationException();
                }

                if (gapStart.StartCount > 0)                   // touching
                {
                    itemIndex++;
                    continue;
                }

                // found a gap
                if (itemIndex < timeLineMoments.Count - 1)
                {
                    T gap = new T();
                    gap.Setup(gapStart.Moment, timeLineMoments[itemIndex + 1].Moment);
                    gaps.Add(gap);
                }

                itemIndex++;
            }

            // range closing gap
            ITimeLineMoment periodEnd = timeLineMoments.Max;

            if (periodEnd != null && range.End > periodEnd.Moment)
            {
                T endingGap = new T();
                endingGap.Setup(periodEnd.Moment, range.End);
                gaps.Add(endingGap);
            }

            return(gaps);
        }         // CalculateGaps
Exemple #17
0
        /// <summary>
        /// <paramref name="timeLineMoments"/>가 가진 모든 ITimePeriod 들의 Gap을 계산합니다.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="timeLineMoments"></param>
        /// <param name="range"></param>
        /// <returns></returns>
        public static ITimePeriodCollection CalculateGaps <T>(this ITimeLineMomentCollection timeLineMoments, ITimePeriod range)
            where T : ITimePeriod
        {
            if (IsDebugEnabled)
            {
                log.Debug("ITimeLineMomentCollection의 Gap들을 계산합니다...");
            }

            var gaps = new TimePeriodCollection();

            if (timeLineMoments.IsEmpty)
            {
                return(gaps);
            }

            // find leading gap
            //
            var periodStart = timeLineMoments.Min;

            if (periodStart != null && range.Start < periodStart.Moment)
            {
                var startingGap = ActivatorTool.CreateInstance <T>();
                startingGap.Setup(range.Start, periodStart.Moment);

                if (IsDebugEnabled)
                {
                    log.Debug("Starting Gap을 추가합니다... startingGap=[{0}]", startingGap);
                }

                gaps.Add(startingGap);
            }

            // find intermediated gap
            //
            var itemIndex = 0;

            while (itemIndex < timeLineMoments.Count)
            {
                var moment = timeLineMoments[itemIndex];

                Guard.Assert(moment.StartCount != 0, "monent.StartCount 값은 0이 아니여야 합니다. moment=[{0}]", moment);

                // search next gap start
                // use balancing to handle overlapping periods
                var             balance  = moment.StartCount;
                ITimeLineMoment gapStart = null;

                while (itemIndex < timeLineMoments.Count - 1 && balance > 0)
                {
                    itemIndex++;
                    gapStart = timeLineMoments[itemIndex];
                    balance += gapStart.StartCount;
                    balance -= gapStart.EndCount;
                }

                gapStart.ShouldNotBeNull("gapStart");

                if (gapStart.StartCount > 0) // touching
                {
                    itemIndex++;
                    continue;
                }

                // found a gap
                if (itemIndex < timeLineMoments.Count - 1)
                {
                    var gap = ActivatorTool.CreateInstance <T>();
                    gap.Setup(gapStart.Moment, timeLineMoments[itemIndex + 1].Moment);

                    if (IsDebugEnabled)
                    {
                        log.Debug("Intermediated Gap을 추가합니다. gap=[{0}]", gap);
                    }

                    gaps.Add(gap);
                }

                itemIndex++;
            }

            // find ending gap
            //
            var periodEnd = timeLineMoments.Max;

            if (periodEnd != null && range.End > periodEnd.Moment)
            {
                var endingGap = ActivatorTool.CreateInstance <T>();
                endingGap.Setup(periodEnd.Moment, range.End);

                if (IsDebugEnabled)
                {
                    log.Debug("Ending Gap을 추가합니다. endingGap=[{0}]", endingGap);
                }

                gaps.Add(endingGap);
            }

            if (IsDebugEnabled)
            {
                log.Debug("기간들의 Gap에 해당하는 부분을 계산했습니다!!! gaps=[{0}]", gaps.CollectionToString());
            }

            return(gaps);
        }