Path: blob/trunk/third_party/closure/goog/async/workqueue.js
4500 views
/**1* @license2* Copyright The Closure Library Authors.3* SPDX-License-Identifier: Apache-2.04*/56goog.module('goog.async.WorkQueue');7goog.module.declareLegacyNamespace();89const FreeList = goog.require('goog.async.FreeList');10const {assert} = goog.require('goog.asserts');1112// TODO(johnlenz): generalize the WorkQueue if this is used by more13// than goog.async.run.141516/**17* A low GC workqueue. The key elements of this design:18* - avoids the need for goog.bind or equivalent by carrying scope19* - avoids the need for array reallocation by using a linked list20* - minimizes work entry objects allocation by recycling objects21* @final22* @struct23*/24class WorkQueue {25constructor() {26this.workHead_ = null;27this.workTail_ = null;28}2930/**31* @param {function()} fn32* @param {Object|null|undefined} scope33*/34add(fn, scope) {35const item = this.getUnusedItem_();36item.set(fn, scope);3738if (this.workTail_) {39this.workTail_.next = item;40this.workTail_ = item;41} else {42assert(!this.workHead_);43this.workHead_ = item;44this.workTail_ = item;45}46}4748/**49* @return {?WorkItem}50*/51remove() {52let item = null;5354if (this.workHead_) {55item = this.workHead_;56this.workHead_ = this.workHead_.next;57if (!this.workHead_) {58this.workTail_ = null;59}60item.next = null;61}62return item;63}6465/**66* @param {!WorkItem} item67*/68returnUnused(item) {69WorkQueue.freelist_.put(item);70}7172/**73* @return {!WorkItem}74* @private75*/76getUnusedItem_() {77return WorkQueue.freelist_.get();78}79}8081/** @define {number} The maximum number of entries to keep for recycling. */82WorkQueue.DEFAULT_MAX_UNUSED =83goog.define('goog.async.WorkQueue.DEFAULT_MAX_UNUSED', 100);8485/** @const @private {!FreeList<!WorkItem>} */86WorkQueue.freelist_ = new FreeList(87() => new WorkItem(), item => item.reset(), WorkQueue.DEFAULT_MAX_UNUSED);8889/**90* @final91* @struct92*/93class WorkItem {94constructor() {95/** @type {?function()} */96this.fn = null;97/** @type {?Object|null|undefined} */98this.scope = null;99/** @type {?WorkItem} */100this.next = null;101}102103/**104* @param {function()} fn105* @param {Object|null|undefined} scope106*/107set(fn, scope) {108this.fn = fn;109this.scope = scope;110this.next = null;111}112113/** Reset the work item so they don't prevent GC before reuse */114reset() {115this.fn = null;116this.scope = null;117this.next = null;118}119}120121exports = WorkQueue;122123124