annotate dwtx/core/internal/jobs/JobQueue.d @ 122:9d0585bcb7aa

Add core.jobs package
author Frank Benoit <benoit@tionex.de>
date Tue, 12 Aug 2008 02:34:21 +0200
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
122
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1 /*******************************************************************************
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
2 * Copyright (c) 2003, 2006 IBM Corporation and others.
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
3 * All rights reserved. This program and the accompanying materials
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
4 * are made available under the terms of the Eclipse Public License v1.0
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
5 * which accompanies this distribution, and is available at
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
6 * http://www.eclipse.org/legal/epl-v10.html
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
7 *
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
8 * Contributors:
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
9 * IBM - Initial API and implementation
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
10 * Port to the D programming language:
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
11 * Frank Benoit <benoit@tionex.de>
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
12 *******************************************************************************/
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
13 module dwtx.core.internal.jobs.JobQueue;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
14
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
15 import dwt.dwthelper.utils;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
16
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
17 import dwtx.core.runtime.Assert;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
18 import dwtx.core.runtime.IProgressMonitor;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
19 import dwtx.core.runtime.IStatus;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
20 import dwtx.core.runtime.Status;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
21
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
22 import dwtx.core.internal.jobs.InternalJob;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
23
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
24 /**
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
25 * A linked list based priority queue. Either the elements in the queue must
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
26 * implement Comparable, or a Comparator must be provided.
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
27 */
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
28 public class JobQueue {
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
29 /**
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
30 * The dummy entry sits between the head and the tail of the queue.
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
31 * dummy.previous() is the head, and dummy.next() is the tail.
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
32 */
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
33 private final InternalJob dummy;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
34
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
35 /**
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
36 * If true, conflicting jobs will be allowed to overtake others in the
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
37 * queue that have lower priority. If false, higher priority jumps can only
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
38 * move up the queue by overtaking jobs that they don't conflict with.
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
39 */
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
40 private bool allowConflictOvertaking;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
41
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
42 /**
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
43 * Create a new job queue.
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
44 */
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
45 public this(bool allowConflictOvertaking) {
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
46 //compareTo on dummy is never called
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
47 dummy = new class("Queue-Head") InternalJob {//$NON-NLS-1$
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
48 this( String name ){
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
49 super(name);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
50 }
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
51 public IStatus run(IProgressMonitor m) {
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
52 return Status.OK_STATUS;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
53 }
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
54 };
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
55 dummy.setNext(dummy);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
56 dummy.setPrevious(dummy);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
57 this.allowConflictOvertaking = allowConflictOvertaking;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
58 }
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
59
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
60 /**
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
61 * remove all elements
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
62 */
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
63 public void clear() {
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
64 dummy.setNext(dummy);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
65 dummy.setPrevious(dummy);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
66 }
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
67
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
68 /**
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
69 * Return and remove the element with highest priority, or null if empty.
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
70 */
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
71 public InternalJob dequeue() {
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
72 InternalJob toRemove = dummy.previous();
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
73 if (toRemove is dummy)
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
74 return null;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
75 return toRemove.remove();
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
76 }
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
77
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
78 /**
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
79 * Adds an item to the queue
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
80 */
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
81 public void enqueue(InternalJob newEntry) {
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
82 //assert new entry is does not already belong to some other data structure
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
83 Assert.isTrue(newEntry.next() is null);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
84 Assert.isTrue(newEntry.previous() is null);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
85 InternalJob tail = dummy.next();
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
86 //overtake lower priority jobs. Only overtake conflicting jobs if allowed to
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
87 while (canOvertake(newEntry, tail))
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
88 tail = tail.next();
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
89 //new entry is smaller than tail
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
90 final InternalJob tailPrevious = tail.previous();
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
91 newEntry.setNext(tail);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
92 newEntry.setPrevious(tailPrevious);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
93 tailPrevious.setNext(newEntry);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
94 tail.setPrevious(newEntry);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
95 }
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
96
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
97 /**
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
98 * Returns whether the new entry to overtake the existing queue entry.
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
99 * @param newEntry The entry to be added to the queue
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
100 * @param queueEntry The existing queue entry
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
101 */
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
102 private bool canOvertake(InternalJob newEntry, InternalJob queueEntry) {
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
103 //can never go past the end of the queue
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
104 if (queueEntry is dummy)
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
105 return false;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
106 //if the new entry was already in the wait queue, ensure it is re-inserted in correct position (bug 211799)
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
107 if (newEntry.getWaitQueueStamp() > 0 && newEntry.getWaitQueueStamp() < queueEntry.getWaitQueueStamp())
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
108 return true;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
109 //if the new entry has lower priority, there is no need to overtake the existing entry
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
110 if (queueEntry.compareTo(newEntry) >= 0)
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
111 return false;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
112 //the new entry has higher priority, but only overtake the existing entry if the queue allows it
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
113 return allowConflictOvertaking || !newEntry.isConflicting(queueEntry);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
114 }
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
115
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
116 /**
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
117 * Removes the given element from the queue.
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
118 */
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
119 public void remove(InternalJob toRemove) {
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
120 toRemove.remove();
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
121 //previous of toRemove might now bubble up
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
122 }
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
123
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
124 /**
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
125 * The given object has changed priority. Reshuffle the heap until it is
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
126 * valid.
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
127 */
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
128 public void resort(InternalJob entry) {
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
129 remove(entry);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
130 enqueue(entry);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
131 }
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
132
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
133 /**
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
134 * Returns true if the queue is empty, and false otherwise.
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
135 */
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
136 public bool isEmpty() {
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
137 return dummy.next() is dummy;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
138 }
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
139
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
140 /**
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
141 * Return greatest element without removing it, or null if empty
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
142 */
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
143 public InternalJob peek() {
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
144 return dummy.previous() is dummy ? null : dummy.previous();
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
145 }
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
146 }