Queue.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. import defineProperties from './defineProperties.js';
  2. /**
  3. * A queue that can enqueue items at the end, and dequeue items from the front.
  4. *
  5. * @alias Queue
  6. * @constructor
  7. */
  8. function Queue() {
  9. this._array = [];
  10. this._offset = 0;
  11. this._length = 0;
  12. }
  13. defineProperties(Queue.prototype, {
  14. /**
  15. * The length of the queue.
  16. *
  17. * @memberof Queue.prototype
  18. *
  19. * @type {Number}
  20. * @readonly
  21. */
  22. length : {
  23. get : function() {
  24. return this._length;
  25. }
  26. }
  27. });
  28. /**
  29. * Enqueues the specified item.
  30. *
  31. * @param {*} item The item to enqueue.
  32. */
  33. Queue.prototype.enqueue = function(item) {
  34. this._array.push(item);
  35. this._length++;
  36. };
  37. /**
  38. * Dequeues an item. Returns undefined if the queue is empty.
  39. *
  40. * @returns {*} The the dequeued item.
  41. */
  42. Queue.prototype.dequeue = function() {
  43. if (this._length === 0) {
  44. return undefined;
  45. }
  46. var array = this._array;
  47. var offset = this._offset;
  48. var item = array[offset];
  49. array[offset] = undefined;
  50. offset++;
  51. if ((offset > 10) && (offset * 2 > array.length)) {
  52. //compact array
  53. this._array = array.slice(offset);
  54. offset = 0;
  55. }
  56. this._offset = offset;
  57. this._length--;
  58. return item;
  59. };
  60. /**
  61. * Returns the item at the front of the queue. Returns undefined if the queue is empty.
  62. *
  63. * @returns {*} The item at the front of the queue.
  64. */
  65. Queue.prototype.peek = function() {
  66. if (this._length === 0) {
  67. return undefined;
  68. }
  69. return this._array[this._offset];
  70. };
  71. /**
  72. * Check whether this queue contains the specified item.
  73. *
  74. * @param {*} item The item to search for.
  75. */
  76. Queue.prototype.contains = function(item) {
  77. return this._array.indexOf(item) !== -1;
  78. };
  79. /**
  80. * Remove all items from the queue.
  81. */
  82. Queue.prototype.clear = function() {
  83. this._array.length = this._offset = this._length = 0;
  84. };
  85. /**
  86. * Sort the items in the queue in-place.
  87. *
  88. * @param {Queue~Comparator} compareFunction A function that defines the sort order.
  89. */
  90. Queue.prototype.sort = function(compareFunction) {
  91. if (this._offset > 0) {
  92. //compact array
  93. this._array = this._array.slice(this._offset);
  94. this._offset = 0;
  95. }
  96. this._array.sort(compareFunction);
  97. };
  98. /**
  99. * A function used to compare two items while sorting a queue.
  100. * @callback Queue~Comparator
  101. *
  102. * @param {*} a An item in the array.
  103. * @param {*} b An item in the array.
  104. * @returns {Number} Returns a negative value if <code>a</code> is less than <code>b</code>,
  105. * a positive value if <code>a</code> is greater than <code>b</code>, or
  106. * 0 if <code>a</code> is equal to <code>b</code>.
  107. *
  108. * @example
  109. * function compareNumbers(a, b) {
  110. * return a - b;
  111. * }
  112. */
  113. export default Queue;