OLD | NEW |
| (Empty) |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 import 'dart:collection'; | |
6 | |
7 import 'package:analysis_server/src/analysis_server.dart'; | |
8 import 'package:analysis_server/src/operation/operation.dart'; | |
9 import 'package:analyzer/src/generated/engine.dart'; | |
10 import 'package:analyzer/src/generated/source.dart'; | |
11 | |
12 /** | |
13 * A queue of operations in an [AnalysisServer]. | |
14 */ | |
15 class ServerOperationQueue { | |
16 final List<Queue<ServerOperation>> _queues = <Queue<ServerOperation>>[]; | |
17 | |
18 ServerOperationQueue() { | |
19 for (int i = 0; i < ServerOperationPriority.COUNT; i++) { | |
20 var queue = new DoubleLinkedQueue<ServerOperation>(); | |
21 _queues.add(queue); | |
22 } | |
23 } | |
24 | |
25 /** | |
26 * Returns `true` if there are no queued [ServerOperation]s. | |
27 */ | |
28 bool get isEmpty { | |
29 return _queues.every((queue) => queue.isEmpty); | |
30 } | |
31 | |
32 /** | |
33 * Adds the given operation to this queue. The exact position in the queue | |
34 * depends on the priority of the given operation relative to the priorities | |
35 * of the other operations in the queue. | |
36 */ | |
37 void add(ServerOperation operation) { | |
38 int queueIndex = operation.priority.ordinal; | |
39 Queue<ServerOperation> queue = _queues[queueIndex]; | |
40 // try to merge into an existing operation | |
41 for (ServerOperation existingOperation in queue) { | |
42 if (existingOperation is MergeableOperation && | |
43 existingOperation.merge(operation)) { | |
44 return; | |
45 } | |
46 } | |
47 // add it | |
48 queue.addLast(operation); | |
49 } | |
50 | |
51 /** | |
52 * Removes all elements in the queue. | |
53 */ | |
54 void clear() { | |
55 for (Queue<ServerOperation> queue in _queues) { | |
56 queue.clear(); | |
57 } | |
58 } | |
59 | |
60 /** | |
61 * The given [context] has been removed, so all pending operations that refer | |
62 * to it should be removed from the queue. | |
63 */ | |
64 void contextRemoved(AnalysisContext context) { | |
65 for (Queue<ServerOperation> queue in _queues) { | |
66 queue.removeWhere((operation) => operation.context == context); | |
67 } | |
68 } | |
69 | |
70 /** | |
71 * Return the next operation to perform, or `null` if the queue is empty. | |
72 * This method does not change the queue. | |
73 */ | |
74 ServerOperation peek() { | |
75 for (Queue<ServerOperation> queue in _queues) { | |
76 if (!queue.isEmpty) { | |
77 return queue.first; | |
78 } | |
79 } | |
80 return null; | |
81 } | |
82 | |
83 /** | |
84 * Reschedules queued operations according their current priorities. | |
85 */ | |
86 void reschedule() { | |
87 // prepare all operations | |
88 List<ServerOperation> operations = <ServerOperation>[]; | |
89 for (Queue<ServerOperation> queue in _queues) { | |
90 operations.addAll(queue); | |
91 queue.clear(); | |
92 } | |
93 // add all operations | |
94 operations.forEach(add); | |
95 } | |
96 | |
97 /** | |
98 * The given [source] if about to changed. | |
99 */ | |
100 void sourceAboutToChange(Source source) { | |
101 for (Queue<ServerOperation> queue in _queues) { | |
102 queue.removeWhere((operation) { | |
103 if (operation is SourceSensitiveOperation) { | |
104 return operation.shouldBeDiscardedOnSourceChange(source); | |
105 } | |
106 return false; | |
107 }); | |
108 } | |
109 } | |
110 | |
111 /** | |
112 * Returns the next operation to perform or `null` if empty. | |
113 */ | |
114 ServerOperation take() { | |
115 for (Queue<ServerOperation> queue in _queues) { | |
116 if (!queue.isEmpty) { | |
117 return queue.removeFirst(); | |
118 } | |
119 } | |
120 return null; | |
121 } | |
122 | |
123 /** | |
124 * Returns an operation that satisfies the given [test] or `null`. | |
125 */ | |
126 ServerOperation takeIf(bool test(ServerOperation operation)) { | |
127 for (Queue<ServerOperation> queue in _queues) { | |
128 for (ServerOperation operation in queue) { | |
129 if (test(operation)) { | |
130 queue.remove(operation); | |
131 return operation; | |
132 } | |
133 } | |
134 } | |
135 return null; | |
136 } | |
137 } | |
OLD | NEW |