Skip to content
This repository has been archived by the owner on May 24, 2020. It is now read-only.

Commit

Permalink
adding object support
Browse files Browse the repository at this point in the history
  • Loading branch information
drora committed Jan 24, 2017
1 parent 0dc33a9 commit e0794d3
Show file tree
Hide file tree
Showing 4 changed files with 170 additions and 13 deletions.
11 changes: 9 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ performance. A new arrival that finds a friend already standing in line joins
him and his group. When the “leader” reaches the cashier, he buys tickets
for the entire group. It is assumed that the buying process is (almost) not
affected by the number of tickets purchased.
<http://www.math.tau.ac.il/~uriy/Papers/IQ-with-Priorities.pdf>

## Usage

Expand All @@ -26,8 +27,14 @@ To install: `npm install israeli-queue`
const IQ = require('israeli-queue');

let q1 = new IQ();
let q2 = new IQ();

q1.dequeue(); // []
q1.enqueue({o:"a"}); // [{"o":"a"}]
q1.enqueue({o:"c"}); // [{"o":"a"},{"o":"c"}]
q1.enqueue({o:"b"}, {o:"a"}); // [{"o":"a"},{"o":"b"},{"o":"c"}]

q1.peek(); // { o: 'a' }
q1.length(); // 3

## API

### *constructor*()
Expand Down
27 changes: 20 additions & 7 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,35 @@
'use strict';

const _ = require('lodash'),
hash = require('object-hash');

module.exports = class IQ {
constructor( queue = [], members = {}) {
this._queue = queue;
this._members = members;
}
enqueue(o, friend = false) {
this._members[o] = !!(this._members[o]) ? ++(this._members[o]) : 1;
if (friend && this._members[friend]) {
let index = (this._queue.indexOf(friend))+1;
this._queue.splice(index, 0, o);
return index+1;
const oKey = o?(typeof o==='object')?hash(o):o:false,
friendKey = friend?(typeof friend==='object')?hash(friend):friend:false;
this._members[oKey] = !!(this._members[oKey]) ? ++(this._members[oKey]) : 1;
if (friend && this._members[friendKey]) {
let index = (typeof friend==='object')?false:(this._queue.indexOf(friend))+1;
if (index) {
this._queue.splice(index, 0, o);
return index + 1;
}
index = _.findIndex(this._queue, (member) => {
return hash(member)==friendKey;
});
this._queue.splice(++index, 0, o);
return index;
}
return this._queue.push(o);
}
dequeue() {
let o = (this.length())?this._queue.shift():false;
o && (this._members[o] = (this._members[o]==1) ? this._members[o]=false : --(this._members[o]));
const o = (this.length())?this._queue.shift():false,
oKey = o?(typeof o==='object')?hash(o):o:false;
o && (this._members[oKey] = (this._members[oKey]==1) ? this._members[oKey]=false : --(this._members[oKey]));
return o;
}
peek() {
Expand Down
9 changes: 6 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "israeli-queue",
"version": "1.0.5",
"description": "The so called “Israeli Queue” is a single server polling system with batch service of an unlimited size, where the next queue to be visited is the one in which the first customer in line has been waiting for the longest time.",
"version": "1.1.0",
"description": "in-memory israeli-queue influenced by: http://www.math.tau.ac.il/~uriy/Papers/IQ-with-Priorities.pdf",
"main": "index.js",
"scripts": {
"test": "mocha"
Expand All @@ -12,7 +12,10 @@
"type": "git",
"url": "https://github.com/Sealights/israeli-queue.git"
},
"dependencies": {},
"dependencies": {
"lodash": "^4.17.4",
"object-hash": "^1.1.5"
},
"devDependencies": {
"chai": "^3.5.0",
"mocha": "^3.2.0"
Expand Down
136 changes: 135 additions & 1 deletion test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const chai = require('chai'),
chai.should();

describe('IQ', () => {
describe('#core', () => {
describe('#primitive', () => {
let queue;

beforeEach(() => {
Expand Down Expand Up @@ -135,6 +135,140 @@ describe('IQ', () => {
queue.peek().should.equal(2);
queue.dequeue().should.equal(2);

queue.length().should.equal(0);
queue.peek().should.equal(false);
queue.dequeue().should.equal(false);
});
});
describe('#object', () => {
let queue;

beforeEach(() => {
queue = new IQ();
});

it('one simple member', () => {
queue.enqueue({o:1});

queue.length().should.equal(1);
queue.peek().should.eql({o:1});
queue.dequeue().should.eql({o:1});

queue.length().should.equal(0);
queue.peek().should.equal(false);
queue.dequeue().should.equal(false);
});

it('many simple members', () => {
queue.enqueue({o:1});
queue.enqueue({o:2});

queue.length().should.equal(2);
queue.peek().should.eql({o:1});
queue.dequeue().should.eql({o:1});

queue.length().should.equal(1);
queue.peek().should.eql({o:2});
queue.dequeue().should.eql({o:2});

queue.length().should.equal(0);
queue.peek().should.equal(false);
queue.dequeue().should.equal(false);
});

it('many israeli members', () => {
queue.enqueue({o:1},{o:2});
queue.enqueue({o:2},{o:3});
queue.enqueue({o:'a'}, {o:1});
queue.enqueue({o:'b'}, {o:'a'});

queue.length().should.equal(4);
queue.peek().should.eql({o:1});
queue.dequeue().should.eql({o:1});

queue.length().should.equal(3);
queue.peek().should.eql({o:'a'});
queue.dequeue().should.eql({o:'a'});

queue.length().should.equal(2);
queue.peek().should.eql({o:'b'});
queue.dequeue().should.eql({o:'b'});

queue.length().should.equal(1);
queue.peek().should.eql({o:2});
queue.dequeue().should.eql({o:2});

queue.length().should.equal(0);
queue.peek().should.equal(false);
queue.dequeue().should.equal(false);

// replay to test dequeue went clean

queue.enqueue({o:1},{o:2});
queue.enqueue({o:2},{o:3});
queue.enqueue({o:'a'}, {o:1});
queue.enqueue({o:'b'}, {o:'a'});

queue.length().should.equal(4);
queue.peek().should.eql({o:1});
queue.dequeue().should.eql({o:1});

queue.enqueue({o:'c'}, {o:1});

queue.length().should.equal(4);
queue.peek().should.eql({o:'a'});
queue.dequeue().should.eql({o:'a'});

queue.length().should.equal(3);
queue.peek().should.eql({o:'b'});
queue.dequeue().should.eql({o:'b'});

queue.length().should.equal(2);
queue.peek().should.eql({o:2});
queue.dequeue().should.eql({o:2});

queue.length().should.equal(1);
queue.peek().should.eql({o:'c'});
queue.dequeue().should.eql({o:'c'});

queue.length().should.equal(0);
queue.peek().should.equal(false);
queue.dequeue().should.equal(false);
});

it('israeli members with duplication', () => {
queue.enqueue({o:1});
queue.enqueue({o:2});
queue.enqueue({o:2});
queue.enqueue({o:3}, {o:2});

queue.length().should.equal(4);
queue.peek().should.eql({o:1});
queue.dequeue().should.eql({o:1});

queue.length().should.equal(3);
queue.peek().should.eql({o:2});
queue.dequeue().should.eql({o:2});

queue.length().should.equal(2);
queue.peek().should.eql({o:3});
queue.dequeue().should.eql({o:3});

queue.enqueue({o:1});
queue.enqueue({o:2});

queue.length().should.equal(3);
queue.peek().should.eql({o:2});
queue.dequeue().should.eql({o:2});

queue.length().should.equal(2);
queue.peek().should.eql({o:1});
queue.dequeue().should.eql({o:1});

queue.length().should.equal(1);
queue.peek().should.eql({o:2});
queue.dequeue().should.eql({o:2});

queue.length().should.equal(0);
queue.peek().should.equal(false);
queue.dequeue().should.equal(false);
Expand Down

0 comments on commit e0794d3

Please sign in to comment.