/// <summary> /// Meldet alle Aufzeichnungen ab einem bestimmten Zeitpunkt. /// </summary> /// <param name="minTime">Alle Aufzeichnungen, die vor diesem Zeitpunkt enden, werden /// nicht berücksichtigt. Die Angabe erfolgt in UTC / GMT Notation.</param> /// <returns>Alle Aufzeichnungen.</returns> private IEnumerable<ScheduleInfo> GetSchedulesForRecordings( DateTime minTime ) { // All items to process var items = new _ScheduleList( m_PlanItems.Where( r => !m_ForbiddenDefinitions.Contains( r.Definition.UniqueIdentifier ) ), minTime ); // Create the plans to extend var plans = new List<SchedulePlan> { m_PlanCreator() }; var steps = 0; // As long as necessary while (items.MoveNext()) { // Load the item var candidate = items.Current; var candiateTime = candidate.Current; var planned = candiateTime.Planned; #if !SILVERLIGHT // Report if (SchedulerTrace.TraceVerbose) Trace.TraceInformation( Properties.SchedulerResources.Trace_Candidate, candidate.Definition.Source, planned.Start, planned.Duration ); #endif // Get the current end of plans and see if we can dump the state - this may increase performance var planStart = plans.SelectMany( p => p.Resources ).Min( r => (DateTime?) r.PlanStart ); var planEnd = plans.SelectMany( p => p.Resources ).Max( r => (DateTime?) r.PlanEnd ); var canEndPlan = planEnd.HasValue && (planEnd.Value != DateTime.MinValue) && (planned.Start >= planEnd.Value); var mustEndPlan = planStart.HasValue && (planStart.Value != DateTime.MaxValue) && planEnd.HasValue && (planEnd.Value != DateTime.MinValue) && ((planEnd.Value - planStart.Value).TotalDays > 2); // Count this effort if ((++steps > MaximumRecordingsInPlan) || canEndPlan || mustEndPlan || (plans.Count > MaximumAlternativesInPlan)) { // Find best plan var best = SchedulePlan.FindBest( plans, m_comparer ); // Report foreach (var info in Dump( best )) yield return info; // Reset plans.Clear(); plans.Add( best.Restart( planned.Start ) ); // Reset steps = 1; } #if !SILVERLIGHT // Report if (SchedulerTrace.TraceVerbose) Trace.TraceInformation( Properties.SchedulerResources.Trace_PlanCount, plans.Count ); #endif // All plans to extend var allPlans = plans.ToArray(); // Discard list plans.Clear(); // Iterate over all plans and try to add the current candidate - in worst case this will multiply possible plans by the number of resources available foreach (var plan in allPlans) for (int i = plan.Resources.Length; i-- > 0; ) { // Clone of plan must be recreated for each resource because test is allowed to modify it var clone = plan.Clone(); // Remember the time we tried - implicit cast is important, do NOT use var SuggestedPlannedTime plannedTime = planned; // See if resource can handle this if (clone.Resources[i].Add( candidate.Definition, plannedTime, minTime )) plans.Add( clone ); } // Must reset if the recording could not be scheduled at all if (plans.Count < 1) { // Report yield return new ScheduleInfo( candidate.Definition, null, planned, false ); // Restore the original plans since we did nothing at all plans.AddRange( allPlans ); } } // Send all we found foreach (var info in Dump( SchedulePlan.FindBest( plans, m_comparer ) )) yield return info; }
/// <summary> /// Meldet alle Aufzeichnungen ab einem bestimmten Zeitpunkt. /// </summary> /// <param name="minTime">Alle Aufzeichnungen, die vor diesem Zeitpunkt enden, werden /// nicht berücksichtigt. Die Angabe erfolgt in UTC / GMT Notation.</param> /// <returns>Alle Aufzeichnungen.</returns> private IEnumerable <ScheduleInfo> GetSchedulesForRecordings(DateTime minTime) { // All items to process var items = new _ScheduleList(m_PlanItems.Where(r => !m_ForbiddenDefinitions.Contains(r.Definition.UniqueIdentifier)), minTime); // Create the plans to extend var plans = new List <SchedulePlan> { m_PlanCreator() }; var steps = 0; // As long as necessary while (items.MoveNext()) { // Load the item var candidate = items.Current; var candiateTime = candidate.Current; var planned = candiateTime.Planned; #if !SILVERLIGHT // Report if (SchedulerTrace.TraceVerbose) { Trace.TraceInformation(Properties.SchedulerResources.Trace_Candidate, candidate.Definition.Source, planned.Start, planned.Duration); } #endif // Get the current end of plans and see if we can dump the state - this may increase performance var planStart = plans.SelectMany(p => p.Resources).Min(r => (DateTime?)r.PlanStart); var planEnd = plans.SelectMany(p => p.Resources).Max(r => (DateTime?)r.PlanEnd); var canEndPlan = planEnd.HasValue && (planEnd.Value != DateTime.MinValue) && (planned.Start >= planEnd.Value); var mustEndPlan = planStart.HasValue && (planStart.Value != DateTime.MaxValue) && planEnd.HasValue && (planEnd.Value != DateTime.MinValue) && ((planEnd.Value - planStart.Value).TotalDays > 2); // Count this effort if ((++steps > MaximumRecordingsInPlan) || canEndPlan || mustEndPlan || (plans.Count > MaximumAlternativesInPlan)) { // Find best plan var best = SchedulePlan.FindBest(plans, m_comparer); // Report foreach (var info in Dump(best)) { yield return(info); } // Reset plans.Clear(); plans.Add(best.Restart(planned.Start)); // Reset steps = 1; } #if !SILVERLIGHT // Report if (SchedulerTrace.TraceVerbose) { Trace.TraceInformation(Properties.SchedulerResources.Trace_PlanCount, plans.Count); } #endif // All plans to extend var allPlans = plans.ToArray(); // Discard list plans.Clear(); // Iterate over all plans and try to add the current candidate - in worst case this will multiply possible plans by the number of resources available foreach (var plan in allPlans) { for (int i = plan.Resources.Length; i-- > 0;) { // Clone of plan must be recreated for each resource because test is allowed to modify it var clone = plan.Clone(); // Remember the time we tried - implicit cast is important, do NOT use var SuggestedPlannedTime plannedTime = planned; // See if resource can handle this if (clone.Resources[i].Add(candidate.Definition, plannedTime, minTime)) { plans.Add(clone); } } } // Must reset if the recording could not be scheduled at all if (plans.Count < 1) { // Report yield return(new ScheduleInfo(candidate.Definition, null, planned, false)); // Restore the original plans since we did nothing at all plans.AddRange(allPlans); } } // Send all we found foreach (var info in Dump(SchedulePlan.FindBest(plans, m_comparer))) { yield return(info); } }