/library/Shanty/Mongo/Connection/Stack.php
PHP | 258 lines | 127 code | 30 blank | 101 comment | 12 complexity | aa41a52983eed24d0ff8d64145af3069 MD5 | raw file
- <?php
- /**
- * @category Shanty
- * @package Shanty_Mongo
- * @copyright Shanty Tech Pty Ltd
- * @license New BSD License
- * @author Coen Hyde
- */
- class Shanty_Mongo_Connection_Stack implements SeekableIterator, Countable, ArrayAccess
- {
- protected $_position = 0;
- protected $_nodes = array();
- protected $_weights = array();
- protected $_options = array(
- 'cacheConnectionSelection' => true
- );
- protected $_cacheConnectionSelection = true;
- protected $_cachedConnection = null;
-
- /**
- * Get an option
- *
- * @param string $option
- */
- public function getOption($option)
- {
- if (!array_key_exists($option, $this->_options)) {
- return null;
- }
-
- return $this->_options[$option];
- }
-
- /**
- * Set an option
- *
- * @param string $option
- * @param mixed $value
- */
- public function setOption($option, $value)
- {
- $this->_options[$option] = $value;
- }
-
- /**
- * Set Options
- *
- * @param array $options
- */
- public function setOptions(array $options)
- {
- $this->_options = array_merge($this->_options, $options);
- }
-
- /**
- * Add node to connection stack
- *
- * @param Shanty_Mongo_Connection $connection
- * @param int $weight
- */
- public function addNode(Shanty_Mongo_Connection $connection, $weight = 1)
- {
- $this->_nodes[] = $connection;
- $this->_weights[] = (int) $weight;
- }
-
- /**
- * Select a node from the connection stack.
- *
- * @return Shanty_Mongo_Connection
- */
- public function selectNode()
- {
- if (count($this) == 0) {
- // no nodes to select from
- return null;
- }
-
- // Return the cached connection if available
- if ($this->cacheConnectionSelection() && $this->hasCachedConnection()) {
- return $this->getCachedConnection();
- }
-
- // Select a new connection
- $r = mt_rand(1,array_sum($this->_weights));
- $offset = 0;
- foreach ($this->_weights as $k => $weight) {
- $offset += $weight;
- if ($r <= $offset) {
- $connection = $this->_nodes[$k];
- break;
- }
- }
-
- // Cache the connection for later use
- if ($this->cacheConnectionSelection()) {
- $this->_cachedConnection = $connection;
- }
-
- return $connection;
- }
-
- /**
- * Determine if this connection stack has a cached connection
- *
- * @return boolean
- */
- public function hasCachedConnection()
- {
- return !is_null($this->_cachedConnection);
- }
-
- /**
- * Get the cached connection
- *
- * @return Shanty_Mongo_Connection
- */
- public function getCachedConnection()
- {
- return $this->_cachedConnection;
- }
-
- /**
- * Get or set the flag to determine if the first connection selection should be cached
- *
- * @param boolean $value
- */
- public function cacheConnectionSelection($value = null)
- {
- if (!is_null($value)) {
- $this->_options['cacheConnectionSelection'] = (boolean) $value;
- }
-
- return $this->_options['cacheConnectionSelection'];
- }
-
- /**
- * Seek to a particular connection
- *
- * @param $position
- */
- public function seek($position)
- {
- if (!is_numeric($position)) {
- require_once 'Shanty/Mongo/Exception.php';
- throw new Shanty_Mongo_Exception("Position must be numeric");
- }
-
- $this->_position = $position;
-
- if (!$this->valid()) {
- throw new OutOfBoundsException("invalid seek position ($position)");
- }
- }
-
- /**
- * Get the current connection
- *
- * @return Shanty_Mongo_Connection
- */
- public function current()
- {
- return $this->_nodes[$this->_position];
- }
-
- /**
- * Get teh current key
- *
- * @return int
- */
- public function key()
- {
- return $this->_position;
- }
-
- /**
- * Move the pointer to the next connection
- */
- public function next()
- {
- $this->_position +=1;
- }
-
- /**
- * Rewind the pointer to the begining of the stack
- */
- public function rewind()
- {
- $this->_position = 0;
- }
-
- /**
- * Is the location of the current pointer valid
- */
- public function valid()
- {
- return $this->offsetExists($this->_position);
- }
-
- /**
- * Count all the connections
- */
- public function count()
- {
- return count($this->_nodes);
- }
-
- /**
- * Test if an offset exists
- *
- * @param int $offset
- */
- public function offsetExists($offset)
- {
- return array_key_exists($offset, $this->_nodes);
- }
-
- /**
- * Get an offset
- *
- * @param int $offset
- */
- public function offsetGet($offset)
- {
- if (!$this->offsetExists($offset)) return null;
-
- return $this->_nodes[$offset];
- }
-
- /**
- * Set an offset
- *
- * @param Shanty_Mongo_Connection $offset
- * @param $connection
- */
- public function offsetSet($offset, $connection)
- {
- if (!is_numeric($offset)) {
- require_once 'Shanty/Mongo/Exception.php';
- throw new Shanty_Mongo_Exception("Offset must be numeric");
- }
-
- $this->_nodes[$offset] = $connection;
- $this->_weights[$offset] = 1;
- }
-
- /**
- * Unset an offset
- *
- * @param int $offset
- */
- public function offsetUnset($offset)
- {
- unset($this->_nodes[$offset]);
- unset($this->_weights[$offset]);
- }
- }