Esempio n. 1
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);
        }
Esempio n. 2
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);
        }
Esempio n. 3
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);
        }