private Entry FindEntry(SystemInfo sysInf, out RREntry rr) { Entry ret; SystemInfo tempInf; if (sysInf.RunRecurrenceInterval == 0) { rr = _runRecurrences[_rrEnd]; if (rr.RunRecurrence != 0) { return(new Entry(-1, -1)); } ret = _entries[rr.Start]; tempInf = _systemCache[rr.Start]; } else { rr = _runRecurrences[_rrStart]; while (rr.RunRecurrence != sysInf.RunRecurrenceInterval && rr.Next != -1) { rr = _runRecurrences[rr.Next]; } if (rr.RunRecurrence != sysInf.RunRecurrenceInterval) { return(new Entry(-1, -1)); } ret = _entries[rr.Start]; tempInf = _systemCache[rr.Start]; } if (tempInf == sysInf) { return(ret); } while (tempInf != sysInf && ret.RunRecurrence == sysInf.RunRecurrenceInterval && ret.NextEntry != -1) { ret = _entries[ret.NextEntry]; tempInf = _systemCache[ret.CacheIndex]; } if (ret.RunRecurrence != sysInf.RunRecurrenceInterval) { return(new Entry(-1, -1)); } if (tempInf != sysInf) { return(new Entry(-1, -1)); } return(ret); }
/// <summary> /// find the index of the previous entry /// </summary> /// <param name="system">system to find previous entry</param> /// <param name="rr">the runrecurrence of the system if it exists /// if it does not exist then it is the one after it unless it is at the end then the previous run recurrence</param> /// <returns>the index of the previous entry or /// -1 if this entry should be placed at the beginning or /// -2 if it should be placed at the end</returns> private int FindPreviousEntry(SystemInfo system, out RREntry rr) { if (system.RunRecurrenceInterval == 0) { rr = _runRecurrences[_rrEnd]; if (rr.RunRecurrence != 0) { return(-2); } } else { rr = _runRecurrences[_rrStart]; while (true) { if (rr.RunRecurrence > system.RunRecurrenceInterval) { if (rr.Prev == -1) { return(-1); } return(_entries[rr.Start].PrevEntry); } else if (rr.RunRecurrence < system.RunRecurrenceInterval) { if (rr.RunRecurrence == 0) { if (rr.Prev == -1) { return(-1); } return(_entries[rr.Start].PrevEntry); } if (rr.Next == -1) { return(-2); } rr = _runRecurrences[rr.Next]; } else { break; } } } Entry current = _entries[rr.Start]; SystemInfo tempSys = _systemCache[current.CacheIndex]; while (true) { if (current.RunRecurrence != system.RunRecurrenceInterval) { break; } if (tempSys.PriorityComposite > system.PriorityComposite) { if (current.NextEntry == -1) { return(-2); } current = _entries[current.NextEntry]; tempSys = _systemCache[current.CacheIndex]; } else if (tempSys.PriorityComposite <= system.PriorityComposite) { break; } } return(current.PrevEntry); }
/// <summary> /// <inheritdoc /> /// Only sorted on insertion /// </summary> public void Add(SystemInfo system) { if (system == null) { throw new ArgumentNullException(nameof(system)); } if (system.Type != _type) { return; } if (freeSpace.Count > 0) { _next = freeSpace.Dequeue(); } _systemCache[_next] = system; _count++; if (_start == -1) { _entries[_next] = new Entry(system.RunRecurrenceInterval, _next); _start = _end = _next; _rrStart = _rrEnd = _runRecurrences.Count; _runRecurrences.Add(new RREntry(_runRecurrences.Count, system.RunRecurrenceInterval, _next)); _top++; _next = _top; return; } int entry = FindPreviousEntry(system, out RREntry rr); if (entry == -1) { Entry start = _entries[_start]; if (start.RunRecurrence != system.RunRecurrenceInterval) { if (rr.Prev == -1) { _rrStart = _runRecurrences.Count; } else { RREntry rrprev = _runRecurrences[rr.Prev]; rrprev.Next = _runRecurrences.Count; _runRecurrences[rr.Prev] = rrprev; } _runRecurrences.Add(new RREntry(_runRecurrences.Count, system.RunRecurrenceInterval, _next, rr.Index, rr.Prev)); rr.Prev = _runRecurrences.Count - 1; } else { rr.Start = _next; } _runRecurrences[rr.Index] = rr; _entries[_next] = new Entry(system.RunRecurrenceInterval, _next, _start); _start = _next; start.PrevEntry = _next; _entries[start.CacheIndex] = start; if (freeSpace.Count == 0) { if (_next == _top) { _top++; } _next = _top; } else { _next = freeSpace.Dequeue(); } return; } if (entry == -2) { Entry end = _entries[_end]; if (end.RunRecurrence != system.RunRecurrenceInterval) { _runRecurrences.Add(new RREntry(_runRecurrences.Count, system.RunRecurrenceInterval, _next, rr.Next, rr.Index)); if (rr.Next == -1) { _rrEnd = _runRecurrences.Count - 1; } rr.Next = _runRecurrences.Count - 1; _runRecurrences[rr.Index] = rr; } _entries[_next] = new Entry(system.RunRecurrenceInterval, _next, -1, _end); _end = _next; end.NextEntry = _next; _entries[end.CacheIndex] = end; if (freeSpace.Count == 0) { if (_next == _top) { _top++; } _next = _top; } else { _next = freeSpace.Dequeue(); } return; } Entry prev = _entries[entry]; if (rr.RunRecurrence != system.RunRecurrenceInterval) { if (rr.Prev != -1) { RREntry preRR = _runRecurrences[rr.Prev]; preRR.Next = _runRecurrences.Count; _runRecurrences[preRR.Index] = preRR; } else { _rrStart = _runRecurrences.Count; } _runRecurrences.Add(new RREntry(_runRecurrences.Count, system.RunRecurrenceInterval, _next, rr.Index, rr.Prev)); rr.Prev = _runRecurrences.Count - 1; _runRecurrences[rr.Index] = rr; } else if (rr.RunRecurrence != prev.RunRecurrence) { rr.Start = _next; _runRecurrences[rr.Index] = rr; } Entry next = _entries[prev.NextEntry]; prev.NextEntry = _next; next.PrevEntry = _next; _entries[_next] = new Entry(system.RunRecurrenceInterval, _next, next.CacheIndex, prev.CacheIndex); _entries[entry] = prev; _entries[next.CacheIndex] = next; if (freeSpace.Count == 0) { if (_next == _top) { _top++; } _next = _top; } else { _next = freeSpace.Dequeue(); } return; }