summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Early <alexander.early@gmail.com>2017-04-08 20:34:34 -0700
committerGitHub <noreply@github.com>2017-04-08 20:34:34 -0700
commit8f58dbd1da3da50ee820a80c1d5088ca37a1d53a (patch)
treed4b1ce37f30b6dab380928bc889720cd8882dbd4
parent7f913b6d6a951bef9b287c0e186664b655b90c73 (diff)
parent07402822c3125a019c3060104eb7da54e0ccc5b6 (diff)
downloadasync-8f58dbd1da3da50ee820a80c1d5088ca37a1d53a.tar.gz
Merge pull request #1397 from caolan/linked-list-methods
queue.remove()
-rw-r--r--lib/internal/DoublyLinkedList.js28
-rw-r--r--lib/internal/queue.js3
-rw-r--r--lib/queue.js6
-rw-r--r--mocha_test/linked_list.js83
-rw-r--r--mocha_test/queue.js19
5 files changed, 138 insertions, 1 deletions
diff --git a/lib/internal/DoublyLinkedList.js b/lib/internal/DoublyLinkedList.js
index 79c3bb5..0e3b394 100644
--- a/lib/internal/DoublyLinkedList.js
+++ b/lib/internal/DoublyLinkedList.js
@@ -23,7 +23,10 @@ DLL.prototype.removeLink = function(node) {
return node;
}
-DLL.prototype.empty = DLL;
+DLL.prototype.empty = function () {
+ while(this.head) this.shift();
+ return this;
+};
DLL.prototype.insertAfter = function(node, newNode) {
newNode.prev = node;
@@ -60,3 +63,26 @@ DLL.prototype.shift = function() {
DLL.prototype.pop = function() {
return this.tail && this.removeLink(this.tail);
};
+
+DLL.prototype.toArray = function () {
+ var arr = Array(this.length);
+ var idx = 0;
+ var curr = this.head;
+ for(idx = 0; idx < this.length; idx++) {
+ arr[idx] = curr.data;
+ curr = curr.next;
+ }
+ return arr;
+}
+
+DLL.prototype.remove = function (testFn) {
+ var curr = this.head;
+ while(!!curr) {
+ var next = curr.next;
+ if (testFn(curr)) {
+ this.removeLink(curr);
+ }
+ curr = next;
+ }
+ return this;
+}
diff --git a/lib/internal/queue.js b/lib/internal/queue.js
index 2eb523a..e357447 100644
--- a/lib/internal/queue.js
+++ b/lib/internal/queue.js
@@ -101,6 +101,9 @@ export default function queue(worker, concurrency, payload) {
unshift: function (data, callback) {
_insert(data, true, callback);
},
+ remove: function (testFn) {
+ q._tasks.remove(testFn);
+ },
process: function () {
// Avoid trying to start too many processing operations. This can occur
// when callbacks resolve synchronously (#1267).
diff --git a/lib/queue.js b/lib/queue.js
index 906467c..2d0abb7 100644
--- a/lib/queue.js
+++ b/lib/queue.js
@@ -24,6 +24,12 @@ import wrapAsync from './internal/wrapAsync';
* task in the list. Invoke with `queue.push(task, [callback])`,
* @property {Function} unshift - add a new task to the front of the `queue`.
* Invoke with `queue.unshift(task, [callback])`.
+ * @property {Function} remove - remove items from the queue that match a test
+ * function. The test function will be passed an object with a `data` property,
+ * and a `priority` property, if this is a
+ * [priorityQueue]{@link module:ControlFlow.priorityQueue} object.
+ * Invoked with `queue.remove(testFn)`, where `testFn` is of the form
+ * `function ({data, priority}) {}` and returns a Boolean.
* @property {Function} saturated - a callback that is called when the number of
* running workers hits the `concurrency` limit, and further tasks will be
* queued.
diff --git a/mocha_test/linked_list.js b/mocha_test/linked_list.js
new file mode 100644
index 0000000..ab4b223
--- /dev/null
+++ b/mocha_test/linked_list.js
@@ -0,0 +1,83 @@
+var DLL = require('../lib/internal/DoublyLinkedList').default;
+var expect = require('chai').expect;
+
+describe('DoublyLinkedList', function () {
+ it('toArray', function() {
+ var list = new DLL();
+ expect(list.toArray()).to.eql([]);
+
+ for (var i = 0; i < 5; i++) {
+ list.push({data: i});
+ }
+ expect(list.toArray()).to.eql([0, 1, 2, 3, 4]);
+ });
+
+ it('remove', function() {
+ var list = new DLL();
+
+ for (var i = 0; i < 5; i++) {
+ list.push({data: i});
+ }
+
+ list.remove(function (node) {
+ return node.data === 3;
+ })
+
+ expect(list.toArray()).to.eql([0, 1, 2, 4]);
+ });
+
+ it('remove (head)', function() {
+ var list = new DLL();
+
+ for (var i = 0; i < 5; i++) {
+ list.push({data: i});
+ }
+
+ list.remove(function (node) {
+ return node.data === 0;
+ })
+
+ expect(list.toArray()).to.eql([1, 2, 3, 4]);
+ });
+
+ it('remove (tail)', function() {
+ var list = new DLL();
+
+ for (var i = 0; i < 5; i++) {
+ list.push({data: i});
+ }
+
+ list.remove(function (node) {
+ return node.data === 4;
+ })
+
+ expect(list.toArray()).to.eql([0, 1, 2, 3]);
+ });
+
+ it('remove (all)', function() {
+ var list = new DLL();
+
+ for (var i = 0; i < 5; i++) {
+ list.push({data: i});
+ }
+
+ list.remove(function (node) {
+ return node.data < 5;
+ })
+
+ expect(list.toArray()).to.eql([]);
+ });
+
+ it('empty', function() {
+ var list = new DLL();
+
+ for (var i = 0; i < 5; i++) {
+ list.push({data: i});
+ }
+
+ var empty = list.empty();
+
+ expect(list).to.equal(empty);
+ expect(list.toArray()).to.eql([]);
+ });
+});
diff --git a/mocha_test/queue.js b/mocha_test/queue.js
index cc72c52..77d4710 100644
--- a/mocha_test/queue.js
+++ b/mocha_test/queue.js
@@ -761,5 +761,24 @@ describe('queue', function(){
q.push('foo4', function () {calls.push('foo4 cb');});
});
});
+
+ it('remove', function(done) {
+ var result = [];
+ var q = async.queue(function(data, cb) {
+ result.push(data);
+ async.setImmediate(cb);
+ });
+
+ q.push([1, 2, 3, 4, 5]);
+
+ q.remove(function (node) {
+ return node.data === 3;
+ });
+
+ q.drain = function () {
+ expect(result).to.eql([1, 2, 4, 5]);
+ done();
+ }
+ });
});