| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258 |
- <?php
- /**
- * @category Thinkopen
- * @package Mooses_Mongodb_Mongo
- * @copyright Thinkopen s.r.l.
- * @license New BSD License
- * @author Coen Hyde
- */
- class Mooses_Mongodb_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 Mooses_Mongodb_Mongo_Connection $connection
- * @param int $weight
- */
- public function addNode(Mooses_Mongodb_Mongo_Connection $connection, $weight = 1)
- {
- $this->_nodes[] = $connection;
- $this->_weights[] = (int) $weight;
- }
-
- /**
- * Select a node from the connection stack.
- *
- * @return Mooses_Mongodb_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 Mooses_Mongodb_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 'Thinkopen/Mongodb/Mongo/Exception.php';
- throw new Mooses_Mongodb_Mongo_Exception("Position must be numeric");
- }
-
- $this->_position = $position;
-
- if (!$this->valid()) {
- throw new OutOfBoundsException("invalid seek position ($position)");
- }
- }
-
- /**
- * Get the current connection
- *
- * @return Mooses_Mongodb_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 Mooses_Mongodb_Mongo_Connection $offset
- * @param $connection
- */
- public function offsetSet($offset, $connection)
- {
- if (!is_numeric($offset)) {
- require_once 'Thinkopen/Mongodb/Mongo/Exception.php';
- throw new Mooses_Mongodb_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]);
- }
- }
|