RingBuffer.php 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\Intl\Data\Util;
  11. use Symfony\Component\Intl\Exception\OutOfBoundsException;
  12. /**
  13. * Implements a ring buffer.
  14. *
  15. * A ring buffer is an array-like structure with a fixed size. If the buffer
  16. * is full, the next written element overwrites the first bucket in the buffer,
  17. * then the second and so on.
  18. *
  19. * @author Bernhard Schussek <bschussek@gmail.com>
  20. *
  21. * @internal
  22. */
  23. class RingBuffer implements \ArrayAccess
  24. {
  25. private $values = [];
  26. private $indices = [];
  27. private $cursor = 0;
  28. private $size;
  29. public function __construct(int $size)
  30. {
  31. $this->size = $size;
  32. }
  33. /**
  34. * {@inheritdoc}
  35. */
  36. public function offsetExists($key): bool
  37. {
  38. return isset($this->indices[$key]);
  39. }
  40. /**
  41. * {@inheritdoc}
  42. */
  43. public function offsetGet($key)
  44. {
  45. if (!isset($this->indices[$key])) {
  46. throw new OutOfBoundsException(sprintf('The index "%s" does not exist.', $key));
  47. }
  48. return $this->values[$this->indices[$key]];
  49. }
  50. /**
  51. * {@inheritdoc}
  52. */
  53. public function offsetSet($key, $value)
  54. {
  55. if (false !== ($keyToRemove = array_search($this->cursor, $this->indices))) {
  56. unset($this->indices[$keyToRemove]);
  57. }
  58. $this->values[$this->cursor] = $value;
  59. $this->indices[$key] = $this->cursor;
  60. $this->cursor = ($this->cursor + 1) % $this->size;
  61. }
  62. /**
  63. * {@inheritdoc}
  64. */
  65. public function offsetUnset($key)
  66. {
  67. if (isset($this->indices[$key])) {
  68. $this->values[$this->indices[$key]] = null;
  69. unset($this->indices[$key]);
  70. }
  71. }
  72. }