Wrr.js 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. var Class = require('./Class');
  2. var max = require('./max');
  3. var map = require('./map');
  4. var reduce = require('./reduce');
  5. var gcd = require('./gcd');
  6. var filter = require('./filter');
  7. exports = Class({
  8. initialize: function Wrr() {
  9. this._peers = [];
  10. },
  11. set: function(val, weight) {
  12. var peers = this._peers;
  13. var size = this.size;
  14. for (var i = 0; i < size; i++) {
  15. var peer = peers[i];
  16. if (peer.val === val) {
  17. peer.weight = weight;
  18. this._reset();
  19. return;
  20. }
  21. }
  22. peers.push({
  23. val: val,
  24. weight: weight
  25. });
  26. this._reset();
  27. },
  28. get: function(val) {
  29. var peers = this._peers;
  30. var size = this.size;
  31. for (var i = 0; i < size; i++) {
  32. var peer = peers[i];
  33. if (peer.val === val) {
  34. return peer.weight;
  35. }
  36. }
  37. },
  38. remove: function(val) {
  39. this._peers = filter(this._peers, function(peer) {
  40. return peer.val !== val;
  41. });
  42. this._reset();
  43. },
  44. next: function() {
  45. var peers = this._peers;
  46. var size = this.size;
  47. if (size === 0) return;
  48. while (true) {
  49. this._i = (this._i + 1) % size;
  50. if (this._i === 0) {
  51. this._cw = this._cw - this._gcdS;
  52. if (this._cw <= 0) {
  53. this._cw = this._maxS;
  54. }
  55. }
  56. if (this._cw === 0) return;
  57. if (peers[this._i].weight >= this._cw) {
  58. return peers[this._i].val;
  59. }
  60. }
  61. },
  62. clear: function() {
  63. this._peers = [];
  64. this._reset();
  65. },
  66. _reset: function() {
  67. var peers = this._peers;
  68. this.size = peers.length;
  69. var weights = map(peers, function(peer) {
  70. return peer.weight;
  71. });
  72. this._i = -1;
  73. this._cw = 0;
  74. this._maxS = max.apply(null, weights);
  75. this._gcdS = reduce(
  76. weights,
  77. function(prev, weight) {
  78. return gcd(prev, weight);
  79. },
  80. 0
  81. );
  82. }
  83. });
  84. module.exports = exports;