diff --git a/index.js b/index.js index 4824381..b75fd4c 100644 --- a/index.js +++ b/index.js @@ -23,25 +23,21 @@ const CREAT = constants.O_CREAT class Pool { constructor (maxSize) { this.maxSize = maxSize - this.active = [] + this.active = new Set() } _onactive (file) { - // suspend a random one when the pool - if (this.active.length >= this.maxSize) { - const r = Math.floor(Math.random() * this.active.length) - this.active[r].suspend() + // suspend least recently inserted + if (this.active.size >= this.maxSize) { + const toSuspend = this.active[Symbol.iterator]().next().value + toSuspend.suspend() + this.active.delete(toSuspend) } - - file._pi = this.active.push(file) - 1 + this.active.add(file) } _oninactive (file) { - const head = this.active.pop() - if (head !== file) { - head._pi = file._pi - this.active[head._pi] = head - } + this.active.delete(file) } } diff --git a/test/basic.js b/test/basic.js index 10b0263..00baa0a 100644 --- a/test/basic.js +++ b/test/basic.js @@ -454,34 +454,36 @@ test('unlink on uncreated file does not reject', async function (t) { }) test('pool', function (t) { - t.plan(8) + const POOL_SIZE = 2 + const RAF_COUNT = 10 + + t.plan((RAF_COUNT * 2) + 2) - const pool = RAF.createPool(2) + const pool = RAF.createPool(POOL_SIZE) - const a = new RAF(gen(), { pool }) - const b = new RAF(gen(), { pool }) - const c = new RAF(gen(), { pool }) + const rafs = [] + let pending = RAF_COUNT + + for (let i = 0; i < RAF_COUNT; i++) { + const raf = new RAF(gen(), { pool }) + rafs.push(raf) + raf.write(0, Buffer.from('hello'), done) + } - a.write(0, Buffer.from('hello'), function (err) { + function done (err) { t.absent(err, 'no error') - b.write(0, Buffer.from('hello'), function (err) { - t.absent(err, 'no error') - c.write(0, Buffer.from('hello'), function (err) { - t.absent(err, 'no error') - setTimeout(function () { - t.is(pool.active.length, 2) - const all = [a, b, c] - t.is(all.filter(f => f.suspended).length, 1) - - for (const f of all) { - f.read(0, 5, function (_, buf) { - t.alike(buf, Buffer.from('hello')) - }) - } - }, 100) - }) - }) - }) + if (--pending !== 0) return + setTimeout(function () { + t.is(pool.active.size, POOL_SIZE) + t.is(rafs.filter(f => f.suspended).length, RAF_COUNT - POOL_SIZE) + + for (const f of rafs) { + f.read(0, 5, function (_, buf) { + t.alike(buf, Buffer.from('hello')) + }) + } + }, 100) + } }) test('readonly mode', function (t) {