HashTable.php 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. <?php
  2. namespace PhpOffice\PhpSpreadsheet;
  3. class HashTable
  4. {
  5. /**
  6. * HashTable elements.
  7. *
  8. * @var IComparable[]
  9. */
  10. protected $items = [];
  11. /**
  12. * HashTable key map.
  13. *
  14. * @var string[]
  15. */
  16. protected $keyMap = [];
  17. /**
  18. * Create a new \PhpOffice\PhpSpreadsheet\HashTable.
  19. *
  20. * @param IComparable[] $pSource Optional source array to create HashTable from
  21. *
  22. * @throws Exception
  23. */
  24. public function __construct($pSource = null)
  25. {
  26. if ($pSource !== null) {
  27. // Create HashTable
  28. $this->addFromSource($pSource);
  29. }
  30. }
  31. /**
  32. * Add HashTable items from source.
  33. *
  34. * @param IComparable[] $pSource Source array to create HashTable from
  35. *
  36. * @throws Exception
  37. */
  38. public function addFromSource(array $pSource = null)
  39. {
  40. // Check if an array was passed
  41. if ($pSource == null) {
  42. return;
  43. }
  44. foreach ($pSource as $item) {
  45. $this->add($item);
  46. }
  47. }
  48. /**
  49. * Add HashTable item.
  50. *
  51. * @param IComparable $pSource Item to add
  52. */
  53. public function add(IComparable $pSource)
  54. {
  55. $hash = $pSource->getHashCode();
  56. if (!isset($this->items[$hash])) {
  57. $this->items[$hash] = $pSource;
  58. $this->keyMap[count($this->items) - 1] = $hash;
  59. }
  60. }
  61. /**
  62. * Remove HashTable item.
  63. *
  64. * @param IComparable $pSource Item to remove
  65. */
  66. public function remove(IComparable $pSource)
  67. {
  68. $hash = $pSource->getHashCode();
  69. if (isset($this->items[$hash])) {
  70. unset($this->items[$hash]);
  71. $deleteKey = -1;
  72. foreach ($this->keyMap as $key => $value) {
  73. if ($deleteKey >= 0) {
  74. $this->keyMap[$key - 1] = $value;
  75. }
  76. if ($value == $hash) {
  77. $deleteKey = $key;
  78. }
  79. }
  80. unset($this->keyMap[count($this->keyMap) - 1]);
  81. }
  82. }
  83. /**
  84. * Clear HashTable.
  85. */
  86. public function clear()
  87. {
  88. $this->items = [];
  89. $this->keyMap = [];
  90. }
  91. /**
  92. * Count.
  93. *
  94. * @return int
  95. */
  96. public function count()
  97. {
  98. return count($this->items);
  99. }
  100. /**
  101. * Get index for hash code.
  102. *
  103. * @param string $pHashCode
  104. *
  105. * @return int Index
  106. */
  107. public function getIndexForHashCode($pHashCode)
  108. {
  109. return array_search($pHashCode, $this->keyMap);
  110. }
  111. /**
  112. * Get by index.
  113. *
  114. * @param int $pIndex
  115. *
  116. * @return IComparable
  117. */
  118. public function getByIndex($pIndex)
  119. {
  120. if (isset($this->keyMap[$pIndex])) {
  121. return $this->getByHashCode($this->keyMap[$pIndex]);
  122. }
  123. return null;
  124. }
  125. /**
  126. * Get by hashcode.
  127. *
  128. * @param string $pHashCode
  129. *
  130. * @return IComparable
  131. */
  132. public function getByHashCode($pHashCode)
  133. {
  134. if (isset($this->items[$pHashCode])) {
  135. return $this->items[$pHashCode];
  136. }
  137. return null;
  138. }
  139. /**
  140. * HashTable to array.
  141. *
  142. * @return IComparable[]
  143. */
  144. public function toArray()
  145. {
  146. return $this->items;
  147. }
  148. /**
  149. * Implement PHP __clone to create a deep clone, not just a shallow copy.
  150. */
  151. public function __clone()
  152. {
  153. $vars = get_object_vars($this);
  154. foreach ($vars as $key => $value) {
  155. if (is_object($value)) {
  156. $this->$key = clone $value;
  157. }
  158. }
  159. }
  160. }