Squiz Matrix  4.12.2
 All Data Structures Namespaces Functions Variables Pages
DSNPool.inc
1 <?php
13 require_once dirname(__FILE__).'/DSN.inc';
14 
23 class DSNPool
24 {
25 
26 
32  private $_pool;
33 
40  private $_currentIndex = -1;
41 
42 
49  public function __construct(Array $dsn_arr)
50  {
51  $this->_pool = Array();
52  foreach ($dsn_arr as $dsn) {
53  $this->_pool[] = new DSN($dsn);
54  }
55 
56  }//end constructor
57 
58 
67  public function registerFailureDSN($index = NULL)
68  {
69  // If there is no index passed in, use the current index
70  if (is_null($index)) {
71  $index = $this->_currentIndex;
72  }
73 
74  if (isset($this->_pool[$index])) {
75  $this->_pool[$index]->setFailure(TRUE);
76  }
77 
78  }//end registerFailureDSN()
79 
80 
89  public function getDSNFromIndex($index = -1)
90  {
91  // It is unlikely to happen but we reset the current index if the index is invalid
92  if (!isset($this->_pool[$index])) {
93  $index = -1;
94  }
95 
96  // Set current index
97  $this->_currentIndex = $index;
98 
99  // If index = -1, we just want to reset the current index
100  if ($index == -1) {
101  return NULL;
102  }
103 
104  return $this->_pool[$index]->getDSN();
105 
106  }//end getDSNFromIndex()
107 
108 
116  public function getDSN()
117  {
118  // Get the weight and index arrays of the active DSN objects
119  $dsn_weights = $this->_getActiveDSNWeights();
120  // Get a weighted random index of the weight array
121  $weight_index = $this->_getWeightedRandomIndex($dsn_weights['weights']);
122  // Get the pool index from the active weight index
123  $index = $weight_index == -1 ? -1 : $dsn_weights['indexes'][$weight_index];
124 
125  return $this->getDSNFromIndex($index);
126 
127  }//end getDSN()
128 
129 
136  private function _getActiveDSNWeights()
137  {
138  $weights = Array();
139  $indexes = Array();
140  foreach ($this->_pool as $index => $dsn) {
141  if ($dsn->getFailure() !== TRUE) {
142  $weights[] = $dsn->getWeight();
143  $indexes[] = $index;
144  }
145  }
146 
147  return Array('weights' => $weights, 'indexes' => $indexes);
148 
149  }//end _getActiveDSNWeights()
150 
151 
163  private function _getWeightedRandomIndex($weights)
164  {
165  switch (count($weights)) {
166  case 0:
167  // The weight array is empty, return -1 to indicate the invalid index
168  return -1;
169  case 1:
170  // The weight array has one element, return the first index
171  return 0;
172  }
173 
174  // Get a random index number based on the weights. The bigger the weight of an array element, the bigger chance its index is selected.
175  $total_weights = array_sum($weights);
176  $random_number = mt_rand(1, $total_weights);
177  $n = 0;
178  foreach ($weights as $index => $weight) {
179  $n += $weight;
180  if ($n >= $random_number) {
181  break;
182  }
183  }
184 
185  return $index;
186 
187  }//end _getWeightedRandomIndex()
188 
189 
190 }//end class
191 
192 
193 ?>