ring_buffer.js 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. 'use strict';
  2. var RingBuffer = function(bufferSize) {
  3. this._bufferSize = bufferSize;
  4. this.clear();
  5. };
  6. RingBuffer.prototype.clear = function() {
  7. this._buffer = new Array(this._bufferSize);
  8. this._ringOffset = 0;
  9. this._ringSize = this._bufferSize;
  10. this._head = 0;
  11. this._tail = 0;
  12. this.length = 0;
  13. };
  14. RingBuffer.prototype.push = function(value) {
  15. var expandBuffer = false,
  16. expandRing = false;
  17. if (this._ringSize < this._bufferSize) {
  18. expandBuffer = (this._tail === 0);
  19. } else if (this._ringOffset === this._ringSize) {
  20. expandBuffer = true;
  21. expandRing = (this._tail === 0);
  22. }
  23. if (expandBuffer) {
  24. this._tail = this._bufferSize;
  25. this._buffer = this._buffer.concat(new Array(this._bufferSize));
  26. this._bufferSize = this._buffer.length;
  27. if (expandRing)
  28. this._ringSize = this._bufferSize;
  29. }
  30. this._buffer[this._tail] = value;
  31. this.length += 1;
  32. if (this._tail < this._ringSize) this._ringOffset += 1;
  33. this._tail = (this._tail + 1) % this._bufferSize;
  34. };
  35. RingBuffer.prototype.peek = function() {
  36. if (this.length === 0) return void 0;
  37. return this._buffer[this._head];
  38. };
  39. RingBuffer.prototype.shift = function() {
  40. if (this.length === 0) return void 0;
  41. var value = this._buffer[this._head];
  42. this._buffer[this._head] = void 0;
  43. this.length -= 1;
  44. this._ringOffset -= 1;
  45. if (this._ringOffset === 0 && this.length > 0) {
  46. this._head = this._ringSize;
  47. this._ringOffset = this.length;
  48. this._ringSize = this._bufferSize;
  49. } else {
  50. this._head = (this._head + 1) % this._ringSize;
  51. }
  52. return value;
  53. };
  54. module.exports = RingBuffer;