You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

86 lines
2.2 KiB

var Class = require('./Class');
var max = require('./max');
var map = require('./map');
var reduce = require('./reduce');
var gcd = require('./gcd');
var filter = require('./filter');
exports = Class({
initialize: function Wrr() {
this._peers = [];
},
set: function(val, weight) {
var peers = this._peers;
var size = this.size;
for (var i = 0; i < size; i++) {
var peer = peers[i];
if (peer.val === val) {
peer.weight = weight;
this._reset();
return;
}
}
peers.push({
val: val,
weight: weight
});
this._reset();
},
get: function(val) {
var peers = this._peers;
var size = this.size;
for (var i = 0; i < size; i++) {
var peer = peers[i];
if (peer.val === val) {
return peer.weight;
}
}
},
remove: function(val) {
this._peers = filter(this._peers, function(peer) {
return peer.val !== val;
});
this._reset();
},
next: function() {
var peers = this._peers;
var size = this.size;
if (size === 0) return;
while (true) {
this._i = (this._i + 1) % size;
if (this._i === 0) {
this._cw = this._cw - this._gcdS;
if (this._cw <= 0) {
this._cw = this._maxS;
}
}
if (this._cw === 0) return;
if (peers[this._i].weight >= this._cw) {
return peers[this._i].val;
}
}
},
clear: function() {
this._peers = [];
this._reset();
},
_reset: function() {
var peers = this._peers;
this.size = peers.length;
var weights = map(peers, function(peer) {
return peer.weight;
});
this._i = -1;
this._cw = 0;
this._maxS = max.apply(null, weights);
this._gcdS = reduce(
weights,
function(prev, weight) {
return gcd(prev, weight);
},
0
);
}
});
module.exports = exports;