UNPKG

gemini-core

Version:

Utility which contains common modules for gemini and hermione

70 lines (54 loc) 1.93 kB
'use strict'; const _ = require('lodash'); const Promise = require('bluebird'); const debug = require('debug'); /** * Set implementation which allows to get and put an object * there only limited amout of times. After limit is reached * attempt to put an object there causes the object to be finalized. * * @constructor * @param {Number} useLimit number of times object can be popped from set * before finalizing. * @param {Function} finalize callback which will be called when value in * set needs to be finalized. */ module.exports = class LimitedUseSet { constructor(opts) { this._useCounts = new WeakMap(); this._useLimit = opts.useLimit; this._finalize = opts.finalize; this._formatItem = opts.formatItem || _.identity; this._objects = []; this.log = debug(`${opts.logNamespace}:pool:limited-use-set`); } push(value) { const formatedItem = this._formatItem(value); this.log(`push ${formatedItem}`); if (this._isOverLimit(value)) { this.log(`over limit, finalizing ${formatedItem}`); return this._finalize(value); } this.log(`under limit for ${formatedItem}`); this._objects.push(value); return Promise.resolve(); } _isOverLimit(value) { if (this._useLimit === 0) { return true; } return this._useCounts.has(value) && this._useCounts.get(value) >= this._useLimit; } pop() { if (this._objects.length === 0) { return null; } const result = this._objects.pop(); const useCount = this._useCounts.get(result) || 0; const formatedItem = this._formatItem(result); this.log(`popping ${formatedItem}`); this.log(`previous use count ${formatedItem}:${useCount}`); this._useCounts.set(result, useCount + 1); return result; } };