PageRenderTime 42ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/library/Shanty/Mongo/Connection/Stack.php

https://bitbucket.org/ilyabazhenov/speakplace
PHP | 258 lines | 127 code | 30 blank | 101 comment | 12 complexity | aa41a52983eed24d0ff8d64145af3069 MD5 | raw file
  1. <?php
  2. /**
  3. * @category Shanty
  4. * @package Shanty_Mongo
  5. * @copyright Shanty Tech Pty Ltd
  6. * @license New BSD License
  7. * @author Coen Hyde
  8. */
  9. class Shanty_Mongo_Connection_Stack implements SeekableIterator, Countable, ArrayAccess
  10. {
  11. protected $_position = 0;
  12. protected $_nodes = array();
  13. protected $_weights = array();
  14. protected $_options = array(
  15. 'cacheConnectionSelection' => true
  16. );
  17. protected $_cacheConnectionSelection = true;
  18. protected $_cachedConnection = null;
  19. /**
  20. * Get an option
  21. *
  22. * @param string $option
  23. */
  24. public function getOption($option)
  25. {
  26. if (!array_key_exists($option, $this->_options)) {
  27. return null;
  28. }
  29. return $this->_options[$option];
  30. }
  31. /**
  32. * Set an option
  33. *
  34. * @param string $option
  35. * @param mixed $value
  36. */
  37. public function setOption($option, $value)
  38. {
  39. $this->_options[$option] = $value;
  40. }
  41. /**
  42. * Set Options
  43. *
  44. * @param array $options
  45. */
  46. public function setOptions(array $options)
  47. {
  48. $this->_options = array_merge($this->_options, $options);
  49. }
  50. /**
  51. * Add node to connection stack
  52. *
  53. * @param Shanty_Mongo_Connection $connection
  54. * @param int $weight
  55. */
  56. public function addNode(Shanty_Mongo_Connection $connection, $weight = 1)
  57. {
  58. $this->_nodes[] = $connection;
  59. $this->_weights[] = (int) $weight;
  60. }
  61. /**
  62. * Select a node from the connection stack.
  63. *
  64. * @return Shanty_Mongo_Connection
  65. */
  66. public function selectNode()
  67. {
  68. if (count($this) == 0) {
  69. // no nodes to select from
  70. return null;
  71. }
  72. // Return the cached connection if available
  73. if ($this->cacheConnectionSelection() && $this->hasCachedConnection()) {
  74. return $this->getCachedConnection();
  75. }
  76. // Select a new connection
  77. $r = mt_rand(1,array_sum($this->_weights));
  78. $offset = 0;
  79. foreach ($this->_weights as $k => $weight) {
  80. $offset += $weight;
  81. if ($r <= $offset) {
  82. $connection = $this->_nodes[$k];
  83. break;
  84. }
  85. }
  86. // Cache the connection for later use
  87. if ($this->cacheConnectionSelection()) {
  88. $this->_cachedConnection = $connection;
  89. }
  90. return $connection;
  91. }
  92. /**
  93. * Determine if this connection stack has a cached connection
  94. *
  95. * @return boolean
  96. */
  97. public function hasCachedConnection()
  98. {
  99. return !is_null($this->_cachedConnection);
  100. }
  101. /**
  102. * Get the cached connection
  103. *
  104. * @return Shanty_Mongo_Connection
  105. */
  106. public function getCachedConnection()
  107. {
  108. return $this->_cachedConnection;
  109. }
  110. /**
  111. * Get or set the flag to determine if the first connection selection should be cached
  112. *
  113. * @param boolean $value
  114. */
  115. public function cacheConnectionSelection($value = null)
  116. {
  117. if (!is_null($value)) {
  118. $this->_options['cacheConnectionSelection'] = (boolean) $value;
  119. }
  120. return $this->_options['cacheConnectionSelection'];
  121. }
  122. /**
  123. * Seek to a particular connection
  124. *
  125. * @param $position
  126. */
  127. public function seek($position)
  128. {
  129. if (!is_numeric($position)) {
  130. require_once 'Shanty/Mongo/Exception.php';
  131. throw new Shanty_Mongo_Exception("Position must be numeric");
  132. }
  133. $this->_position = $position;
  134. if (!$this->valid()) {
  135. throw new OutOfBoundsException("invalid seek position ($position)");
  136. }
  137. }
  138. /**
  139. * Get the current connection
  140. *
  141. * @return Shanty_Mongo_Connection
  142. */
  143. public function current()
  144. {
  145. return $this->_nodes[$this->_position];
  146. }
  147. /**
  148. * Get teh current key
  149. *
  150. * @return int
  151. */
  152. public function key()
  153. {
  154. return $this->_position;
  155. }
  156. /**
  157. * Move the pointer to the next connection
  158. */
  159. public function next()
  160. {
  161. $this->_position +=1;
  162. }
  163. /**
  164. * Rewind the pointer to the begining of the stack
  165. */
  166. public function rewind()
  167. {
  168. $this->_position = 0;
  169. }
  170. /**
  171. * Is the location of the current pointer valid
  172. */
  173. public function valid()
  174. {
  175. return $this->offsetExists($this->_position);
  176. }
  177. /**
  178. * Count all the connections
  179. */
  180. public function count()
  181. {
  182. return count($this->_nodes);
  183. }
  184. /**
  185. * Test if an offset exists
  186. *
  187. * @param int $offset
  188. */
  189. public function offsetExists($offset)
  190. {
  191. return array_key_exists($offset, $this->_nodes);
  192. }
  193. /**
  194. * Get an offset
  195. *
  196. * @param int $offset
  197. */
  198. public function offsetGet($offset)
  199. {
  200. if (!$this->offsetExists($offset)) return null;
  201. return $this->_nodes[$offset];
  202. }
  203. /**
  204. * Set an offset
  205. *
  206. * @param Shanty_Mongo_Connection $offset
  207. * @param $connection
  208. */
  209. public function offsetSet($offset, $connection)
  210. {
  211. if (!is_numeric($offset)) {
  212. require_once 'Shanty/Mongo/Exception.php';
  213. throw new Shanty_Mongo_Exception("Offset must be numeric");
  214. }
  215. $this->_nodes[$offset] = $connection;
  216. $this->_weights[$offset] = 1;
  217. }
  218. /**
  219. * Unset an offset
  220. *
  221. * @param int $offset
  222. */
  223. public function offsetUnset($offset)
  224. {
  225. unset($this->_nodes[$offset]);
  226. unset($this->_weights[$offset]);
  227. }
  228. }