/// <summary>Add an element to the priority queue - O(log(n)) time operation.</summary> /// <param name="item">The item to be added to the queue</param> /// <returns>A node representing the item.</returns> public PriorityQueueNode <T> Enqueue(T item) { var result = new PriorityQueueNode <T>(item); Enqueue(result); return(result); }
// TODO: We will need a better API than exposing PriorityQueueNode<SchedulerEntry> before we can make this public. public void Add(Action simpleAction, int priority = 0, object token = null) { var schedulerEntryNode = new PriorityQueueNode <SchedulerEntry>(new SchedulerEntry(simpleAction, priority) { Token = token }); Schedule(schedulerEntryNode, ScheduleMode.Last); }
public MicroThread(Scheduler scheduler, MicroThreadFlags flags = MicroThreadFlags.None) { Id = Interlocked.Increment(ref globalCounterId); Scheduler = scheduler; ScheduledLinkedListNode = new PriorityQueueNode <SchedulerEntry>(new SchedulerEntry(this)); AllLinkedListNode = new LinkedListNode <MicroThread>(this); ScheduleMode = ScheduleMode.Last; Flags = flags; cancellationTokenSource = new CancellationTokenSource(); }
public void Schedule(PriorityQueueNode <SchedulerEntry> schedulerEntry, ScheduleMode scheduleMode) { var nextCounter = SchedulerCounter++; if (scheduleMode == ScheduleMode.First) { nextCounter = -nextCounter; } schedulerEntry.Value.SchedulerCounter = nextCounter; scheduledEntries.Enqueue(schedulerEntry); }
/// <summary>Add an element to the priority queue - O(log(n)) time operation.</summary> /// <param name="item">The item to be added to the queue</param> public void Enqueue(PriorityQueueNode <T> item) { if (item.Index != -1) { throw new InvalidOperationException("Item belongs to another PriorityNodeQueue."); } // We add the item to the end of the list (at the bottom of the // tree). Then, the heap-property could be violated between this element // and it's parent. If this is the case, we swap this element with the // parent (a safe operation to do since the element is known to be less // than it's parent). Now the element move one level up the tree. We repeat // this test with the element and it's new parent. The element, if lesser // than everybody else in the tree will eventually bubble all the way up // to the root of the tree (or the head of the list). It is easy to see // this will take log(N) time, since we are working with a balanced binary // tree. int n = items.Count; items.Add(item); item.Index = n; while (n != 0) { int p = n / 2; // This is the 'parent' of this item if (comparer.Compare(items[n].Value, items[p].Value) >= 0) { break; // Item >= parent } // Swap item and parent var tmp = items[n]; var tmp2 = items[p]; tmp2.Index = n; tmp.Index = p; items[n] = tmp2; items[p] = tmp; n = p; // And continue } }
/// <summary> /// Removes the specified item. /// </summary> /// <param name="item">The item to remove.</param> public void Remove(PriorityQueueNode <T> item) { int index = item.Index; if (index == -1) { return; } // The element to return is of course the first element in the array, // or the root of the tree. However, this will leave a 'hole' there. We // fill up this hole with the last element from the array. This will // break the heap property. So we bubble the element downwards by swapping // it with it's lower child until it reaches it's correct level. The lower // child (one of the orignal elements with index 1 or 2) will now be at the // head of the queue (root of the tree). int nMax = items.Count - 1; var itemMax = items[nMax]; itemMax.Index = index; var itemToRemove = items[index]; itemToRemove.Index = -1; items[index] = itemMax; items.RemoveAt(nMax); // Move the last element to the top int p = index; while (true) { // c is the child we want to swap with. If there // is no child at all, then the heap is balanced int c = p * 2; if (c >= nMax) { break; } // If the second child is smaller than the first, that's the one // we want to swap with this parent. if (c + 1 < nMax && comparer.Compare(items[c + 1].Value, items[c].Value) < 0) { c++; } // If the parent is already smaller than this smaller child, then // we are done if (comparer.Compare(items[p].Value, items[c].Value) <= 0) { break; } // Othewise, swap parent and child, and follow down the parent var tmp = items[p]; var tmp2 = items[c]; tmp.Index = c; tmp2.Index = p; items[p] = tmp2; items[c] = tmp; p = c; } item.Index = -1; }