Ejemplo n.º 1
0
        }         // IntersectPeriods

        // ----------------------------------------------------------------------
        public ITimePeriodCollection CalculateGaps()
        {
            // exclude periods
            TimePeriodCollection gapPeriods = new TimePeriodCollection();

            foreach (ITimePeriod period in periods)
            {
                if (limits.IntersectsWith(period))
                {
                    gapPeriods.Add(new TimeRange(period));
                }
            }

            ITimeLineMomentCollection timeLineMoments = GetTimeLineMoments(gapPeriods);

            if (timeLineMoments.Count == 0)
            {
                return(new TimePeriodCollection {
                    limits
                });
            }

            T range = new T();

            range.Setup(MapPeriodStart(limits.Start), MapPeriodEnd(limits.End));
            return(CalculateGaps(range, timeLineMoments));
        }         // CalculateGaps
Ejemplo n.º 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
Ejemplo n.º 3
0
        /// <summary>
        /// ITimeLineMomentCollection으로부터 교집합에 해당하는 기간들을 구합니다
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="timeLineMoments"></param>
        /// <returns></returns>
        public static ITimePeriodCollection IntersectPeriods <T>(this ITimeLineMomentCollection timeLineMoments) where T : ITimePeriod
        {
            if (IsDebugEnabled)
            {
                log.Debug("ITimeLineMomentCollection으로부터 교집합에 해당하는 기간들을 구합니다...");
            }

            var periods = new TimePeriodCollection();

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

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

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

                balance += moment.StartCount;
                balance -= moment.EndCount;

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

                // intersection is starting by a period end
                if (moment.EndCount > 0 && balance <= 1 && intersectionStart >= 0)
                {
                    var period = ActivatorTool.CreateInstance <T>();
                    period.Setup(timeLineMoments[intersectionStart].Moment, moment.Moment);

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

                    periods.Add(period);
                    intersectionStart = -1;
                }
            }

            if (IsDebugEnabled)
            {
                log.Debug("ITimeLineMomentCollection으로부터 교집합에 해당하는 기간들을 구했습니다. periods=[{0}]", periods.CollectionToString());
            }

            return(periods);
        }
Ejemplo n.º 4
0
        }         // PeriodMapper

        // ----------------------------------------------------------------------
        public ITimePeriodCollection CombinePeriods()
        {
            if (periods.Count == 0)
            {
                return(new TimePeriodCollection());
            }

            ITimeLineMomentCollection timeLineMoments = GetTimeLineMoments();

            return(timeLineMoments.Count == 0 ? new TimePeriodCollection {
                new TimeRange(periods)
            } : CombinePeriods(timeLineMoments));
        }         // CombinePeriods
Ejemplo n.º 5
0
        public ITimePeriodCollection CombinePeriods()
        {
            if (Periods.Count == 0 || (Periods.Count > 1 && !HasNonMomentPeriods))
            {
                return(new TimePeriodCollection());
            }

            ITimeLineMomentCollection timeLineMoments = GetTimeLineMoments();

            return(timeLineMoments.Count == 0 ? new TimePeriodCollection {
                new TimeRange(Periods)
            } : CombinePeriods(timeLineMoments));
        }
Ejemplo n.º 6
0
        }         // CombinePeriods

        // ----------------------------------------------------------------------
        public ITimePeriodCollection IntersectPeriods(bool combinePeriods = true)
        {
            if (periods.Count == 0)
            {
                return(new TimePeriodCollection());
            }

            ITimeLineMomentCollection timeLineMoments = GetTimeLineMoments();

            if (timeLineMoments.Count == 0)
            {
                return(new TimePeriodCollection());
            }

            return(combinePeriods ? IntersectCombinedPeriods(timeLineMoments) : IntersectPeriods(timeLineMoments));
        }         // IntersectPeriods
Ejemplo n.º 7
0
        }         // 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
Ejemplo n.º 8
0
        } // 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
Ejemplo n.º 9
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
Ejemplo n.º 10
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);
        }
Ejemplo n.º 11
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);
        }