Chromium Code Reviews| Index: third_party/WebKit/Source/core/streams/SimpleQueue.js |
| diff --git a/third_party/WebKit/Source/core/streams/SimpleQueue.js b/third_party/WebKit/Source/core/streams/SimpleQueue.js |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..cede7552dfac836493b9b31dad65f8ae7ac6b6c4 |
| --- /dev/null |
| +++ b/third_party/WebKit/Source/core/streams/SimpleQueue.js |
| @@ -0,0 +1,91 @@ |
| +// Copyright 2016 The Chromium Authors. All rights reserved. |
|
yhirano
2017/03/17 13:56:45
2017
Adam Rice
2017/03/17 14:02:08
Done.
|
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +// Queue implementation used by ReadableStream and WritableStream. |
| + |
| +(function(global, binding, v8) { |
| + 'use strict'; |
| + |
| + // Simple queue structure. Avoids scalability issues with using |
| + // InternalPackedArray directly by using multiple arrays in a linked list and |
| + // keeping the array size bounded. |
| + const QUEUE_MAX_ARRAY_SIZE = 16384; |
| + class SimpleQueue { |
| + constructor() { |
| + this.front = { |
| + elements: new v8.InternalPackedArray(), |
| + next: undefined, |
| + }; |
| + this.back = this.front; |
| + // The cursor is used to avoid calling InternalPackedArray.shift(). |
| + this.cursor = 0; |
| + this.size = 0; |
| + } |
| + |
| + get length() { |
| + return this.size; |
| + } |
| + |
| + push(element) { |
| + ++this.size; |
| + if (this.back.elements.length === QUEUE_MAX_ARRAY_SIZE) { |
| + const oldBack = this.back; |
| + this.back = { |
| + elements: new v8.InternalPackedArray(), |
| + next: undefined, |
| + }; |
| + oldBack.next = this.back; |
| + } |
| + this.back.elements.push(element); |
| + } |
| + |
| + shift() { |
| + // assert(this.size > 0); |
| + --this.size; |
| + if (this.front.elements.length === this.cursor) { |
| + // assert(this.cursor === QUEUE_MAX_ARRAY_SIZE); |
| + // assert(this.front.next !== undefined); |
| + this.front = this.front.next; |
| + this.cursor = 0; |
| + } |
| + const element = this.front.elements[this.cursor]; |
| + // Permit shifted element to be garbage collected. |
| + this.front.elements[this.cursor] = undefined; |
| + ++this.cursor; |
| + |
| + return element; |
| + } |
| + |
| + forEach(callback) { |
| + let i = this.cursor; |
| + let node = this.front; |
| + let elements = node.elements; |
| + while (i !== elements.length || node.next !== undefined) { |
| + if (i === elements.length) { |
| + // assert(node.next !== undefined); |
| + // assert(i === QUEUE_MAX_ARRAY_SIZE); |
| + node = node.next; |
| + elements = node.elements; |
| + i = 0; |
| + } |
| + callback(elements[i]); |
| + ++i; |
| + } |
| + } |
| + |
| + // Return the element that would be returned if shift() was called now, |
| + // without modifying the queue. |
| + peek() { |
| + // assert(this.size > 0); |
| + if (this.front.elements.length === this.cursor) { |
| + // assert(this.cursor === QUEUE_MAX_ARRAY_SIZE) |
| + // assert(this.front.next !== undefined); |
| + return this.front.next.elements[0]; |
| + } |
| + return this.front.elements[this.cursor]; |
| + } |
| + } |
| + |
| + binding.SimpleQueue = SimpleQueue; |
| +}); |