ARedisSortedSet.php 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. <?php
  2. /**
  3. * Represents a redis sorted set.
  4. *
  5. * Redis Sorted Sets are, similarly to Redis Sets, non repeating collections of Strings. The difference is that every member of a Sorted Set is associated with score, that is used in order to take the sorted set ordered, from the smallest to the greatest score. While members are unique, scores may be repeated.
  6. *
  7. * <pre>
  8. * $set = new ARedisSortedSet("mySortedSet");
  9. * $set->add("myThing", 0.5);
  10. * $set->add("myOtherThing", 0.6);
  11. *
  12. * foreach($set as $key => $score) {
  13. * echo $key.":".$score."\n";
  14. * }
  15. * </pre>
  16. *
  17. * @author Charles Pick
  18. * @package packages.redis
  19. */
  20. class ARedisSortedSet extends ARedisIterableEntity {
  21. /**
  22. * Adds an item to the set
  23. * @param string $key the key to add
  24. * @param integer $value the score for this key
  25. * @return boolean true if the item was added, otherwise false
  26. */
  27. public function add($key, $value) {
  28. if (!$this->getConnection()->getClient()->zadd($this->name,$value, $key)) {
  29. return false;
  30. }
  31. $this->_data = null;
  32. $this->_count = null;
  33. return true;
  34. }
  35. /**
  36. * Removes an item from the set
  37. * @param string $key the item to remove
  38. * @return boolean true if the item was removed, otherwise false
  39. */
  40. public function remove($key) {
  41. if (!$this->getConnection()->getClient()->zrem($this->name,$key)) {
  42. return false;
  43. }
  44. $this->_data = null;
  45. $this->_count = null;
  46. return true;
  47. }
  48. /**
  49. * Gets the intersection between this set and the given set(s), stores it in a new set and returns it
  50. * @param ARedisSortedSet|string $destination the destination to store the result in
  51. * @param mixed $set The sets to compare to, either ARedisSortedSet instances or their names
  52. * @param array $weights the weights for the sets, if any
  53. * @return ARedisSortedSet a set that contains the intersection between this set and the given sets
  54. */
  55. public function interStore($destination, $set, $weights = null) {
  56. if ($destination instanceof ARedisSortedSet) {
  57. $destination->_count = null;
  58. $destination->_data = null;
  59. }
  60. else {
  61. $destination = new ARedisSortedSet($destination,$this->getConnection());
  62. }
  63. if (is_array($set)) {
  64. $sets = $set;
  65. }
  66. else {
  67. $sets = array($set);
  68. }
  69. foreach($sets as $n => $set) {
  70. if ($set instanceof ARedisSortedSet) {
  71. $sets[$n] = $set->name;
  72. }
  73. }
  74. array_unshift($sets,$this->name);
  75. $parameters = array(
  76. $destination->name,
  77. $sets,
  78. );
  79. if ($weights !== null) {
  80. $parameters[] = $weights;
  81. }
  82. $total = call_user_func_array(array(
  83. $this->getConnection()->getClient(),
  84. "zinter"
  85. ),$parameters);
  86. $destination->_count = $total;
  87. return $destination;
  88. }
  89. /**
  90. * Gets the union of this set and the given set(s), stores it in a new set and returns it
  91. * @param ARedisSortedSet|string $destination the destination to store the result in
  92. * @param mixed $set The sets to compare to, either ARedisSortedSet instances or their names
  93. * @param array $weights the weights for the sets, if any
  94. * @return ARedisSortedSet a set that contains the union of this set and the given sets
  95. */
  96. public function unionStore($destination, $set, $weights = null) {
  97. if ($destination instanceof ARedisSortedSet) {
  98. $destination->_count = null;
  99. $destination->_data = null;
  100. }
  101. else {
  102. $destination = new ARedisSortedSet($destination,$this->getConnection());
  103. }
  104. if (is_array($set)) {
  105. $sets = $set;
  106. }
  107. else {
  108. $sets = array($set);
  109. }
  110. foreach($sets as $n => $set) {
  111. if ($set instanceof ARedisSortedSet) {
  112. $sets[$n] = $set->name;
  113. }
  114. }
  115. array_unshift($sets,$this->name);
  116. $parameters = array(
  117. $destination->name,
  118. $sets,
  119. );
  120. if ($weights !== null) {
  121. $parameters[] = $weights;
  122. }
  123. $total = call_user_func_array(array(
  124. $this->getConnection()->getClient(),
  125. "zunion"
  126. ),$parameters);
  127. $destination->_count = $total;
  128. return $destination;
  129. }
  130. /**
  131. * Returns an iterator for traversing the items in the set.
  132. * This method is required by the interface IteratorAggregate.
  133. * @return Iterator an iterator for traversing the items in the set.
  134. */
  135. public function getIterator()
  136. {
  137. return new CMapIterator($this->getData());
  138. }
  139. /**
  140. * Gets the number of items in the set
  141. * @return integer the number of items in the set
  142. */
  143. public function getCount() {
  144. if ($this->_count === null) {
  145. $this->_count = $this->getConnection()->getClient()->zcard($this->name);
  146. }
  147. return $this->_count;
  148. }
  149. /**
  150. * Gets all the members in the sorted set
  151. * @param boolean $forceRefresh whether to force a refresh or not
  152. * @return array the members in the set
  153. */
  154. public function getData($forceRefresh = false) {
  155. if ($forceRefresh || $this->_data === null) {
  156. $this->_data = $this->getConnection()->getClient()->zrange($this->name,0, -1, true);
  157. }
  158. return $this->_data;
  159. }
  160. /**
  161. * Returns whether there is an item at the specified offset.
  162. * This method is required by the interface ArrayAccess.
  163. * @param integer $offset the offset to check on
  164. * @return boolean
  165. */
  166. public function offsetExists($offset)
  167. {
  168. return ($offset>=0 && $offset<$this->getCount());
  169. }
  170. /**
  171. * Returns the item at the specified offset.
  172. * This method is required by the interface ArrayAccess.
  173. * @param integer $offset the offset to retrieve item.
  174. * @return mixed the item at the offset
  175. * @throws CException if the offset is invalid
  176. */
  177. public function offsetGet($offset)
  178. {
  179. return $this->_data[$offset];
  180. }
  181. /**
  182. * Sets the item at the specified offset.
  183. * This method is required by the interface ArrayAccess.
  184. * @param integer $offset the offset to set item
  185. * @param mixed $item the item value
  186. */
  187. public function offsetSet($offset,$item)
  188. {
  189. $this->add($offset,$item);
  190. }
  191. /**
  192. * Unsets the item at the specified offset.
  193. * This method is required by the interface ArrayAccess.
  194. * @param integer $offset the offset to unset item
  195. */
  196. public function offsetUnset($offset)
  197. {
  198. $this->remove($offset);
  199. }
  200. }